Пример #1
0
def uri2options(uri):
    '''
    \brief Converts a coap URI into a list of CoAP options.
    
    Examples:
    
    calling this function with uri="coap://[aaaa::1]:1234/test1/test2"
    returns 
    (
        'aaaa::1',
        1234,
        (
           [Uri-Path('test1'),
           Uri-Path('test2')],
        ),
    )
    
    Calling this function with uri="http://[aaaa::1]/test1/test2"
    raises a coapMalformattedUri.
    
    \param[in] uri A string representing a CoAP URI.
    
    \raises coapMalformattedUri When the string passed in the uri parameter
        is not a valid CoAP URI.
    
    \return A tuple with the following elements;
        - at index 0, the destination IP address or host name (a string).
        - at index 1, the UDP port, possibly default CoAP port if none is
          explicitly specified..
        - at index 2, a tuple of CoAP options, i.e. (sub-)instances of the
          #coapOption objects.
    '''
    options   = []
    
    log.debug('uri      : {0}'.format(uri))
    
    # scheme
    if not uri.startswith(d.COAP_SCHEME):
        raise e.coapMalformattedUri('does not start with {0}'.format(d.COAP_SCHEME))
    
    # remove scheme
    uri       = uri.split(d.COAP_SCHEME,1)[1]
    
    # host and port
    host      = None
    port      = None
    hostPort  = uri.split('/')[0]
    if (not host) or (not port):
        # try format [aaaa::1]:1244
        m = re.match('\[([0-9a-fA-F:]+)\]:([0-9]+)',hostPort)
        if m:
            host   =     m.group(1)
            port   = int(m.group(2))
    if (not host) or (not port):
        # try format [aaaa::1]
        m = re.match('\[([0-9a-fA-F:]+)\]',hostPort)
        if m:
            host   = m.group(1)
            port   = d.DEFAULT_UDP_PORT
    if (not host) or (not port):
        # try formats:
        #    123.123.123.123:1234
        m = re.match('([0-9.]+):([0-9]+)',hostPort)
        if m:
            host   =     '::ffff:{0}'.format(m.group(1))
            port   = int(m.group(2))
    if (not host) or (not port):
        # try formats:
        #    www.example.com:1234
        m = re.match('([0-9a-zA.\-\_]+):([0-9]+)',hostPort)
        if m:
            host   =     m.group(1)
            port   = int(m.group(2))
    if (not host) or (not port):
        # try formats:
        #    123.123.123.123
        m = re.match('([0-9.]+)',hostPort)
        if m:
            host   = '::ffff:{0}'.format(m.group(1))
            port   = d.DEFAULT_UDP_PORT
    if (not host) or (not port):
        # try formats:
        #    www.example.com
        m = re.match('([0-9a-zA-Z.\-\_]+)', hostPort)
        if m:
            host = m.group(1)
            port = d.DEFAULT_UDP_PORT
    if (not host) or (not port):
        raise e.coapMalformattedUri('invalid host and port {0}'.format(hostPort))
    
    # log
    log.debug('host     : {0}'.format(host))
    log.debug('port     : {0}'.format(port))
    
    # remove hostPort
    uri       = uri.split(hostPort,1)[1]
    
    # Uri-path
    paths     = [p for p in uri.split('?')[0].split('/') if p]
    log.debug('paths    : {0}'.format(paths))
    for p in paths:
        options += [o.UriPath(path=p)]
    
    # Uri-query
    if len(uri.split('?'))>1:
        queries   = [q for q in uri.split('?')[1].split('&') if q]
        log.debug('queries  : {0}'.format(queries))
        raise NotImplementedError()
    
    host=host.lower()
    host=u.trimAddress(host)
    
    return (host,port,options)
Пример #2
0
def uri2options(uri):
    '''
    \brief Converts a coap URI into a list of CoAP options.
    
    Examples:
    
    calling this function with uri="coap://[aaaa::1]:1234/test1/test2"
    returns 
    (
        'aaaa::1',
        1234,
        (
           [Uri-Path('test1'),
           Uri-Path('test2')],
        ),
    )
    
    Calling this function with uri="http://[aaaa::1]/test1/test2"
    raises a coapMalformattedUri.
    
    \param[in] uri A string representing a CoAP URI.
    
    \raises coapMalformattedUri When the string passed in the uri parameter
        is not a valid CoAP URI.
    
    \return A tuple with the following elements;
        - at index 0, the destination IP address or host name (a string).
        - at index 1, the UDP port, possibly default CoAP port if none is
          explicitly specified..
        - at index 2, a tuple of CoAP options, i.e. (sub-)instances of the
          #coapOption objects.
    '''
    options = []

    log.debug('uri      : {0}'.format(uri))

    # scheme
    if not uri.startswith(d.COAP_SCHEME):
        raise e.coapMalformattedUri('does not start with {0}'.format(
            d.COAP_SCHEME))

    # remove scheme
    uri = uri.split(d.COAP_SCHEME, 1)[1]

    # host and port
    host = None
    port = None
    hostPort = uri.split('/')[0]
    if (not host) or (not port):
        # try format [aaaa::1]:1244
        m = re.match('\[([0-9a-fA-F:]+)\]:([0-9]+)', hostPort)
        if m:
            host = m.group(1)
            port = int(m.group(2))
    if (not host) or (not port):
        # try format [aaaa::1]
        m = re.match('\[([0-9a-fA-F:]+)\]', hostPort)
        if m:
            host = m.group(1)
            port = d.DEFAULT_UDP_PORT
    if (not host) or (not port):
        # try formats:
        #    123.123.123.123:1234
        m = re.match('([0-9.]+):([0-9]+)', hostPort)
        if m:
            host = '::ffff:{0}'.format(m.group(1))
            port = int(m.group(2))
    if (not host) or (not port):
        # try formats:
        #    www.example.com:1234
        m = re.match('([0-9a-zA.\-\_]+):([0-9]+)', hostPort)
        if m:
            host = m.group(1)
            port = int(m.group(2))
    if (not host) or (not port):
        # try formats:
        #    123.123.123.123
        m = re.match('([0-9.]+)', hostPort)
        if m:
            host = '::ffff:{0}'.format(m.group(1))
            port = d.DEFAULT_UDP_PORT
    if (not host) or (not port):
        # try formats:
        #    www.example.com
        m = re.match('([0-9a-zA-Z.\-\_]+)', hostPort)
        if m:
            host = m.group(1)
            port = d.DEFAULT_UDP_PORT
    if (not host) or (not port):
        raise e.coapMalformattedUri(
            'invalid host and port {0}'.format(hostPort))

    # log
    log.debug('host     : {0}'.format(host))
    log.debug('port     : {0}'.format(port))

    # remove hostPort
    uri = uri.split(hostPort, 1)[1]

    # Uri-path
    paths = [p for p in uri.split('?')[0].split('/') if p]
    log.debug('paths    : {0}'.format(paths))
    for p in paths:
        options += [o.UriPath(path=p)]

    # Uri-query
    if len(uri.split('?')) > 1:
        queries = [q for q in uri.split('?')[1].split('&') if q]
        log.debug('queries  : {0}'.format(queries))
        raise NotImplementedError()

    host = host.lower()
    host = u.trimAddress(host)

    return (host, port, options)
Пример #3
0
    def _receive(self, timestamp, sender, bytes):
        # all UDP packets are received here

        output = []
        output += ['\n{0} _receive message:'.format(self.name)]
        output += ['- timestamp: {0}'.format(timestamp)]
        output += ['- sender:    {0}'.format(sender)]
        output += ['- bytes:     {0}'.format(u.formatBuf(bytes))]
        output = '\n'.join(output)
        log.debug(output)

        srcIp = sender[0]
        srcIp = u.trimAddress(srcIp)

        srcPort = sender[1]

        # parse messages
        try:
            message = m.parseMessage(bytes)
        except e.messageFormatError as err:
            log.warning('malformed message {0}: {1}'.format(
                u.formatBuf(bytes), str(err)))
            return

        # dispatch message
        try:
            if message['code'] in d.METHOD_ALL:
                # this is meant for a resource

                #==== find right resource

                # retrieve path
                path = coapUri.options2path(message['options'])
                log.debug('path="{0}"'.format(path))

                # find resource that matches this path
                resource = None
                with self.resourceLock:
                    for r in self.resources:
                        if r.matchesPath(path):
                            resource = r
                            break
                log.debug('resource={0}'.format(resource))

                if not resource:
                    raise e.coapRcNotFound()

                #==== get a response

                # call the right resource's method
                try:
                    if message['code'] == d.METHOD_GET:
                        (respCode, respOptions, respPayload) = resource.GET(
                            options=message['options'])
                    elif message['code'] == d.METHOD_POST:
                        (respCode, respOptions, respPayload) = resource.POST(
                            options=message['options'],
                            payload=message['payload'])
                    elif message['code'] == d.METHOD_PUT:
                        (respCode, respOptions, respPayload) = resource.PUT(
                            options=message['options'],
                            payload=message['payload'])
                    elif message['code'] == d.METHOD_DELETE:
                        (respCode, respOptions, respPayload) = resource.DELETE(
                            options=message['options'])
                    else:
                        raise SystemError('unexpected code {0}'.format(
                            message['code']))
                except Exception as err:
                    if isinstance(err, e.coapRc):
                        raise
                    else:
                        raise e.coapRcInternalServerError()

                #==== send back response

                # determine type of response packet
                if message['type'] == d.TYPE_CON:
                    responseType = d.TYPE_ACK
                elif message['type'] == d.TYPE_NON:
                    responseType = d.TYPE_NON
                else:
                    raise SystemError('unexpected type {0}'.format(
                        message['type']))

                # build response packets
                response = m.buildMessage(
                    type=responseType,
                    token=message['token'],
                    code=respCode,
                    messageId=message['messageId'],
                    options=respOptions,
                    payload=respPayload,
                )

                # send
                self.socketUdp.sendUdp(
                    destIp=srcIp,
                    destPort=srcPort,
                    msg=response,
                )

            elif message['code'] in d.COAP_RC_ALL:
                # this is meant for a transmitter

                # find transmitter
                msgkey = (srcIp, srcPort, message['token'],
                          message['messageId'])

                found = False
                with self.transmittersLock:
                    self._cleanupTransmitter()
                    for (k, v) in self.transmitters.items():
                        # try matching
                        if (msgkey[0] == k[0] and msgkey[1] == k[1]
                                and (msgkey[2] == k[2] or msgkey[3] == k[3])):
                            found = True
                            v.receiveMessage(timestamp, srcIp, srcPort,
                                             message)
                            break
                if found == False:
                    raise e.coapRcBadRequest()

            else:
                raise NotImplementedError()

        except e.coapRc as err:
            # determine type of response packet
            if message['type'] == d.TYPE_CON:
                responseType = d.TYPE_ACK
            elif message['type'] == d.TYPE_NON:
                responseType = d.TYPE_NON
            else:
                raise SystemError('unexpected type {0}'.format(
                    message['type']))

            # build response packets
            response = m.buildMessage(
                type=responseType,
                token=message['token'],
                code=err.rc,
                messageId=message['messageId'],
            )

            # send
            self.socketUdp.sendUdp(
                destIp=srcIp,
                destPort=srcPort,
                msg=response,
            )
Пример #4
0
def uri2options(uri):
    '''
    \brief Converts a coap URI into a list of CoAP options.
    
    Examples:
    
    calling this function with uri="coap://[aaaa::1]/test1/test2"
    returns 
    (
        'aaaa::1'
        [Uri-Path('test1'),Uri-Path('test2')]
    )
    
    calling this function with uri="http://[aaaa::1]/test1/test2"
    raises a coapMalformattedUri.
    
    calling this function with uri="coap://example.com/test1/test2"
    returns 
    (
        'aaaa::1'
        [Uri-Path('test1'),Uri-Path('test2')]
    )
    
    \param[in] uri A string representing a CoAP URI.
    
    \raises coapMalformattedUri When the string passed in the uri parameter
        is not a valid CoAP URI.
    
    \return A tuple with the following 2 elements;
        - at index 0, the destination IP address. This is useful when the URI contains
          a DNS name instead of an IP addres
        - at index 1, a list of CoAP options, i.e. (sub-)instances of the
          #coapOption objects.
    '''
    options   = []
    
    log.debug('uri      : {0}'.format(uri))
    
    # scheme
    if not uri.startswith(d.COAP_SCHEME):
        raise e.coapMalformattedUri('does not start with {0}'.format(d.COAP_SCHEME))
    
    # remove scheme
    uri       = uri.split(d.COAP_SCHEME,1)[1]
    
    # ip address and port
    ip        = None
    port      = None
    ipPort    = uri.split('/')[0]
    if (not ip) or (not port):
        m = re.match('\[([0-9a-fA-F:]+)\]:([0-9]+)',ipPort)
        if m:
            ip     =     m.group(1)
            port   = int(m.group(2))
    if (not ip) or (not port):
        m = re.match('\[([0-9a-fA-F:]+)\]',ipPort)
        if m:
            ip     = m.group(1)
            port   = d.DEFAULT_UDP_PORT
    if (not ip) or (not port):
        m = re.match('([0-9a-zA-Z.]+):([0-9]+)',ipPort)
        if m:
            raise NotImplementedError
    if (not ip) or (not port):
        m = re.match('([0-9a-zA-Z.]+)',ipPort)
        if m:
            raise NotImplementedError
    if (not ip) or (not port):
        raise e.coapMalformattedUri('invalid host and port {0}'.format(temp))
    
    # log
    log.debug('ip       : {0}'.format(ip))
    log.debug('port     : {0}'.format(port))
    
    # remove ipPort
    uri       = uri.split(ipPort,1)[1]
    
    # Uri-path
    paths     = [p for p in uri.split('?')[0].split('/') if p]
    log.debug('paths    : {0}'.format(paths))
    for p in paths:
        options += [o.UriPath(path=p)]
    
    # Uri-query
    if len(uri.split('?'))>1:
        queries   = [q for q in uri.split('?')[1].split('&') if q]
        log.debug('queries  : {0}'.format(queries))
        raise NotImplementedError()
    
    ip=ip.lower()
    ip=u.trimAddress(ip)
    
    return (ip,port,options)
Пример #5
0
    def _receive(self, timestamp, sender, rawbytes):
        # all UDP packets are received here

        output = []
        output += ['\n{0} _receive message:'.format(self.name)]
        output += ['- timestamp: {0}'.format(timestamp)]
        output += ['- sender:    {0}'.format(sender)]
        output += ['- bytes:     {0}'.format(u.formatBuf(rawbytes))]
        output = '\n'.join(output)
        log.debug(output)

        srcIp = sender[0]
        srcIp = u.trimAddress(srcIp)

        srcPort = sender[1]

        options = []

        # parse messages
        try:
            message = m.parseMessage(rawbytes)
        except e.messageFormatError as err:
            log.warning('malformed message {0}: {1}'.format(
                u.formatBuf(rawbytes), str(err)))
            return

        # dispatch message
        try:
            if message['code'] in d.METHOD_ALL:
                # this is meant for a resource (request)

                #==== decrypt message if encrypted
                innerOptions = []
                foundContext = None
                requestPartialIV = None
                if 'ciphertext' in message.keys():
                    # retrieve security context
                    # before decrypting we don't know what resource this request is meant for
                    # so we take the first binding with the correct context (recipientID)
                    blindContext = self._securityContextLookup(
                        u.buf2str(message['kid']))

                    if not blindContext:
                        if self.secContextHandler:
                            appContext = self.secContextHandler(
                                u.buf2str(message['kid']))
                            if not appContext:
                                raise e.coapRcUnauthorized(
                                    'Security context not found.')
                        else:
                            raise e.coapRcUnauthorized(
                                'Security context not found.')

                    foundContext = blindContext if blindContext != None else appContext

                    requestPartialIV = u.zeroPadString(
                        u.buf2str(message['partialIV']),
                        foundContext.getIVLength())

                    # decrypt the message
                    try:
                        (innerOptions, plaintext) = oscoap.unprotectMessage(
                            foundContext,
                            version=message['version'],
                            code=message['code'],
                            options=message['options'],
                            ciphertext=message['ciphertext'],
                            partialIV=requestPartialIV)
                    except e.oscoapError as err:
                        raise e.coapRcBadRequest(
                            'OSCOAP unprotect failed: {0}'.format(str(err)))

                    payload = plaintext
                else:  # message not encrypted
                    payload = message['payload']

                options = message['options'] + innerOptions

                #==== find right resource

                # retrieve path
                path = coapUri.options2path(options)
                log.debug('path="{0}"'.format(path))

                # find resource that matches this path
                resource = None
                with self.resourceLock:
                    for r in self.resources:
                        if r.matchesPath(path):
                            resource = r
                            break
                log.debug('resource={0}'.format(resource))

                if not resource:
                    raise e.coapRcNotFound()

                #==== check if appropriate security context was used for the resource
                (context, authorizedMethods) = resource.getSecurityBinding()

                if context is not None:
                    if context != foundContext:
                        raise e.coapRcUnauthorized(
                            'Unauthorized security context for the given resource'
                        )

                objectSecurity = oscoap.objectSecurityOptionLookUp(options)
                if objectSecurity:
                    objectSecurity.setContext(foundContext)
                #==== get a response

                # call the right resource's method
                try:
                    if message[
                            'code'] == d.METHOD_GET and d.METHOD_GET in authorizedMethods:
                        (respCode, respOptions,
                         respPayload) = resource.GET(options=options)
                    elif message[
                            'code'] == d.METHOD_POST and d.METHOD_POST in authorizedMethods:
                        (respCode, respOptions,
                         respPayload) = resource.POST(options=options,
                                                      payload=payload)
                    elif message[
                            'code'] == d.METHOD_PUT and d.METHOD_PUT in authorizedMethods:
                        (respCode, respOptions,
                         respPayload) = resource.PUT(options=options,
                                                     payload=payload)
                    elif message[
                            'code'] == d.METHOD_DELETE and d.METHOD_DELETE in authorizedMethods:
                        (respCode, respOptions,
                         respPayload) = resource.DELETE(options=options)
                    elif message['code'] not in d.METHOD_ALL:
                        raise SystemError('unexpected code {0}'.format(
                            message['code']))
                    else:
                        raise e.coapRcUnauthorized(
                            'Unauthorized method for the given resource')
                except Exception as err:
                    if isinstance(err, e.coapRc):
                        raise
                    else:
                        raise e.coapRcInternalServerError()

                #==== send back response

                # determine type of response packet
                if message['type'] == d.TYPE_CON:
                    responseType = d.TYPE_ACK
                elif message['type'] == d.TYPE_NON:
                    responseType = d.TYPE_NON
                else:
                    raise SystemError('unexpected type {0}'.format(
                        message['type']))

                # if resource is protected with a security context, add Object-Security option
                if foundContext:
                    # verify that the Object-Security option was not set by the resource handler
                    assert not any(
                        isinstance(option, o.ObjectSecurity)
                        for option in respOptions)
                    objectSecurity = o.ObjectSecurity(context=foundContext)
                    respOptions += [objectSecurity]

                # if Stateless-Proxy option was present in the request echo it
                for option in options:
                    if isinstance(option, o.StatelessProxy):
                        respOptions += [option]
                        break

                # build response packets and pass partialIV from the request for OSCOAP's processing
                response = m.buildMessage(msgtype=responseType,
                                          token=message['token'],
                                          code=respCode,
                                          messageId=message['messageId'],
                                          options=respOptions,
                                          payload=respPayload,
                                          securityContext=foundContext,
                                          partialIV=requestPartialIV)

                # send
                self.socketUdp.sendUdp(
                    destIp=srcIp,
                    destPort=srcPort,
                    msg=response,
                )

            elif message['code'] in d.COAP_RC_ALL:
                # this is meant for a transmitter (response)

                # find transmitter
                msgkey = (srcIp, srcPort, message['token'],
                          message['messageId'])

                found = False
                with self.transmittersLock:
                    self._cleanupTransmitter()
                    for (k, v) in self.transmitters.items():
                        # try matching
                        if (msgkey[0] == k[0] and msgkey[1] == k[1]
                                and (msgkey[2] == k[2] or msgkey[3] == k[3])):
                            found = True
                            v.receiveMessage(timestamp, srcIp, srcPort,
                                             message)
                            break
                if found == False:
                    raise e.coapRcBadRequest(
                        'could not find transmitter corresponding to {0}, transmitters are {1}'
                        .format(
                            msgkey, ','.join(
                                [str(k) for k in self.transmitters.keys()])))

            else:
                raise NotImplementedError()

        except e.coapRc as err:

            # log
            log.warning(err)

            # determine type of response packet
            if message['type'] == d.TYPE_CON:
                responseType = d.TYPE_ACK
            elif message['type'] == d.TYPE_NON:
                responseType = d.TYPE_NON
            else:
                raise SystemError('unexpected type {0}'.format(
                    message['type']))

            # if Stateless-Proxy option was present in the request echo it
            errorOptions = []
            for option in options:
                if isinstance(option, o.StatelessProxy):
                    errorOptions += [option]
                    break

            # build response packets
            response = m.buildMessage(
                msgtype=responseType,
                token=message['token'],
                code=err.rc,
                messageId=message['messageId'],
                options=errorOptions,
            )

            # send
            self.socketUdp.sendUdp(
                destIp=srcIp,
                destPort=srcPort,
                msg=response,
            )

        except Exception as err:
            log.critical(traceback.format_exc())
Пример #6
0
    def _receive(self,timestamp,sender,rawbytes):
        # all UDP packets are received here

        output  = []
        output += ['\n{0} _receive message:'.format(self.name)]
        output += ['- timestamp: {0}'.format(timestamp)]
        output += ['- sender:    {0}'.format(sender)]
        output += ['- bytes:     {0}'.format(u.formatBuf(rawbytes))]
        output  = '\n'.join(output)
        log.debug(output)

        srcIp   = sender[0]
        srcIp   = u.trimAddress(srcIp)

        srcPort = sender[1]

        # parse messages
        try:
            message = m.parseMessage(rawbytes)
        except e.messageFormatError as err:
            log.warning('malformed message {0}: {1}'.format(u.formatBuf(rawbytes),str(err)))
            return

        # dispatch message
        try:
            if   message['code'] in d.METHOD_ALL:
                # this is meant for a resource

                #==== find right resource

                # retrieve path
                path = coapUri.options2path(message['options'])
                log.debug('path="{0}"'.format(path))

                # find resource that matches this path
                resource = None
                with self.resourceLock:
                    for r in self.resources:
                        if r.matchesPath(path):
                            resource = r
                            break
                log.debug('resource={0}'.format(resource))

                if not resource:
                    raise e.coapRcNotFound()

                #==== get a response

                # call the right resource's method
                try:
                    if   message['code']==d.METHOD_GET:
                        (respCode,respOptions,respPayload) = resource.GET(
                            options=message['options']
                        )
                    elif message['code']==d.METHOD_POST:
                        (respCode,respOptions,respPayload) = resource.POST(
                            options=message['options'],
                            payload=message['payload']
                        )
                    elif message['code']==d.METHOD_PUT:
                        (respCode,respOptions,respPayload) = resource.PUT(
                            options=message['options'],
                            payload=message['payload']
                        )
                    elif message['code']==d.METHOD_DELETE:
                        (respCode,respOptions,respPayload) = resource.DELETE(
                            options=message['options']
                        )
                    else:
                        raise SystemError('unexpected code {0}'.format(message['code']))
                except Exception as err:
                    if isinstance(err,e.coapRc):
                        raise
                    else:
                        raise e.coapRcInternalServerError()

                #==== send back response

                # determine type of response packet
                if   message['type']==d.TYPE_CON:
                    responseType = d.TYPE_ACK
                elif message['type']==d.TYPE_NON:
                    responseType = d.TYPE_NON
                else:
                    raise SystemError('unexpected type {0}'.format(message['type']))

                # build response packets
                response = m.buildMessage(
                    msgtype             = responseType,
                    token            = message['token'],
                    code             = respCode,
                    messageId        = message['messageId'],
                    options          = respOptions,
                    payload          = respPayload,
                )

                # send
                self.socketUdp.sendUdp(
                    destIp           = srcIp,
                    destPort         = srcPort,
                    msg              = response,
                )

            elif message['code'] in d.COAP_RC_ALL:
                # this is meant for a transmitter

                # find transmitter
                msgkey = (srcIp,srcPort,message['token'],message['messageId'])

                found  = False
                with self.transmittersLock:
                    self._cleanupTransmitter()
                    for (k,v) in self.transmitters.items():
                        # try matching
                        if (
                                msgkey[0]==k[0] and
                                msgkey[1]==k[1] and
                                (
                                    msgkey[2]==k[2] or
                                    msgkey[3]==k[3]
                                )
                            ):
                            found = True
                            v.receiveMessage(timestamp,srcIp,srcPort,message)
                            break
                if found==False:
                    raise e.coapRcBadRequest(
                        'could not find transmitter corresponding to {0}, transmitters are {1}'.format(
                            msgkey,
                            ','.join([str(k) for k in self.transmitters.keys()])
                        )
                    )

            else:
                raise NotImplementedError()

        except e.coapRc as err:

            # log
            log.warning(err)

            # determine type of response packet
            if   message['type']==d.TYPE_CON:
                responseType = d.TYPE_ACK
            elif message['type']==d.TYPE_NON:
                responseType = d.TYPE_NON
            else:
                raise SystemError('unexpected type {0}'.format(message['type']))

            # build response packets
            response = m.buildMessage(
                msgtype             = responseType,
                token            = message['token'],
                code             = err.rc,
                messageId        = message['messageId'],
            )

            # send
            self.socketUdp.sendUdp(
                destIp           = srcIp,
                destPort         = srcPort,
                msg              = response,
            )

        except Exception as err:
            log.critical(traceback.format_exc())
Пример #7
0
def uri2options(uri):
    '''
    \brief Converts a coap URI into a list of CoAP options.
    
    Examples:
    
    calling this function with uri="coap://[aaaa::1]/test1/test2"
    returns 
    (
        'aaaa::1'
        [Uri-Path('test1'),Uri-Path('test2')]
    )
    
    calling this function with uri="http://[aaaa::1]/test1/test2"
    raises a coapMalformattedUri.
    
    calling this function with uri="coap://example.com/test1/test2"
    returns 
    (
        'aaaa::1'
        [Uri-Path('test1'),Uri-Path('test2')]
    )
    
    \param[in] uri A string representing a CoAP URI.
    
    \raises coapMalformattedUri When the string passed in the uri parameter
        is not a valid CoAP URI.
    
    \return A tuple with the following 2 elements;
        - at index 0, the destination IP address. This is useful when the URI contains
          a DNS name instead of an IP addres
        - at index 1, a list of CoAP options, i.e. (sub-)instances of the
          #coapOption objects.
    '''
    options = []

    log.debug('uri      : {0}'.format(uri))

    # scheme
    if not uri.startswith(d.COAP_SCHEME):
        raise e.coapMalformattedUri('does not start with {0}'.format(
            d.COAP_SCHEME))

    # remove scheme
    uri = uri.split(d.COAP_SCHEME, 1)[1]

    # ip address and port
    ip = None
    port = None
    ipPort = uri.split('/')[0]
    if (not ip) or (not port):
        m = re.match('\[([0-9a-fA-F:]+)\]:([0-9]+)', ipPort)
        if m:
            ip = m.group(1)
            port = int(m.group(2))
    if (not ip) or (not port):
        m = re.match('\[([0-9a-fA-F:]+)\]', ipPort)
        if m:
            ip = m.group(1)
            port = d.DEFAULT_UDP_PORT
    if (not ip) or (not port):
        m = re.match('([0-9a-zA-Z.]+):([0-9]+)', ipPort)
        if m:
            raise NotImplementedError
    if (not ip) or (not port):
        m = re.match('([0-9a-zA-Z.]+)', ipPort)
        if m:
            raise NotImplementedError
    if (not ip) or (not port):
        raise e.coapMalformattedUri('invalid host and port {0}'.format(temp))

    # log
    log.debug('ip       : {0}'.format(ip))
    log.debug('port     : {0}'.format(port))

    # remove ipPort
    uri = uri.split(ipPort, 1)[1]

    # Uri-path
    paths = [p for p in uri.split('?')[0].split('/') if p]
    log.debug('paths    : {0}'.format(paths))
    for p in paths:
        options += [o.UriPath(path=p)]

    # Uri-query
    if len(uri.split('?')) > 1:
        queries = [q for q in uri.split('?')[1].split('&') if q]
        log.debug('queries  : {0}'.format(queries))
        raise NotImplementedError()

    ip = ip.lower()
    ip = u.trimAddress(ip)

    return (ip, port, options)