Beispiel #1
0
    async def test_td_coap_link_08(self):
        client, server = await self.start_client_server()
        print("TD_COAP_LINK_08")
        path = "/.well-known/core"
        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.uri_query = "?href=/link*"
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = utils.generate_random_hex(2)

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.payload = '</link1>;obs,</link2>;obs,</link3>;obs'
        expected.token = req.token
        expected.content_type = defines.ContentType.application_link_format
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        self.stop_client_server(client, server)
    async def test_td_coap_link_01(self):
        client, server = await self.start_client_server()
        print("TD_COAP_LINK_CLIENT_01")

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = '</group-if1>;if="if1",obs,</group-if2>;if="if2",obs,</group-if3>;if="foo",obs,' \
                           '</group-if4>;obs,</group-type1>;obs,rt="Type1 Type2",</group-type2>;obs,rt="Type2 Type3",' \
                           '</group-type3>;obs,rt="Type1 Type3",</group-type4>;obs,rt,</link1>;obs,</link2>;obs,' \
                           '</link3>;obs,</sz>;obs,sz="10",</type1>;obs,rt="Type1",</type2>;obs,rt="Type2"'

        expected.content_type = defines.ContentType.application_link_format
        expected.source = "127.0.0.1", 5683

        ret = await client.discover(timeout=10)
        self.assertIsInstance(ret, Response)
        expected.mid = ret.mid
        expected.token = ret.token

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        await self.stop_client_server(client, server)
    async def test_td_coap_core_19(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_19")
        path = "/location-query"

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CREATED
        expected.location_path = "/location-query/location-query1"
        expected.location_query = "?first=1&second=2"
        expected.source = self.server_address

        ret = await client.post(path, None, timeout=10)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)
        await self.stop_client_server(client, server)
    async def test_td_coap_core_01(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_01")
        path = "/test"

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = "Test"
        expected.content_type = defines.ContentType.TEXT_PLAIN

        expected.source = "127.0.0.1", 5683

        ret = await client.get(path, timeout=10)
        self.assertIsInstance(ret, Response)
        expected.mid = ret.mid
        expected.token = ret.token
        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)

        await self.stop_client_server(client, server)
    async def test_td_coap_core_14(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_14")
        path = "/query"

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = "Query12"
        expected.content_type = defines.ContentType.TEXT_PLAIN
        expected.source = self.server_address

        ret = await client.get(path, timeout=10, uri_query="first=1&second=2")
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)
        await self.stop_client_server(client, server)
    async def test_td_coap_link_08(self):
        client, server = await self.start_client_server()
        print("TD_COAP_LINK_CLIENT_08")

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = '</link1>;obs,</link2>;obs,</link3>;obs'
        expected.content_type = defines.ContentType.application_link_format
        expected.source = "127.0.0.1", 5683

        ret = await client.discover(timeout=10, uri_query="?href=/link*")
        self.assertIsInstance(ret, Response)
        expected.mid = ret.mid
        expected.token = ret.token

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        await self.stop_client_server(client, server)
Beispiel #7
0
    async def _handle_get(self, transaction: Transaction) -> Transaction:
        """
        Handle GET requests

        :type transaction: Transaction
        :param transaction: the transaction that owns the request
        :rtype : Transaction
        :return: the edited transaction with the response to the request
        """
        path = str("/" + transaction.request.uri_path)
        transaction.response = Response()
        transaction.response.destination = transaction.request.source
        transaction.response.token = transaction.request.token
        if path == defines.DISCOVERY_URL:
            resources = []
            for i in self._root.dump():
                if i == "/":
                    continue
                resource = self._root[i]
                if resource.visible:
                    resources.append(resource)

            transaction = await self._resourceLayer.discover(transaction, resources)
        else:
            try:
                resource = self._root[path]
            except KeyError:
                resource = None
            if resource is None or path == '/':
                # Not Found
                transaction.response.code = defines.Code.NOT_FOUND
            else:
                transaction = await self._resourceLayer.get_resource(transaction, resource)
        return transaction
Beispiel #8
0
    async def _handle_post(self, transaction: Transaction) -> Transaction:
        """
        Handle POST requests

        :type transaction: Transaction
        :param transaction: the transaction that owns the request
        :rtype : Transaction
        :return: the edited transaction with the response to the request
        """
        path = str("/" + transaction.request.uri_path)
        transaction.response = Response()
        transaction.response.destination = transaction.request.source
        transaction.response.token = transaction.request.token

        try:
            resource = self._root[path]
            # If-None-Match
            if transaction.request.if_none_match:
                transaction.response.code = defines.Code.PRECONDITION_FAILED
                return transaction

        except KeyError:
            transaction.response.code = defines.Code.NOT_FOUND
        else:
            # post
            transaction = await self._resourceLayer.post_resource(transaction, resource)

            if transaction.resource is not None and resource.__repr__() != transaction.resource.__repr__():
                # new resource created by the method
                self._root[transaction.resource.path] = transaction.resource
                transaction.response.code = defines.Code.CREATED

        return transaction
Beispiel #9
0
    async def _handle_put(self, transaction: Transaction) -> Transaction:
        """
        Handle PUT requests

        :type transaction: Transaction
        :param transaction: the transaction that owns the request
        :rtype : Transaction
        :return: the edited transaction with the response to the request
        """
        path = str("/" + transaction.request.uri_path)
        transaction.response = Response()
        transaction.response.destination = transaction.request.source
        transaction.response.token = transaction.request.token
        try:
            resource = self._root[path]

            # If-None-Match
            if transaction.request.if_none_match:
                transaction.response.code = defines.Code.PRECONDITION_FAILED
                return transaction

        except KeyError:
            # If-Match empty string
            if transaction.request.if_match:
                if "".encode("utf-8") in transaction.request.if_match:
                    transaction.response.code = defines.Code.PRECONDITION_FAILED
                    return transaction

            lst = self._root.get_ascending(path)

            max_len = 0
            imax = None

            for i in lst:
                if len(i.path) > max_len:
                    imax = i
                    max_len = len(i.path)

            parent_resource = imax
            if parent_resource.allow_children is not None:
                resource = parent_resource.allow_children()
                resource.path = path
                transaction.resource = resource
                self._root[resource.path] = transaction.resource
                transaction.response.code = defines.Code.CREATED
            else:
                transaction.response.code = defines.Code.NOT_FOUND
        else:
            transaction = await self._resourceLayer.put_resource(transaction, resource)

        return transaction
    async def test_td_coap_obs_14(self):
        client, server = await self.start_client_server()
        print("TD_COAP_OBS_14")
        path = "/not-obs"

        token = utils.generate_random_hex(2)
        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.observe = 0

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.payload = "NotObservable"
        expected.token = token
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        self.stop_client_server(client, server)
Beispiel #11
0
    async def _handle_delete(self, transaction: Transaction) -> Transaction:
        """
        Handle DELETE requests

        :type transaction: Transaction
        :param transaction: the transaction that owns the request
        :rtype : Transaction
        :return: the edited transaction with the response to the request
        """
        path = str("/" + transaction.request.uri_path)
        transaction.response = Response()
        transaction.response.destination = transaction.request.source
        transaction.response.token = transaction.request.token
        try:
            resource = self._root[path]
        except KeyError:
            transaction.response.code = defines.Code.NOT_FOUND
        else:
            # Delete
            transaction.resource = resource
            transaction = await self._resourceLayer.delete_resource(transaction, resource)
            if transaction.resource.deleted:
                del self._root[path]
        return transaction
    async def test_td_coap_core_08(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_08")
        path = "/test"

        expected = Response()
        expected.type = defines.Type.NON
        expected.mid = self.server_mid
        expected.code = defines.Code.CHANGED
        expected.source = "127.0.0.1", 5683

        ret = await client.post_non(path, "Updated", timeout=10)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)
        await self.stop_client_server(client, server)
Beispiel #13
0
    async def test_td_coap_block_03b(self):
        client, server = await self.start_client_server()
        print("TD_COAP_BLOCK_03B")
        path = "/large-update"

        token = utils.generate_random_hex(2)
        req = Request()
        req.code = defines.Code.PUT
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.block1 = (0, 1, 2048)
        req.payload = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc malesuada eget nunc " \
                      "interdum rutrum. In cursus mauris tortor, pulvinar mollis nibh sollicitudin et. Cras " \
                      "malesuada magna eu vestibulum semper. Cras sit amet molestie dolor. Class aptent " \
                      "taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent " \
                      "tortor velit, tempor ac interdum eget, fermentum vitae turpis. Etiam nisi sem, " \
                      "porta vel euismod quis, malesuada non lorem. Phasellus commodo nisl id justo efficitur, " \
                      "eu dapibus est semper.Sed vel sollicitudin purus. Ut viverra est facilisis ligula volutpat," \
                      " faucibus vestibulum nunc porttitor. Donec arcu elit, aliquam nec mattis eget, faucibus " \
                      "sit amet libero. Donec at mi eget dui ullamcorper malesuada at ut lorem. Maecenas varius" \
                      " congue augue nec convallis. Aenean sed urna non mi finibus fermentum. Aliquam vestibulum " \
                      "pharetra felis nec finibus. Nunc leo orci, commodo sit amet diam vel, facilisis tincidunt " \
                      "odio.Sed libero quam, eleifend at ante ac, gravida interdum tellus. Aliquam mattis ultrices " \
                      "viverra. Aliquam ultrices finibus erat, vel semper diam. Pellentesque auctor tortor vel " \
                      "erat laoreet venenatis. Nam mauris metus, egestas at dapibus quis, efficitur et quam. " \
                      "Vestibulum tempor, erat sit amet consectetur pellentesque, dui orci iaculis tellus, at " \
                      "volutpat tellus lacus congue libero. Suspendisse potenti. Aliquam placerat ut mauris ac " \
                      "mollis. Vestibulum eget urna lacus. Aenean ut laoreet velit. Pellentesque quis consectetur " \
                      "risus, eget tristique diam. Quisque ut mollis erat, et semper ipsum.Phasellus porta quam in " \
                      "nisl rutrum, at pretium lorem maximus. Donec a dapibus tellus, id suscipit orci. Suspendisse" \
                      " in porta tellus. Donec et accumsan felis. Donec non tempor diam, eu ornare libero. Morbi vel " \
                      "consequat lectus, eget facilisis sapien. Duis magna justo, dictum et tellus et, pulvinar " \
                      "cursus nisl. Proin vitae tincidunt sem. Nam et accumsan purus, at finibus augue. Praesent " \
                      "tellus tortor, sodales a neque id, fringilla tincidunt lectus. Ut quis augue eu nulla " \
                      "lobortis ultrices id ne"

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTINUE
        expected.token = token
        expected.block1 = (0, 1, 1024)
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        req = Request()
        req.code = defines.Code.PUT
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.block1 = (1, 1, 1024)
        req.payload = "c est. In vestibulum viverra facilisis. Aliquam posuere lectus " \
                      "eget facilisis faucibus. In hac habitasse platea dictumst.Vestibulum ornare lorem ac " \
                      "consequat volutpat. Fusce tristique nisi quis lorem congue, tincidunt pellentesque mi " \
                      "facilisis. Aliquam nec orci mollis, mollis metus id, maximus ex. Nunc sit amet purus " \
                      "non quam luctus posuere sit amet nec dui. Nulla suscipit erat sem, ac facilisis justo " \
                      "rutrum eget. Cras neque augue, blandit a imperdiet nec, dignissim non elit. Pellentesque " \
                      "vitae sem ac neque ornare posuere id sed elit. Aliquam erat volutpat. Nulla facilisi.Etiam " \
                      "quis ultrices nunc. Proin elit sapien, rutrum id felis sed, eleifend dignissim mi. Nulla " \
                      "non est gravida, placerat tortor quis, dapibus lectus. Aliquam tempus velit vitae est " \
                      "posuere, nec sodales massa luctus. Duis feugiat ex in facilisis posuere. Quisque in mi " \
                      "massa. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus " \
                      "mus. Nullam semper massa id arcu lobortis lobortis. Donec pulvinar auctor massa, imperdi"

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTINUE
        expected.token = token
        expected.block1 = (1, 1, 1024)
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        req = Request()
        req.code = defines.Code.PUT
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.block1 = (2, 0, 1024)
        req.payload = "et " \
                      "varius tortor.Nunc rhoncus sit amet ipsum nec pulvinar. Duis vel luctus nunc, nec hendrerit " \
                      "nulla. Sed suscipit elit ornare tempus imperdiet. Nulla vel aliquet arcu. Vivamus tristique " \
                      "quam dignissim nulla tempus ultricies. Fusce eu arcu egestas, aliquet ipsum non, iaculis ex. " \
                      "Mauris ut hendrerit velit, a faucibus metus. Quisque consectetur nec mi quis egestas. Cras " \
                      "sodales ipsum sapien, at varius lectus elementum nec. Nullam dictum mattis maximus. Fusce " \
                      "hendrerit rutrum condimentum. Cras malesuada risus sed hendrerit dignissim.Vestibulum vel " \
                      "velit eu urna consequat ullamcorper. Ut ut eros ac quam molestie feugiat. Mauris vehicula " \
                      "pharetra purus sed aliquam. Maecenas eget placerat nisi, ut pharetra dui. Mauris in dictum" \
                      " sem. Duis lacinia erat nec turpis semper euismod. In cursus non felis quis varius. Fusce " \
                      "mauris nunc, dapibus at bibendum vel, molestie vitae dolor. Donec ut orci at lorem tristique " \
                      "tincidunt. Nullam condimentum a lacus ut scelerisque. Vivamus sed leo ipsum. Sed in felis " \
                      "eget eros cras amet."

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CHANGED
        expected.token = token
        expected.block1 = (2, 0, 1024)
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        self.stop_client_server(client, server)
    async def test_td_coap_core_22(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_22")
        path = "/validate"

        # STEP 3
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = "Validate"
        expected.etag = b'\x01'
        expected.source = self.server_address

        ret = await client.get(path, timeout=10)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        # STEP 6
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CHANGED
        expected.source = self.server_address
        expected.payload = None

        ret = await client.put(path,
                               "Validate changed",
                               timeout=10,
                               if_match=b'\x01')
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        # STEP 10
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = "Validate changed"
        expected.etag = b'\x02'
        expected.source = self.server_address

        ret = await client.get(path, timeout=10)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        # STEP 14
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CHANGED
        expected.source = self.server_address

        ret = await client.put(path, "Step 13", timeout=10)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        # STEP 14
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.PRECONDITION_FAILED
        expected.source = self.server_address
        expected.payload = None

        ret = await client.put(path, "Step 17", timeout=10, if_match=b'\x02')
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)
        await self.stop_client_server(client, server)
    async def test_td_coap_core_20(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_20")
        path = "/multi-format"

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = "1"
        expected.content_type = defines.ContentType.TEXT_PLAIN
        expected.source = self.server_address

        ret = await client.get(path,
                               timeout=10,
                               accept=defines.ContentType.TEXT_PLAIN)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CONTENT
        expected.payload = "<value>1</value>"
        expected.content_type = defines.ContentType.application_xml
        expected.source = self.server_address

        ret = await client.get(path,
                               timeout=10,
                               accept=defines.ContentType.application_xml)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)
        await self.stop_client_server(client, server)
    async def test_td_coap_core_23(self):
        client, server = await self.start_client_server()
        print("TD_COAP_CORE_CLIENT_23")
        path = "/storage/create1"

        # STEP 3
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.CREATED
        expected.payload = None
        expected.source = self.server_address

        ret = await client.put(path,
                               "New Resource",
                               timeout=10,
                               if_none_match=True)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        # STEP 6
        expected = Response()
        expected.type = defines.Type.ACK
        expected.code = defines.Code.PRECONDITION_FAILED
        expected.source = self.server_address
        expected.payload = None

        ret = await client.put(path,
                               "Validate changed",
                               timeout=10,
                               if_none_match=True)
        self.assertIsInstance(ret, Response)
        expected.token = ret.token
        expected.mid = ret.mid

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))

        self.assertEqual(ret, expected)
        await self.stop_client_server(client, server)
Beispiel #17
0
    async def receive_request(self, transaction: Transaction) -> Transaction:
        """
        Handles the Blocks option in a incoming request.

        :type transaction: Transaction
        :param transaction: the transaction that owns the request
        :rtype : Transaction
        :return: the edited transaction
        """
        try:
            host, port = transaction.request.source
        except AttributeError:  # pragma: no cover
            raise errors.CoAPException("Request Source cannot be computed")

        key_token = utils.str_append_hash(host, port,
                                          transaction.request.token)

        if transaction.request.block2 is not None:

            num, m, size = transaction.request.block2
            if key_token in self._block2_receive:
                self._block2_receive[key_token].num = num
                self._block2_receive[key_token].size = size
                self._block2_receive[key_token].m = m
            else:
                # early negotiation
                byte = size * num
                self._block2_receive[key_token] = BlockItem(byte, num, m, size)

        elif transaction.request.block1 is not None or len(
                transaction.request.payload) > defines.MAX_PAYLOAD:
            # POST or PUT
            if len(transaction.request.payload) > defines.MAX_PAYLOAD:
                num, m, size = 0, 1, defines.MAX_PAYLOAD
                transaction.request.payload = transaction.request.payload[
                    0:size]
            else:
                num, m, size = transaction.request.block1
            if key_token in self._block1_receive:
                content_type = transaction.request.content_type
                if num != self._block1_receive[key_token].num \
                        or content_type != self._block1_receive[key_token].content_type \
                        or transaction.request.payload is None:
                    # Error Incomplete
                    raise errors.InternalError(
                        msg="Entity incomplete",
                        response_code=defines.Code.REQUEST_ENTITY_INCOMPLETE,
                        transaction=transaction)
                self._block1_receive[
                    key_token].payload += transaction.request.payload
            else:
                # first block
                if num != 0:
                    # Error Incomplete
                    raise errors.InternalError(
                        msg="Entity incomplete",
                        response_code=defines.Code.REQUEST_ENTITY_INCOMPLETE,
                        transaction=transaction)
                content_type = transaction.request.content_type
                self._block1_receive[key_token] = BlockItem(
                    size, num, m, size, transaction.request.payload,
                    content_type)
            num += 1
            byte = size
            self._block1_receive[key_token].byte = byte
            self._block1_receive[key_token].num = num
            self._block1_receive[key_token].size = size
            self._block1_receive[key_token].m = m

            if m == 0:
                transaction.request.payload = self._block1_receive[
                    key_token].payload
                # end of blockwise
                transaction.block_transfer = False
                #
                return transaction
            else:
                # Continue
                transaction.block_transfer = True
                transaction.response = Response()
                transaction.response.destination = transaction.request.source
                transaction.response.token = transaction.request.token

        return transaction
Beispiel #18
0
    async def _handler(self, data, addr):
        try:
            transaction, msg_type = await self._handle_datagram(data, addr)
            await self.handle_message(transaction, msg_type)
        except errors.PongException as e:
            if e.message is not None:
                # check if it is ping
                if e.message.type == defines.Type.CON:
                    rst = Message()
                    rst.destination = addr
                    rst.type = defines.Type.RST
                    rst.mid = e.message.mid
                    await self._send_datagram(rst)
        except errors.ProtocolError as e:
            '''
               From RFC 7252, Section 4.2
               reject the message if the recipient
               lacks context to process the message properly, including situations
               where the message is Empty, uses a code with a reserved class (1, 6,
               or 7), or has a message format error.  Rejecting a Confirmable
               message is effected by sending a matching Reset message and otherwise
               ignoring it.

               From RFC 7252, Section 4.3
               A recipient MUST reject the message
               if it lacks context to process the message properly, including the
               case where the message is Empty, uses a code with a reserved class
               (1, 6, or 7), or has a message format error.  Rejecting a Non-
               confirmable message MAY involve sending a matching Reset message
            '''
            rst = Message()
            rst.destination = addr
            rst.type = defines.Type.RST
            rst.mid = e.mid
            rst.payload = e.msg
            await self._send_datagram(rst)
        except errors.InternalError as e:
            if e.transaction.separate_task is not None:
                e.transaction.separate_task.cancel()
                del e.transaction.separate_task

            e.transaction.response = Response()
            e.transaction.response.destination = addr
            e.transaction.response.code = e.response_code
            e.transaction.response.payload = e.msg
            transaction = await self._messageLayer.send_response(e.transaction)
            await self._send_datagram(transaction.response)
            logger.error(e.msg)
        except errors.ObserveError as e:
            if e.transaction is not None:
                if e.transaction.separate_task is not None:
                    e.transaction.separate_task.cancel()
                    del e.transaction.separate_task
                e.transaction.response.payload = e.msg
                e.transaction.response.clear_options()
                e.transaction.response.type = defines.Type.CON
                e.transaction.response.code = e.response_code
                e.transaction = await self._messageLayer.send_response(e.transaction)
                await self._send_datagram(e.transaction.response)
                logger.error("Observe Error")
        except errors.CoAPException as e:
            logger.error(e.msg)
        except Exception as e:
            logger.exception(e)
    async def test_td_coap_obs_13(self):
        client, server = await self.start_client_server()
        print("TD_COAP_OBS_13")
        path = "/obs-large"

        token = utils.generate_random_hex(2)
        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.observe = 0

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.token = token
        expected.observe = 2
        expected.source = "127.0.0.1", 5683
        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"
        expected.block2 = (0, 1, 1024)

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.block2 = (1, 0, 1024)

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.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."

        expected.token = token
        expected.block2 = (1, 0, 1024)
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        expected = Response()
        expected.type = defines.Type.CON
        expected.mid = self.server_mid + 2
        expected.code = defines.Code.CONTENT
        expected.token = token
        expected.observe = 3
        expected.source = "127.0.0.1", 5683
        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"
        expected.block2 = (0, 1, 1024)

        transaction.response = None
        ret = await client.receive_response(transaction, 10)

        req = Message()
        req.code = defines.Code.EMPTY
        req.type = defines.Type.ACK
        req.mid = self.server_mid + 2
        req.destination = self.server_address
        req.token = token

        transaction = await client.send_request(req)

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        self.stop_client_server(client, server)
    async def test_td_coap_obs_01(self):
        client, server = await self.start_client_server()
        print("TD_COAP_OBS_01")
        path = "/obs"

        token = utils.generate_random_hex(2)
        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.observe = 0

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.payload = "5"
        expected.token = token
        expected.observe = 2
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        expected = Response()
        expected.type = defines.Type.CON
        expected.mid = self.server_mid + 1
        expected.code = defines.Code.CONTENT
        expected.payload = "6"
        expected.token = token
        expected.observe = 3
        expected.source = "127.0.0.1", 5683

        transaction.response = None
        ret = await client.receive_response(transaction, 10)

        req = Message()
        req.code = defines.Code.EMPTY
        req.type = defines.Type.ACK
        req.mid = self.server_mid
        req.destination = self.server_address
        req.token = token

        transaction = await client.send_request(req)

        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.observe = 0

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.payload = "6"
        expected.token = token
        expected.observe = 3
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)

        expected = Response()
        expected.type = defines.Type.CON
        expected.mid = self.server_mid + 4
        expected.code = defines.Code.CONTENT
        expected.payload = "7"
        expected.token = token
        expected.observe = 4
        expected.source = "127.0.0.1", 5683

        transaction.response = None
        ret = await client.receive_response(transaction, 10)

        req = Message()
        req.code = defines.Code.EMPTY
        req.type = defines.Type.RST
        req.mid = self.server_mid + 4
        req.destination = self.server_address
        req.token = token

        transaction = await client.send_request(req)
        await asyncio.sleep(5)

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        self.stop_client_server(client, server)
Beispiel #21
0
    async def deserialize(
        cls,
        datagram: bytes,
        source: Optional[Tuple[str, int]] = None,
        destination: Optional[Tuple[str, int]] = None
    ) -> Union[Message, Request, Response]:
        """
        De-serialize a stream of byte to a message.

        :param destination:
        :param datagram: the incoming udp message
        :param source: the source address and port (ip, port)
        :return: the message
        :rtype: Message
        """

        try:
            (vttkl, code, mid) = struct.unpack('!BBH', datagram[:4])
        except struct.error:  # pragma: no cover
            raise errors.CoAPException("Message too short for CoAP")

        datagram = datagram[4:]
        version = int((vttkl & 0xC0) >> 6)
        message_type = (vttkl & 0x30) >> 4
        tkl = int(vttkl & 0x0F)

        if version != defines.VERSION:  # pragma: no cover
            raise errors.ProtocolError("Unsupported protocol version", mid)

        if 9 <= tkl <= 15:  # pragma: no cover
            raise errors.ProtocolError("Token Length 9-15 are reserved", mid)

        code_class = (code & 0b11100000) >> 5
        code_details = (code & 0b00011111)
        try:
            cl = MessageCodeClass(code_class)
        except ValueError:  # pragma: no cover
            raise errors.ProtocolError(
                "Unknown code class {0}".format(code_class), mid)
        try:
            if cl == MessageCodeClass.RESPONSE or cl == MessageCodeClass.CLIENT_ERROR or \
                    cl == MessageCodeClass.SERVER_ERROR:
                message = Response()
                message.code = code
            elif cl == MessageCodeClass.REQUEST and code_details != 0:
                message = Request()
                message.code = code
            else:  # Empty message
                message = Message()
                message.code = defines.Code.EMPTY
        except ValueError:  # pragma: no cover
            raise errors.ProtocolError("Unknown code {0}".format(code), mid)

        if source is not None:
            message.source = source
        if destination is not None:
            message.destination = destination
        message.version = version
        message.type = message_type
        message.mid = mid

        if tkl > 0:
            message.token = datagram[:tkl]
        else:
            message.token = None
        try:
            datagram, options = cls._deserialize_options(datagram[tkl:])
        except errors.CoAPException as e:
            raise errors.ProtocolError(e.msg, mid)
        message.add_options(options)
        if len(datagram) == 1:  # pragma: no cover
            raise errors.ProtocolError("Payload Marker with no payload", mid)
        elif len(datagram) == 0:
            message.payload = None
        else:
            message.payload = datagram[1:]
        return message
    async def test_td_coap_obs_08(self):
        client, server = await self.start_client_server()
        print("TD_COAP_OBS_08")
        path = "/obs"

        token = utils.generate_random_hex(2)
        req = Request()
        req.code = defines.Code.GET
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token
        req.observe = 0

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CONTENT
        expected.payload = "5"
        expected.token = token
        expected.observe = 2
        expected.source = "127.0.0.1", 5683

        transaction = await client.send_request(req)
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)
        else:
            print("PASS-EXCHANGE-01")

        expected = Response()
        expected.type = defines.Type.CON
        expected.mid = self.server_mid + 1
        expected.code = defines.Code.CONTENT
        expected.payload = "6"
        expected.token = token
        expected.observe = 3
        expected.source = "127.0.0.1", 5683

        transaction.response = None
        ret = await client.receive_response(transaction, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)
        else:
            print("PASS-EXCHANGE-02")

        req = Message()
        req.code = defines.Code.EMPTY
        req.type = defines.Type.ACK
        req.mid = self.server_mid + 1
        req.destination = self.server_address
        req.token = token

        transaction = await client.send_request(req)

        token2 = utils.generate_random_hex(2)
        req = Request()
        req.code = defines.Code.PUT
        req.uri_path = path
        req.type = defines.Type.CON
        req.mid = random.randint(1, 1000)
        req.destination = self.server_address
        req.token = token2
        req.payload = "{ \"value\": 100}"
        req.content_type = defines.ContentType.application_json

        expected = Response()
        expected.type = defines.Type.ACK
        expected.mid = req.mid
        expected.code = defines.Code.CHANGED
        expected.token = token2
        expected.source = self.server_address

        transaction2 = await client.send_request(req)
        ret = await client.receive_response(transaction2, 10)

        if ret != expected:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            self.assertEqual(ret, expected)
        else:
            print("PASS-EXCHANGE-03")

        expected = Response()
        expected.type = defines.Type.CON
        expected.mid = self.server_mid + 4
        expected.code = defines.Code.NOT_ACCEPTABLE
        expected.token = token
        expected.source = self.server_address
        expected.payload = "Content-Type changed"

        transaction.response = None
        ret = await client.receive_response(transaction, 10)

        if ret == expected:
            print("PASS")
        else:
            print("Received: {0}".format(ret))
            print("Expected: {0}".format(expected))
            print(ret.pretty_print())

        self.assertEqual(ret, expected)

        self.stop_client_server(client, server)