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)
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)
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
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)])
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
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)
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
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)])
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
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))
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
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