コード例 #1
0
ファイル: plugtest.py プロジェクト: Cereal84/CoAPthon
    def test_td_coap_core_06(self):
        print "TD_COAP_CORE_06"
        path = "/test_post"
        req = Request()

        req.code = defines.inv_codes['POST']
        req.uri_path = path
        req.type = defines.inv_types["NON"]
        o = Option()
        o.number = defines.inv_options["Content-Type"]
        o.value = defines.inv_content_types["application/xml"]
        req.add_option(o)
        req._mid = self.current_mid
        req.destination = self.server_address
        req.payload = "<value>test</value>"

        expected = Response()
        expected.type = defines.inv_types["NON"]
        expected._mid = None
        expected.code = defines.responses["CREATED"]
        expected.token = None
        expected.payload = None
        option = Option()
        option.number = defines.inv_options["Location-Path"]
        option.value = "/test_post"
        expected.add_option(option)

        self.current_mid += 1
        self._test_plugtest(req, expected)
コード例 #2
0
    def test_post_and_get_storage(self):
        print "\nPOST /storage/data1 - GET /storage/data1\n"
        args = ("/storage/data1",)
        kwargs = {}
        path = args[0]
        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['POST']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.payload = "Created"
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CREATED"]
        expected.token = None
        expected.payload = None
        option = Option()
        option.number = defines.inv_options["Location-Path"]
        option.value = "/storage/data1"
        expected.add_option(option)

        self.current_mid += 1

        self._test(req, expected)

        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        expected.payload = "Created"

        self.current_mid += 1

        self._test(req, expected)
コード例 #3
0
ファイル: observe.py プロジェクト: hushuitian/CoAPthon
    def prepare_notification(self, t):
        """
        Create the notification message.

        :type t: (resource, request, old_response)
        :param t: the arguments of the notification message
        :return: the notification message
        """
        resource, request, old_response = t
        assert(isinstance(resource, Resource))
        response = Response()
        response.destination = old_response.destination
        response.token = old_response.token

        option = Option()
        option.number = defines.inv_options['Observe']
        option.value = resource.observe_count
        response.add_option(option)
        method = getattr(resource, 'render_GET', None)
        if hasattr(method, '__call__'):
            # Render_GET
            response.code = defines.responses['CONTENT']
            resource = method(request)
            response.payload = resource.payload
            # Blockwise
            response, resource = self._parent.blockwise_response(request, response, resource)
            host, port = request.source
            key = hash(str(host) + str(port) + str(request.token))
            if key in self._parent.blockwise:
                del self._parent.blockwise[key]
            # Reliability
            request.acknowledged = True
            response = self._parent.message_layer.reliability_response(request, response)
            # Matcher
            response = self._parent.message_layer.matcher_response(response)
            return resource, request, response
        else:
            response.code = defines.responses['METHOD_NOT_ALLOWED']
            # Blockwise
            response, resource = self._parent.blockwise_response(request, response, resource)
            host, port = request.source
            key = hash(str(host) + str(port) + str(request.token))
            if key in self._parent.blockwise:
                del self._parent.blockwise[key]
            # Reliability
            request.acknowledged = True
            response = self._parent.message_layer.reliability_response(request, response)
            # Matcher
            response = self._parent.message_layer.matcher_response(response)
            return resource, request, response
コード例 #4
0
ファイル: plugtest.py プロジェクト: hushuitian/CoAPthon
    def test_td_coap_link_02(self):
        print "TD_COAP_LINK_02"
        path = "/.well-known/core"
        req = Request()
        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address
        req.add_query("rt=Type1")

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        option = Option()
        option.number = defines.inv_options["Content-Type"]
        option.value = defines.inv_content_types["application/link-format"]
        expected.add_option(option)
        expected.payload = """</seg1/seg2/seg3>;rt="Type1",</seg1/seg2>;rt="Type1",</test>;rt="Type1",</seg1>;rt="Type1",</query>;rt="Type1","""

        self.current_mid += 1
        self._test_plugtest([(req, expected)])
コード例 #5
0
ファイル: serializer.py プロジェクト: Jenson1130/CSYE6530
    def deserialize(datagram, source):
        """
        De-serialize a stream of byte to a message.

        :param datagram: the incoming udp message
        :param source: the source address and port (ip, port)
        :return: the message
        :rtype: Message
        """
        try:
            fmt = "!BBH"
            pos = struct.calcsize(fmt)
            s = struct.Struct(fmt)
            values = s.unpack_from(datagram)
            first = values[0]
            code = values[1]
            mid = values[2]
            version = (first & 0xC0) >> 6
            message_type = (first & 0x30) >> 4
            token_length = (first & 0x0F)
            if Serializer.is_response(code):
                message = Response()
                message.code = code
            elif Serializer.is_request(code):
                message = Request()
                message.code = code
            else:
                message = Message()
            message.source = source
            message.destination = None
            message.version = version
            message.type = message_type
            message.mid = mid
            if token_length > 0:
                fmt = "%ss" % token_length
                s = struct.Struct(fmt)
                token_value = s.unpack_from(datagram[pos:])[0]
                message.token = token_value.decode("utf-8")
            else:
                message.token = None

            pos += token_length
            current_option = 0
            values = datagram[pos:]
            length_packet = len(values)
            pos = 0
            while pos < length_packet:
                next_byte = struct.unpack("B", values[pos].to_bytes(1, "big"))[0]
                pos += 1
                if next_byte != int(defines.PAYLOAD_MARKER):
                    # the first 4 bits of the byte represent the option delta
                    # delta = self._reader.read(4).uint
                    num, option_length, pos = Serializer.read_option_value_len_from_byte(next_byte, pos, values)
                    current_option += num
                    # read option
                    try:
                        option_item = defines.OptionRegistry.LIST[current_option]
                    except KeyError:
                        (opt_critical, _, _) = defines.OptionRegistry.get_option_flags(current_option)
                        if opt_critical:
                            raise AttributeError("Critical option %s unknown" % current_option)
                        else:
                            # If the non-critical option is unknown
                            # (vendor-specific, proprietary) - just skip it
                            #log.err("unrecognized option %d" % current_option)
                            pass
                    else:
                        if option_length == 0:
                            value = None
                        elif option_item.value_type == defines.INTEGER:
                            tmp = values[pos: pos + option_length]
                            value = 0
                            for b in tmp:
                                value = (value << 8) | struct.unpack("B", b.to_bytes(1, "big"))[0]
                        elif option_item.value_type == defines.OPAQUE:
                            tmp = values[pos: pos + option_length]
                            value = tmp
                        else:
                            value = values[pos: pos + option_length]

                        option = Option()
                        option.number = current_option
                        option.value = Serializer.convert_to_raw(current_option, value, option_length)

                        message.add_option(option)
                        if option.number == defines.OptionRegistry.CONTENT_TYPE.number:
                            message.payload_type = option.value
                    finally:
                        pos += option_length
                else:

                    if length_packet <= pos:
                        # log.err("Payload Marker with no payload")
                        raise AttributeError("Packet length %s, pos %s" % (length_packet, pos))
                    message.payload = ""
                    payload = values[pos:]
                    try:
                        if message.payload_type == defines.Content_types["application/octet-stream"]:
                            message.payload = payload
                        else:
                            message.payload = payload.decode("utf-8")
                    except AttributeError:
                        message.payload = payload.decode("utf-8")
                    pos += len(payload)

            return message
        except AttributeError:
            return defines.Codes.BAD_REQUEST.number
        except struct.error:
            return defines.Codes.BAD_REQUEST.number
コード例 #6
0
ファイル: plugtest.py プロジェクト: Cereal84/CoAPthon
    def test_td_coap_core_03(self):
        print "TD_COAP_CORE_03"
        path = "/test"
        req = Request()

        req.code = defines.inv_codes['PUT']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        o = Option()
        o.number = defines.inv_options["Content-Type"]
        o.value = defines.inv_content_types["application/xml"]
        req.add_option(o)
        req._mid = self.current_mid
        req.destination = self.server_address
        req.payload = "<value>test</value>"

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CHANGED"]
        expected.token = None
        expected.payload = None

        self.current_mid += 1
        self._test_plugtest(req, expected)

        req = Request()

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        expected.payload = "<value>test</value>"
        option = Option()
        option.number = defines.inv_options["Content-Type"]
        option.value = defines.inv_content_types["application/xml"]
        expected.add_option(option)

        self.current_mid += 1
        self._test_plugtest(req, expected)

        req = Request()

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address
        option = Option()
        option.number = defines.inv_options["Accept"]
        option.value = defines.inv_content_types["application/xml"]
        req.add_option(option)

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        expected.payload = "<value>test</value>"
        option = Option()
        option.number = defines.inv_options["Content-Type"]
        option.value = defines.inv_content_types["application/xml"]
        expected.add_option(option)

        self.current_mid += 1
        self._test_plugtest(req, expected)
コード例 #7
0
    def deserialize(datagram, source):
        """
        De-serialize a stream of byte to a message.

        :type datagram: String
        :param datagram:
        :param source:
        """
        try:
            fmt = "!BBH"
            pos = 4
            length = len(datagram)
            while pos < length:
                fmt += "c"
                pos += 1
            s = struct.Struct(fmt)
            values = s.unpack_from(datagram)
            first = values[0]
            code = values[1]
            mid = values[2]
            version = (first & 0xC0) >> 6
            message_type = (first & 0x30) >> 4
            token_length = (first & 0x0F)
            if Serializer.is_response(code):
                message = Response()
                message.code = code
            elif Serializer.is_request(code):
                message = Request()
                message.code = code
            else:
                message = Message()
            message.source = source
            message.destination = None
            message.version = version
            message.type = message_type
            message.mid = mid
            pos = 3
            if token_length > 0:
                message.token = "".join(values[pos: pos + token_length])
            else:
                message.token = None

            pos += token_length
            current_option = 0
            length_packet = len(values)
            while pos < length_packet:
                next_byte = struct.unpack("B", values[pos])[0]
                pos += 1
                if next_byte != int(defines.PAYLOAD_MARKER):
                    # the first 4 bits of the byte represent the option delta
                    # delta = self._reader.read(4).uint
                    delta = (next_byte & 0xF0) >> 4
                    # the second 4 bits represent the option length
                    # length = self._reader.read(4).uint
                    length = (next_byte & 0x0F)
                    num, pos = Serializer.read_option_value_from_nibble(delta, pos, values)
                    option_length, pos = Serializer.read_option_value_from_nibble(length, pos, values)
                    current_option += num
                    # read option
                    try:
                        option_item = defines.OptionRegistry.LIST[current_option]
                    except KeyError:
                        # log.err("unrecognized option")
                        raise AttributeError
                    if option_length == 0:
                        value = None
                    elif option_item.value_type == defines.INTEGER:
                        tmp = values[pos: pos + option_length]
                        value = 0
                        for b in tmp:
                            value = (value << 8) | struct.unpack("B", b)[0]
                    elif option_item.value_type == defines.OPAQUE:
                        tmp = values[pos: pos + option_length]
                        value = bytearray(tmp)
                    else:
                        tmp = values[pos: pos + option_length]
                        value = ""
                        for b in tmp:
                            value += str(b)

                    pos += option_length
                    option = Option()
                    option.number = current_option
                    option.value = Serializer.convert_to_raw(current_option, value, option_length)

                    message.add_option(option)
                else:

                    if length_packet <= pos:
                        # log.err("Payload Marker with no payload")
                        raise AttributeError
                    message.payload = ""
                    payload = values[pos:]
                    for b in payload:
                        message.payload += str(b)
                        pos += 1
            return message
        except AttributeError:
            return defines.Codes.BAD_REQUEST.number
        except struct.error:
            return defines.Codes.BAD_REQUEST.number
コード例 #8
0
    def test_big(self):
        print "\nGET /big\n"
        args = ("/big",)
        path = args[0]

        req = Request()
        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        expected.payload = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sollicitudin fermentum ornare." \
                           " Cras accumsan tellus quis dui lacinia eleifend. Proin ultrices rutrum orci vitae luctus. " \
                           "Nullam malesuada pretium elit, at aliquam odio vehicula in. Etiam nec maximus elit. Etiam " \
                           "at erat ac ex ornare feugiat. Curabitur sed malesuada orci, id aliquet nunc. Phasellus nec " \
                           "leo luctus, blandit lorem sit amet, interdum metus. Duis efficitur volutpat magna, ac " \
                           "ultricies nibh aliquet sit amet. Etiam tempor egestas augue in hendrerit. Nunc eget augue " \
                           "ultricies, dignissim lacus et, vulputate dolor. Nulla eros odio, fringilla vel massa ut, " \
                           "facilisis cursus quam. Fusce faucibus lobortis congue. Fusce consectetur porta neque, id " \
                           "sollicitudin velit maximus eu. Sed pharetra leo quam, vel finibus turpis cursus ac. Aenean " \
                           "ac nisi massa. Cras commodo arcu nec ante tristique ullamcorper. Quisque eu hendrerit urna. " \
                           "Cras fringilla eros ut nunc maximus, non porta nisl mollis. Aliquam in rutrum massa. " \
                           "Praesent tristique turpis dui, at ultri"
        option = Option()
        option.number = defines.inv_options["Block2"]
        option.value = 14
        expected.add_option(option)

        self.current_mid += 1

        req2 = Request()
        req2.code = defines.inv_codes['GET']
        req2.uri_path = path
        req2.type = defines.inv_types["CON"]
        req2._mid = self.current_mid
        req.destination = self.server_address

        option = Option()
        option.number = defines.inv_options["Block2"]
        option.value = 22
        req2.add_option(option)

        expected2 = Response()
        expected2.type = defines.inv_types["ACK"]
        expected2.code = defines.responses["CONTENT"]
        expected2._mid = self.current_mid
        expected2.token = None
        expected2.payload = "cies lorem fermentum at. Vivamus sit amet ornare neque, a imperdiet nisl. Quisque a " \
                            "iaculis libero, id tempus lacus. Aenean convallis est non justo consectetur, a hendrerit " \
                            "enim consequat. In accumsan ante a egestas luctus. Etiam quis neque nec eros vestibulum " \
                            "faucibus. Nunc viverra ipsum lectus, vel scelerisque dui dictum a. Ut orci enim, ultrices " \
                            "a ultrices nec, pharetra in quam. Donec accumsan sit amet eros eget fermentum.Vivamus ut " \
                            "odio ac odio malesuada accumsan. Aenean vehicula diam at tempus ornare. Phasellus dictum " \
                            "mauris a mi consequat, vitae mattis nulla fringilla. Ut laoreet tellus in nisl efficitur, " \
                            "a luctus justo tempus. Fusce finibus libero eget velit finibus iaculis. Morbi rhoncus " \
                            "purus vel vestibulum ullamcorper. Sed ac metus in urna fermentum feugiat. Nulla nunc " \
                            "diam, sodales aliquam mi id, varius porta nisl. Praesent vel nibh ac turpis rutrum " \
                            "laoreet at non odio. Phasellus ut posuere mi. Suspendisse malesuada velit nec mauris " \
                            "convallis porta. Vivamus sed ultrices sapien, at cras amet."
        option = Option()
        option.number = defines.inv_options["Block2"]
        option.value = 22
        expected2.add_option(option)
        self.current_mid += 1
        self._test_modular([(req, expected), (req2, expected2)])
コード例 #9
0
    def deserialize(datagram, source):
        """
        De-serialize a stream of byte to a message.

        :param datagram: the incoming udp message
        :param source: the source address and port (ip, port)
        :return: the message
        :rtype: Message
        """
        try:
            fmt = "!BBH"
            pos = 4
            length = len(datagram)
            while pos < length:
                fmt += "c"
                pos += 1
            s = struct.Struct(fmt)
            values = s.unpack_from(datagram)
            first = values[0]
            code = values[1]
            mid = values[2]
            version = (first & 0xC0) >> 6
            message_type = (first & 0x30) >> 4
            token_length = (first & 0x0F)
            if Serializer.is_response(code):
                message = Response()
                message.code = code
            elif Serializer.is_request(code):
                message = Request()
                message.code = code
            else:
                message = Message()
            message.source = source
            message.destination = None
            message.version = version
            message.type = message_type
            message.mid = mid
            pos = 3
            if token_length > 0:
                message.token = "".join(values[pos:pos + token_length])
            else:
                message.token = None

            pos += token_length
            current_option = 0
            length_packet = len(values)
            while pos < length_packet:
                next_byte = struct.unpack("B", values[pos])[0]
                pos += 1
                if next_byte != int(defines.PAYLOAD_MARKER):
                    # the first 4 bits of the byte represent the option delta
                    # delta = self._reader.read(4).uint
                    delta = (next_byte & 0xF0) >> 4
                    # the second 4 bits represent the option length
                    # length = self._reader.read(4).uint
                    length = (next_byte & 0x0F)
                    num, pos = Serializer.read_option_value_from_nibble(
                        delta, pos, values)
                    option_length, pos = Serializer.read_option_value_from_nibble(
                        length, pos, values)
                    current_option += num
                    # read option
                    try:
                        option_item = defines.OptionRegistry.LIST[
                            current_option]
                    except KeyError:
                        # log.err("unrecognized option")
                        raise AttributeError
                    if option_length == 0:
                        value = None
                    elif option_item.value_type == defines.INTEGER:
                        tmp = values[pos:pos + option_length]
                        value = 0
                        for b in tmp:
                            value = (value << 8) | struct.unpack("B", b)[0]
                    elif option_item.value_type == defines.OPAQUE:
                        tmp = values[pos:pos + option_length]
                        value = bytearray(tmp)
                    else:
                        tmp = values[pos:pos + option_length]
                        value = ""
                        for b in tmp:
                            value += str(b)

                    pos += option_length
                    option = Option()
                    option.number = current_option
                    option.value = Serializer.convert_to_raw(
                        current_option, value, option_length)

                    message.add_option(option)
                else:

                    if length_packet <= pos:
                        # log.err("Payload Marker with no payload")
                        raise AttributeError
                    message.payload = ""
                    payload = values[pos:]
                    for b in payload:
                        message.payload += str(b)
                        pos += 1
            return message
        except AttributeError:
            return defines.Codes.BAD_REQUEST.number
        except struct.error:
            return defines.Codes.BAD_REQUEST.number
コード例 #10
0
ファイル: serializer.py プロジェクト: johanzander/CoAPthon
    def deserialize(self, raw, host, port):
        """
        De-serialize a stream of byte to a message.

        :param raw: received bytes
        :param host: source host
        :param port: source port
        :return: the message
        """
        self._reader = BitStream(bytes=raw, length=(len(raw) * 8))
        version = self._reader.read(defines.VERSION_BITS).uint
        message_type = self._reader.read(defines.TYPE_BITS).uint
        token_length = self._reader.read(defines.TOKEN_LENGTH_BITS).uint
        code = self._reader.read(defines.CODE_BITS).uint
        mid = self._reader.read(defines.MESSAGE_ID_BITS).uint
        if self.is_response(code):
            message = Response()
            message.code = code
        elif self.is_request(code):
            message = Request()
            message.code = code
        else:
            message = Message()
        message.source = (host, port)
        message.destination = None
        message.version = version
        message.type = message_type
        message._mid = mid

        if token_length > 0:
            message.token = self._reader.read(token_length * 8).bytes
        else:
            message.token = None

        current_option = 0
        try:
            while self._reader.pos < self._reader.len:
                next_byte = self._reader.peek(8).uint
                if next_byte != int(defines.PAYLOAD_MARKER):
                    # the first 4 bits of the byte represent the option delta
                    delta = self._reader.read(4).uint
                    # the second 4 bits represent the option length
                    length = self._reader.read(4).uint
                    current_option += self.read_option_value_from_nibble(delta)
                    option_length = self.read_option_value_from_nibble(length)

                    # read option
                    try:
                        option_name, option_type, option_repeatable, default = defines.options[current_option]
                    except KeyError:
                        log.err("unrecognized option")
                        return message, "BAD_OPTION"
                    if option_length == 0:
                        value = None
                    elif option_type == defines.INTEGER:
                        value = self._reader.read(option_length * 8).uint
                    else:
                        value = self._reader.read(option_length * 8).bytes

                    option = Option()
                    option.number = current_option
                    option.value = self.convert_to_raw(current_option, value, option_length)

                    message.add_option(option)
                else:
                    self._reader.pos += 8  # skip payload marker
                    if self._reader.len <= self._reader.pos:
                        log.err("Payload Marker with no payload")
                        return message, "BAD_REQUEST"
                    to_end = self._reader.len - self._reader.pos
                    message.payload = self._reader.read(to_end).bytes
            return message
        except ReadError, e:
            log.err("Error parsing message: " + str(e))
コード例 #11
0
ファイル: serializer.py プロジェクト: hushuitian/CoAPthon
    def deserialize(self, raw, host, port):
        """
        De-serialize a stream of byte to a message.

        :param raw: received bytes
        :param host: source host
        :param port: source port
        :return: the message
        """

        fmt = "!BBH"
        pos = 4
        length = len(raw)
        while pos < length:
            fmt += "c"
            pos += 1
        s = struct.Struct(fmt)
        self._reader = raw
        values = s.unpack_from(self._reader)
        first = values[0]
        code = values[1]
        mid = values[2]
        version = (first & 0xC0) >> 6
        message_type = (first & 0x30) >> 4
        token_length = (first & 0x0F)
        if self.is_response(code):
            message = Response()
            message.code = code
        elif self.is_request(code):
            message = Request()
            message.code = code
        else:
            message = Message()
        message.source = (host, port)
        message.destination = None
        message.version = version
        message.type = message_type
        message._mid = mid
        pos = 3
        if token_length > 0:
                message.token = "".join(values[pos: pos + token_length])
        else:
            message.token = None

        pos += token_length
        current_option = 0
        length_packet = len(values)
        while pos < length_packet:
            next_byte = struct.unpack("B", values[pos])[0]
            pos += 1
            if next_byte != int(defines.PAYLOAD_MARKER):
                # the first 4 bits of the byte represent the option delta
                # delta = self._reader.read(4).uint
                delta = (next_byte & 0xF0) >> 4
                # the second 4 bits represent the option length
                # length = self._reader.read(4).uint
                length = (next_byte & 0x0F)
                num, pos = self.read_option_value_from_nibble(delta, pos, values)
                option_length, pos = self.read_option_value_from_nibble(length, pos, values)
                current_option += num
                # read option
                try:
                    option_name, option_type, option_repeatable, default = defines.options[current_option]
                except KeyError:
                    # log.err("unrecognized option")
                    return message, "BAD_OPTION"
                if option_length == 0:
                    value = None
                elif option_type == defines.INTEGER:
                    tmp = values[pos: pos + option_length]
                    value = 0
                    for b in tmp:
                        value = (value << 8) | struct.unpack("B", b)[0]
                else:
                    tmp = values[pos: pos + option_length]
                    value = ""
                    for b in tmp:
                        value += str(b)

                pos += option_length
                option = Option()
                option.number = current_option
                option.value = self.convert_to_raw(current_option, value, option_length)

                message.add_option(option)
            else:

                if length_packet <= pos:
                    # log.err("Payload Marker with no payload")
                    return message, "BAD_REQUEST"
                message.payload = ""
                payload = values[pos:]
                for b in payload:
                    message.payload += str(b)
                    pos += 1
        return message
コード例 #12
0
ファイル: serializer.py プロジェクト: Tanganelli/CoAPthon
    def deserialize(datagram, source):
        """
        De-serialize a stream of byte to a message.

        :param datagram: the incoming udp message
        :param source: the source address and port (ip, port)
        :return: the message
        :rtype: Message
        """
        try:
            fmt = "!BBH"
            pos = struct.calcsize(fmt)
            s = struct.Struct(fmt)
            values = s.unpack_from(datagram)
            first = values[0]
            code = values[1]
            mid = values[2]
            version = (first & 0xC0) >> 6
            message_type = (first & 0x30) >> 4
            token_length = (first & 0x0F)
            if Serializer.is_response(code):
                message = Response()
                message.code = code
            elif Serializer.is_request(code):
                message = Request()
                message.code = code
            else:
                message = Message()
            message.source = source
            message.destination = None
            message.version = version
            message.type = message_type
            message.mid = mid
            if token_length > 0:
                fmt = "%ss" % token_length
                s = struct.Struct(fmt)
                token_value = s.unpack_from(datagram[pos:])[0]
                message.token = token_value
            else:
                message.token = None

            pos += token_length
            current_option = 0
            values = datagram[pos:]
            length_packet = len(values)
            pos = 0
            while pos < length_packet:
                next_byte = struct.unpack("B", values[pos])[0]
                pos += 1
                if next_byte != int(defines.PAYLOAD_MARKER):
                    # the first 4 bits of the byte represent the option delta
                    # delta = self._reader.read(4).uint
                    num, option_length, pos = Serializer.read_option_value_len_from_byte(next_byte, pos, values)
                    current_option += num
                    # read option
                    try:
                        option_item = defines.OptionRegistry.LIST[current_option]
                    except KeyError:
                        (opt_critical, _, _) = defines.OptionRegistry.get_option_flags(current_option)
                        if opt_critical:
                            raise AttributeError("Critical option %s unknown" % current_option)
                        else:
                            # If the non-critical option is unknown
                            # (vendor-specific, proprietary) - just skip it
                            #log.err("unrecognized option %d" % current_option)
                            pass
                    else:
                        if option_length == 0:
                            value = None
                        elif option_item.value_type == defines.INTEGER:
                            tmp = values[pos: pos + option_length]
                            value = 0
                            for b in tmp:
                                value = (value << 8) | struct.unpack("B", b)[0]
                        elif option_item.value_type == defines.OPAQUE:
                            tmp = values[pos: pos + option_length]
                            value = bytearray(tmp)
                        else:
                            tmp = values[pos: pos + option_length]
                            value = ""
                            for b in tmp:
                                value += str(b)

                        option = Option()
                        option.number = current_option
                        option.value = Serializer.convert_to_raw(current_option, value, option_length)

                        message.add_option(option)
                        if option.number == defines.OptionRegistry.CONTENT_TYPE.number:
                            message.payload_type = option.value
                    finally:
                        pos += option_length
                else:

                    if length_packet <= pos:
                        # log.err("Payload Marker with no payload")
                        raise AttributeError("Packet length %s, pos %s" % (length_packet, pos))
                    message.payload = ""
                    payload = values[pos:]
                    for b in payload:
                        message.payload += str(b)
                        pos += 1
            return message
        except AttributeError:
            return defines.Codes.BAD_REQUEST.number
        except struct.error:
            return defines.Codes.BAD_REQUEST.number