Exemplo n.º 1
0
def main():
    global client
    host, port, path = parse_uri("coap://[::1]:5683/lights")
    try:
        tmp = socket.gethostbyname(host)
        host = tmp
        print "Host:", tmp
    except socket.gaierror:
        print("Exception")
        pass
    msg = Message()
    # msg.source = (host, port)
    # msg.destination = ('192.168.103.137', 5683)
    # msg.type = defines.Types['CON']
    msg.payload = '{"message": "Hello"}'
    # msg.code = 2
    # print msg.pretty_print()

    try:
        client = HelperClient(server=(host, port))
        response = client.get(path)
        print response.pretty_print()
        response = client.post(path, msg.payload, timeout=10)
        print response.pretty_print()
        response = client.delete(path)
        print response.pretty_print()
        client.close()
        # client = CoAPclient(host, port, msg)
    except Exception as e:
        print "Exception: ", str(e)
        client.close()
Exemplo n.º 2
0
    def receive_datagram(self):
        """
        Receive datagram from the UDP socket and invoke the callback function.
        """
        logger.debug("Start receiver Thread")
        while not self.stopped.isSet():
            self._socket.settimeout(0.1)
            try:
                datagram, addr = self._socket.recvfrom(1500)
            except socket.timeout:  # pragma: no cover
                continue
            except Exception as e:  # pragma: no cover
                if self._cb_ignore_read_exception is not None and isinstance(self._cb_ignore_read_exception, collections.Callable):
                    if self._cb_ignore_read_exception(e, self):
                        continue
                return
            else:  # pragma: no cover
                if len(datagram) == 0:
                    logger.debug("Exiting receiver Thread due to orderly shutdown on server end")
                    return

            serializer = Serializer()

            try:
                host, port = addr
            except ValueError:
                host, port, tmp1, tmp2 = addr

            source = (host, port)

            message = serializer.deserialize(datagram, source)

            if isinstance(message, Response):
                logger.debug("receive_datagram - " + str(message))
                transaction, send_ack = self._messageLayer.receive_response(message)
                if transaction is None:  # pragma: no cover
                    continue
                self._wait_for_retransmit_thread(transaction)
                if send_ack:
                    self._send_ack(transaction)
                self._blockLayer.receive_response(transaction)
                if transaction.block_transfer:
                    self._send_block_request(transaction)
                    continue
                elif transaction is None:  # pragma: no cover
                    self._send_rst(transaction)
                    return
                self._observeLayer.receive_response(transaction)
                if transaction.notification:  # pragma: no cover
                    ack = Message()
                    ack.type = defines.Types['ACK']
                    ack = self._messageLayer.send_empty(transaction, transaction.response, ack)
                    self.send_datagram(ack)
                    self._callback(transaction.response)
                else:
                    self._callback(transaction.response)
            elif isinstance(message, Message):
                self._messageLayer.receive_empty(message)

        logger.debug("Exiting receiver Thread due to request")
Exemplo n.º 3
0
 def _test_with_client_observe(self, message_list, callback):
     client = HelperClient(self.server_address)
     token = None
     last_mid = 0
     for message, expected in message_list:
         if message is not None:
             token = message.token
             client.send_request(message, callback)
         received_message = self.queue.get()
         if expected is not None:
             last_mid = expected.mid
             if expected.type is not None:
                 self.assertEqual(received_message.type, expected.type)
             if expected.mid is not None:
                 self.assertEqual(received_message.mid, expected.mid)
             self.assertEqual(received_message.code, expected.code)
             if expected.source is not None:
                 self.assertEqual(received_message.source, self.server_address)
             if expected.token is not None:
                 self.assertEqual(received_message.token, expected.token)
             if expected.payload is not None:
                 self.assertEqual(received_message.payload, expected.payload)
             if expected.options is not None:
                 self.assertEqual(received_message.options, expected.options)
     message = Message()
     message.type = defines.Types["RST"]
     message.token = token
     message._mid = last_mid
     message.destination = self.server_address
     client.send_empty(message)
     client.stop()
Exemplo n.º 4
0
    def receive_datagram(self):
        """
        Receive datagram from the UDP socket and invoke the callback function.
        """
        logger.debug("Start receiver Thread")
        while not self.stopped.isSet():
            self._socket.settimeout(0.1)
            try:
                datagram, addr = self._socket.recvfrom(1152)
            except socket.timeout:  # pragma: no cover
                continue
            except Exception as e:  # pragma: no cover
                if self._cb_ignore_read_exception is not None and callable(self._cb_ignore_read_exception):
                    if self._cb_ignore_read_exception(e, self):
                        continue
                return
            else:  # pragma: no cover
                if len(datagram) == 0:
                    logger.debug("Exiting receiver Thread due to orderly shutdown on server end")
                    return

            serializer = Serializer()

            try:
                host, port = addr
            except ValueError:
                host, port, tmp1, tmp2 = addr

            source = (host, port)

            message = serializer.deserialize(datagram, source)

            if isinstance(message, Response):
                logger.debug("receive_datagram - " + str(message))
                transaction, send_ack = self._messageLayer.receive_response(message)
                if transaction is None:  # pragma: no cover
                    continue
                self._wait_for_retransmit_thread(transaction)
                if send_ack:
                    self._send_ack(transaction)
                self._blockLayer.receive_response(transaction)
                if transaction.block_transfer:
                    self._send_block_request(transaction)
                    continue
                elif transaction is None:  # pragma: no cover
                    self._send_rst(transaction)
                    return
                self._observeLayer.receive_response(transaction)
                if transaction.notification:  # pragma: no cover
                    ack = Message()
                    ack.type = defines.Types['ACK']
                    ack = self._messageLayer.send_empty(transaction, transaction.response, ack)
                    self.send_datagram(ack)
                    self._callback(transaction.response)
                else:
                    self._callback(transaction.response)
            elif isinstance(message, Message):
                self._messageLayer.receive_empty(message)

        logger.debug("Exiting receiver Thread due to request")
Exemplo n.º 5
0
    def listen(self, timeout=10):
        """
        Listen for incoming messages. Timeout is used to check if the server must be switched off.

        :param timeout: Socket Timeout in seconds
        """
        self._socket.settimeout(float(timeout))
        while not self.stopped.isSet():
            try:
                data, client_address = self._socket.recvfrom(4096)
                if len(client_address) > 2:
                    client_address = (client_address[0], client_address[1])
            except socket.timeout:
                continue
            try:
                serializer = Serializer()
                message = serializer.deserialize(data, client_address)
                if isinstance(message, int):
                    logger.error("receive_datagram - BAD REQUEST")

                    rst = Message()
                    rst.destination = client_address
                    rst.type = defines.Types["RST"]
                    rst.code = message
                    rst.mid = self._messageLayer._current_mid
                    self._messageLayer._current_mid += 1 % 65535
                    self.send_datagram(rst)
                    continue

                logger.debug("receive_datagram - " + str(message))
                if isinstance(message, Request):
                    transaction = self._messageLayer.receive_request(message)
                    if transaction.request.duplicated and transaction.completed:
                        logger.debug("message duplicated, transaction completed")
                        if transaction.response is not None:
                            self.send_datagram(transaction.response)
                        return
                    elif transaction.request.duplicated and not transaction.completed:
                        logger.debug("message duplicated, transaction NOT completed")
                        self._send_ack(transaction)
                        return
                    args = (transaction, )
                    t = threading.Thread(target=self.receive_request, args=args)
                    t.start()
                # self.receive_datagram(data, client_address)
                elif isinstance(message, Response):
                    logger.error("Received response from %s", message.source)

                else:  # is Message
                    transaction = self._messageLayer.receive_empty(message)
                    if transaction is not None:
                        with transaction:
                            self._blockLayer.receive_empty(message, transaction)
                            self._observeLayer.receive_empty(message, transaction)

            except RuntimeError:
                print "Exception with Executor"
        self._socket.close()
Exemplo n.º 6
0
    def receive_datagram(self):
        """
        Receive datagram from the UDP socket and invoke the callback function.
        """
        logger.debug("Start receiver Thread")
        while not self.stopped.isSet():
            self._socket.settimeout(1)
            try:
                datagram, addr = self._socket.recvfrom(1152)
            except socket.timeout:  # pragma: no cover
                continue
            except socket.error:  # pragma: no cover
                return
            else:  # pragma: no cover
                if len(datagram) == 0:
                    logger.debug("orderly shutdown on server end")
                    return

            serializer = Serializer()

            try:
                host, port = addr
            except ValueError:
                host, port, tmp1, tmp2 = addr

            source = (host, port)

            message = serializer.deserialize(datagram, source)

            if isinstance(message, Response):
                transaction, send_ack = self._messageLayer.receive_response(
                    message)
                if transaction is None:  # pragma: no cover
                    continue
                if send_ack:
                    self._send_ack(transaction)
                self._blockLayer.receive_response(transaction)
                if transaction.block_transfer:
                    transaction = self._messageLayer.send_request(
                        transaction.request)
                    self.send_datagram(transaction.request)
                    continue
                elif transaction is None:  # pragma: no cover
                    self._send_rst(transaction)
                    return
                self._observeLayer.receive_response(transaction)
                if transaction.notification:  # pragma: no cover
                    ack = Message()
                    ack.type = defines.Types['ACK']
                    ack = self._messageLayer.send_empty(
                        transaction, transaction.response, ack)
                    self.send_datagram(ack)
                    self._callback(transaction.response)
                else:
                    self._callback(transaction.response)
            elif isinstance(message, Message):
                self._messageLayer.receive_empty(message)
Exemplo n.º 7
0
    def end_observation(self, token):
        """
        Remove an observation token from our records.

        :param token: the token for the observation
        """
        dummy = Message()
        dummy.token = token
        dummy.destination = self._server
        self._observeLayer.remove_subscriber(dummy)
Exemplo n.º 8
0
    def end_observation(self, token):
        """
        Remove an observation token from our records.

        :param token: the token for the observation
        """
        dummy = Message()
        dummy.token = token
        dummy.destination = self._server
        self._observeLayer.remove_subscriber(dummy)
Exemplo n.º 9
0
    def receive_datagram(self, args):
        """
        Handle messages coming from the udp socket.

        :param args: (data, client_address)
        """
        data, client_address = args

        logging.debug("receiving datagram")

        try:
            host, port = client_address
        except ValueError:
            host, port, tmp1, tmp2 = client_address

        client_address = (host, port)

        serializer = Serializer()
        message = serializer.deserialize(data, client_address)
        if isinstance(message, int):
            logger.error("receive_datagram - BAD REQUEST")
            rst = Message()
            rst.destination = client_address
            rst.type = Types["RST"]
            rst.code = message
            rst.mid = message.mid
            self.send_datagram(rst)
            return
        logger.debug("receive_datagram - " + str(message))

        if isinstance(message, Request):
            if not message.proxy_uri or message.uri_path != "coap2http":
                logger.error("receive_datagram - BAD REQUEST")
                rst = Message()
                rst.destination = client_address
                rst.type = Types["RST"]
                rst.code = Codes.BAD_REQUEST.number
                rst.mid = message.mid
                self.send_datagram(rst)
                return
            # Execute HTTP/HTTPS request
            http_response = CoAP_HTTP.execute_http_request(message.code, message.proxy_uri, message.payload)
            # HTTP response to CoAP response conversion
            coap_response = CoAP_HTTP.to_coap_response(http_response, message.code, client_address, message.mid)
            # Send datagram and return
            self.send_datagram(coap_response)
            return

        elif isinstance(message, Message):
            logger.error("Received message from %s", message.source)

        else:  # is Response
            logger.error("Received response from %s", message.source)
Exemplo n.º 10
0
    def receive_datagram(self):
        """
        Receive datagram from the UDP socket and invoke the callback function.
        """

        logger.debug("Start receiver Thread")
        while not self.stopped.isSet():
            try:
                xbee_message = self.xbee.read_data(timeout=0.1)
            except TimeoutException:
                continue
            except Exception as e:
                if self._cb_ignore_read_exception is not None and isinstance(
                        self._cb_ignore_read_exception, collections.Callable):
                    if self._cb_ignore_read_exception(e, self):
                        continue
                return

            serializer = Serializer()
            message = serializer.deserialize(bytes(xbee_message.data),
                                             self._server)

            if isinstance(message, Response):
                logger.debug("receive_datagram - " + str(message))
                transaction, send_ack = self._messageLayer.receive_response(
                    message)
                if transaction is None:  # pragma: no cover
                    continue
                self._wait_for_retransmit_thread(transaction)
                if send_ack:
                    self._send_ack(transaction)
                self._blockLayer.receive_response(transaction)
                if transaction.block_transfer:
                    self._send_block_request(transaction)
                    continue
                elif transaction is None:  # pragma: no cover
                    self._send_rst(transaction)
                    return
                self._observeLayer.receive_response(transaction)
                if transaction.notification:  # pragma: no cover
                    ack = Message()
                    ack.type = defines.Types['ACK']
                    ack = self._messageLayer.send_empty(
                        transaction, transaction.response, ack)
                    self.send_datagram(ack)
                    self._callback(transaction.response)
                else:
                    self._callback(transaction.response)
            elif isinstance(message, Message):
                self._messageLayer.receive_empty(message)

        logger.debug("Exiting receiver Thread due to request")
Exemplo n.º 11
0
    def _send_rst(self, transaction):  # pragma: no cover
        """
        Sends an RST message for the response.

        :param transaction: transaction that holds the response
        """

        rst = Message()
        rst.type = defines.Types['RST']

        if not transaction.response.acknowledged:
            rst = self._messageLayer.send_empty(transaction, transaction.response, rst)
            self.send_datagram(rst)
Exemplo n.º 12
0
    def _send_ack(self, transaction):
        """
        Sends an ACK message for the response.

        :param transaction: transaction that holds the response
        """

        ack = Message()
        ack.type = defines.Types['ACK']

        if not transaction.response.acknowledged:
            ack = self._messageLayer.send_empty(transaction, transaction.response, ack)
            self.send_datagram(ack)
Exemplo n.º 13
0
    def _send_ack(self, transaction):
        """
        Sends an ACK message for the request.

        :param transaction: the transaction that owns the request
        """

        ack = Message()
        ack.type = defines.Types['ACK']
        # TODO handle mutex on transaction
        if not transaction.request.acknowledged and transaction.request.type == defines.Types["CON"]:
            ack = self._messageLayer.send_empty(transaction, transaction.request, ack)
            self.send_datagram(ack)
Exemplo n.º 14
0
    def _send_ack(self, transaction):
        """
        Sends an ACK message for the response.

        :param transaction: transaction that holds the response
        """

        ack = Message()
        ack.type = defines.Types['ACK']

        if not transaction.response.acknowledged:
            ack = self._messageLayer.send_empty(transaction, transaction.response, ack)
            self.send_datagram(ack)
Exemplo n.º 15
0
    def _send_rst(self, transaction):  # pragma: no cover
        """
        Sends an RST message for the response.

        :param transaction: transaction that holds the response
        """

        rst = Message()
        rst.type = defines.Types['RST']

        if not transaction.response.acknowledged:
            rst = self._messageLayer.send_empty(transaction, transaction.response, rst)
            self.send_datagram(rst)
Exemplo n.º 16
0
    def _send_ack(self, transaction):
        """
        Sends an ACK message for the request.

        :param transaction: the transaction that owns the request
        """

        ack = Message()
        ack.type = defines.Types['ACK']
        # TODO handle mutex on transaction
        if not transaction.request.acknowledged and transaction.request.type == defines.Types["CON"]:
            ack = self._messageLayer.send_empty(transaction, transaction.request, ack)
            self.send_datagram(ack)
Exemplo n.º 17
0
    def receive_datagram(self):
        logger.debug("Start receiver Thread")
        while not self.stopped.isSet():
            self._socket.settimeout(1)
            try:
                datagram, addr = self._socket.recvfrom(1152)
            except socket.timeout:  # pragma: no cover
                continue
            except socket.error:  # pragma: no cover
                return
            else:  # pragma: no cover
                if len(datagram) == 0:
                    print 'orderly shutdown on server end'
                    return

            serializer = Serializer()

            try:
                host, port = addr
            except ValueError:
                host, port, tmp1, tmp2 = addr

            source = (host, port)

            message = serializer.deserialize(datagram, source)

            if isinstance(message, Response):
                transaction, send_ack = self._messageLayer.receive_response(message)
                if transaction is None:  # pragma: no cover
                    continue
                if send_ack:
                    self._send_ack(transaction)
                self._blockLayer.receive_response(transaction)
                if transaction.block_transfer:
                    transaction = self._messageLayer.send_request(transaction.request)
                    self.send_datagram(transaction.request)
                    continue
                elif transaction is None:  # pragma: no cover
                    self._send_rst(transaction)
                    return
                self._observeLayer.receive_response(transaction)
                if transaction.notification:  # pragma: no cover
                    ack = Message()
                    ack.type = defines.Types['ACK']
                    ack = self._messageLayer.send_empty(transaction, transaction.response, ack)
                    self.send_datagram(ack)
                    self._callback(transaction.response)
                else:
                    self._callback(transaction.response)
            elif isinstance(message, Message):
                self._messageLayer.receive_empty(message)
Exemplo n.º 18
0
    def _send_rst(self, transaction):
        # Handle separate
        """
        Sends an RST message for the request.

        :param request: [request, sleep_time] or request
        """

        rst = Message()
        rst.type = defines.Types['RST']

        if not transaction.response.acknowledged:
            rst = self._messageLayer.send_empty(transaction, transaction.response, rst)
            self.send_datagram(rst)
Exemplo n.º 19
0
    def _send_ack(self, transaction):
        # Handle separate
        """
        Sends an ACK message for the request.

        :param request: [request, sleep_time] or request
        """

        ack = Message()
        ack.type = defines.Types['ACK']

        if not transaction.request.acknowledged:
            ack = self._messageLayer.send_empty(transaction, transaction.request, ack)
            self.send_datagram(ack)
Exemplo n.º 20
0
    def _send_ack(self, transaction):
        # Handle separate
        """
        Sends an ACK message for the request.

        :param request: [request, sleep_time] or request
        """

        ack = Message()
        ack.type = defines.Types['ACK']

        if not transaction.request.acknowledged:
            ack = self._messageLayer.send_empty(transaction,
                                                transaction.request, ack)
            self.send_datagram(ack)
Exemplo n.º 21
0
 def handle_notification(self, response, client_callback):
     host, port = response.source
     key = hash(str(host) + str(port) + str(response.token))
     self.relation[key] = (response, time.time(), client_callback)
     if response.type == defines.inv_types["CON"]:
         ack = Message.new_ack(response)
         self.send(ack)
Exemplo n.º 22
0
    def _send_ack(self, transaction):
        """
        Sends an ACK message for the request.

        :param transaction: the transaction that owns the request
        """

        ack = Message()
        ack.type = defines.Types['ACK']
        with transaction:
            if not transaction.request.acknowledged and transaction.request.type == defines.Types[
                    "CON"]:
                ack = self._messageLayer.send_empty(transaction,
                                                    transaction.request, ack)
                if ack.type is not None and ack.mid is not None:
                    self.send_datagram(ack)
Exemplo n.º 23
0
 def cancel_observing(self, response, send_rst):
     host, port = response.source
     key = hash(str(host) + str(port) + str(response.token))
     del self.relation[key]
     if send_rst:
         rst = Message.new_rst(response)
         self.send(rst)
Exemplo n.º 24
0
    def _test_modular(self, lst):
        serializer = Serializer()
        for t in lst:
            message, expected = t
            send_ack = False
            if message is not None:
                datagram = serializer.serialize(message)
                self.proto.datagramReceived(datagram, ("127.0.0.1", 5600))
            else:
                send_ack = True

            datagram, source = self.tr.written.pop(0)
            host, port = source
            message = serializer.deserialize(datagram, host, port)
            self.assertEqual(message.type, expected.type)
            if not send_ack:
                self.assertEqual(message.mid, expected.mid)
            self.assertEqual(message.code, expected.code)
            self.assertEqual(message.source, source)
            self.assertEqual(message.token, expected.token)
            self.assertEqual(message.payload, expected.payload)
            self.assertEqual(message.options, expected.options)
            if send_ack:
                message = Message.new_ack(message)
                datagram = serializer.serialize(message)
                self.proto.datagramReceived(datagram, ("127.0.0.1", 5600))

        self.tr.written = []
Exemplo n.º 25
0
    def _test_separate(self, message, notification):
        serializer = Serializer()
        datagram = serializer.serialize(message)
        self.proto.datagramReceived(datagram, ("127.0.0.1", 5600))

        datagram, source = self.tr.written[0]
        host, port = source
        message = serializer.deserialize(datagram, host, port)

        self.assertEqual(message.type, defines.inv_types["ACK"])
        self.assertEqual(message.code, None)
        self.assertEqual(message.mid, self.current_mid + 4)
        self.assertEqual(message.source, source)

        datagram, source = self.tr.written[1]
        host, port = source
        message = serializer.deserialize(datagram, host, port)

        self.assertEqual(message.type, notification.type)
        self.assertEqual(message.code, notification.code)
        self.assertEqual(message.source, source)
        self.assertEqual(message.token, notification.token)
        self.assertEqual(message.payload, notification.payload)
        self.assertEqual(message.options, notification.options)

        self.tr.written = []

        message = Message.new_ack(message)
        datagram = serializer.serialize(message)
        self.proto.datagramReceived(datagram, ("127.0.0.1", 5600))
        self.tr.written = []
Exemplo n.º 26
0
    def _test_separate(self, message, notification):
        serializer = Serializer()
        datagram = serializer.serialize(message)
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.sendto(datagram, self.server_address)

        datagram, source = sock.recvfrom(4096)
        host, port = source
        message = serializer.deserialize(datagram, host, port)

        self.assertEqual(message.type, defines.inv_types["ACK"])
        self.assertEqual(message.code, None)
        self.assertEqual(message.mid, self.current_mid - 1)
        self.assertEqual(message.source, source)

        datagram, source = sock.recvfrom(4096)
        host, port = source
        message = serializer.deserialize(datagram, host, port)

        self.assertEqual(message.type, notification.type)
        self.assertEqual(message.code, notification.code)
        self.assertEqual(message.source, source)
        self.assertEqual(message.token, notification.token)
        self.assertEqual(message.payload, notification.payload)
        self.assertEqual(message.options, notification.options)

        message = Message.new_ack(message)
        datagram = serializer.serialize(message)
        sock.sendto(datagram, self.server_address)
        sock.close()
Exemplo n.º 27
0
 def to_coap_response(http_response, request_method, client_address, mid,
                      token):
     coap_msg = Message()
     coap_msg.destination = client_address
     coap_msg.type = Types["ACK"]
     coap_msg.code = CoAP_HTTP.to_coap_code(http_response.status_code,
                                            request_method)
     coap_msg.mid = mid
     coap_msg.token = token
     if 'Content-Type' in http_response.headers:
         coap_msg.content_type = CoAP_HTTP.to_coap_content_type(
             http_response.headers['Content-Type'].split(";")[0])
     else:
         coap_msg.content_type = 0
     coap_msg.payload = http_response.content
     return coap_msg
Exemplo n.º 28
0
    def _test_modular(self, lst):
        serializer = Serializer()
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        for t in lst:
            message, expected = t
            send_ack = False
            if message is not None:
                datagram = serializer.serialize(message)
                sock.sendto(datagram, self.server_address)
            else:
                send_ack = True

            datagram, source = sock.recvfrom(4096)
            host, port = source
            message = serializer.deserialize(datagram, host, port)
            self.assertEqual(message.type, expected.type)
            if not send_ack:
                self.assertEqual(message.mid, expected.mid)
            self.assertEqual(message.code, expected.code)
            self.assertEqual(message.source, source)
            self.assertEqual(message.token, expected.token)
            self.assertEqual(message.payload, expected.payload)
            self.assertEqual(message.options, expected.options)
            if send_ack:
                message = Message.new_ack(message)
                datagram = serializer.serialize(message)
                sock.sendto(datagram, self.server_address)

        sock.close()
Exemplo n.º 29
0
 def to_coap_response(http_response, request_method, client_address, mid):
     coap_msg = Message()
     coap_msg.destination = client_address
     coap_msg.type = Types["ACK"]
     coap_msg.code = CoAP_HTTP.to_coap_code(http_response.status_code, request_method)
     coap_msg.mid = mid
     if 'Content-Type' in http_response.headers:
         coap_msg.content_type = CoAP_HTTP.to_coap_content_type(http_response.headers['Content-Type'].split(";")[0])
     else:
         coap_msg.content_type = 0
     coap_msg.payload = http_response.content
     return coap_msg
Exemplo n.º 30
0
 def handle_response(self, response):
     if response.type == defines.inv_types["CON"]:
         ack = Message.new_ack(response)
         self.send(ack)
     key_token = hash(str(self.server[0]) + str(self.server[1]) + str(response.token))
     if key_token in self.sent_token.keys():
         self.received_token[key_token] = response
         req, timestamp, callback, client_callback = self.sent_token[key_token]
         key = hash(str(self.server[0]) + str(self.server[1]) + str(req.mid))
         self.received[key] = response
         callback(req.mid, client_callback)
Exemplo n.º 31
0
def coap_encode(payload):
    message = Message()
    message.type = defines.Types['CON']
    message.token = 4321
    message.mid = 2
    message.options = None
    message.payload = str(payload)
    serializer = Serializer()
    messagestring = serializer.serialize(message)
    return messagestring
Exemplo n.º 32
0
 def cancel_observing(self, response, send_rst):  # pragma: no cover
     if send_rst:
         message = Message()
         message.destination = self.server
         message.code = defines.Codes.EMPTY.number
         message.type = defines.Types["RST"]
         message.token = response.token
         message.mid = response.mid
         self.protocol.send_message(message)
     self.stop()
Exemplo n.º 33
0
    def handle_request(self, request):
        """
        Handles requests.

        :param request: the request
        :return: the response
        """
        host, port = request.source
        key = hash(str(host) + str(port) + str(request.mid))
        if key not in self._parent.received:
            if request.blockwise:
                # Blockwise
                last, request = self._parent.blockwise_transfer(request)
                if last:
                    self._parent.received[key] = (request, time.time())
                    return request
            else:
                self._parent.received[key] = (request, time.time())
                return request
        else:
            request, timestamp = self._parent.received.get(key)
            request.duplicated = True
            self._parent.received[key] = (request, timestamp)
            try:
                response, timestamp = self._parent.sent.get(key)
            except TypeError:
                response = None
            if isinstance(response, Response):
                return response
            elif request.acknowledged:
                ack = Message.new_ack(request)
                return ack
            elif request.rejected:
                rst = Message.new_rst(request)
                return rst
            else:
                # The server has not yet decided, whether to acknowledge or
                # reject the request. We know for sure that the server has
                # received the request though and can drop this duplicate here.
                return None
Exemplo n.º 34
0
 def _test_with_client_observe(self, message_list,
                               callback):  # pragma: no cover
     client = HelperClient(self.server_address)
     token = None
     last_mid = 0
     for message, expected in message_list:
         if message is not None:
             token = message.token
             client.send_request(message, callback)
         received_message = self.queue.get()
         if expected is not None:
             last_mid = expected.mid
             if expected.type is not None:
                 self.assertEqual(received_message.type, expected.type)
             if expected.mid is not None:
                 self.assertEqual(received_message.mid, expected.mid)
             self.assertEqual(received_message.code, expected.code)
             if expected.source is not None:
                 self.assertEqual(received_message.source,
                                  self.server_address)
             if expected.token is not None:
                 self.assertEqual(received_message.token, expected.token)
             if expected.payload is not None:
                 self.assertEqual(received_message.payload,
                                  expected.payload)
             if expected.options is not None:
                 self.assertEqual(received_message.options,
                                  expected.options)
     message = Message()
     message.type = defines.Types["RST"]
     message.token = token
     message._mid = last_mid
     message.destination = self.server_address
     client.send_empty(message)
     client.stop()
Exemplo n.º 35
0
    def send_ack(self, request):
        # Handle separate
        """
        Sends an ACK message for the request.

        :param request: [request] or request
        """
        if isinstance(request, list):
            request = request[0]
        ack = Message.new_ack(request)
        host, port = request.source
        self._parent.send(ack, host, port)
        request.acknowledged = True
Exemplo n.º 36
0
 def cancel_observing(self, response, send_rst):  # pragma: no cover
     if send_rst:
         message = Message()
         message.destination = self.server
         message.code = defines.Codes.EMPTY.number
         message.type = defines.Types["RST"]
         message.token = response.token
         message.mid = response.mid
         self.protocol.send_message(message)
     self.stop()
Exemplo n.º 37
0
    def datagramReceived(self, data, addr):
        """
        Handler for received UDP datagram.

        :param data: the UDP datagram
        :param host: source host
        :param port: source port
        """
        try:
            host, port = addr
        except ValueError:
            host, port, tmp1, tmp2 = addr
        log.msg("Datagram received from " + str(host) + ":" + str(port))
        serializer = Serializer()
        message = serializer.deserialize(data, host, port)
        print "Message received from " + host + ":" + str(port)
        print "----------------------------------------"
        print message
        print "----------------------------------------"
        if isinstance(message, Request):
            log.msg("Received request")
            ret = self.request_layer.handle_request(message)
            if isinstance(ret, Request):
                response = self.request_layer.process(ret)
            else:
                response = ret
            self.schedule_retrasmission(message, response, None)
            log.msg("Send Response")
            self.send(response, host, port)
        elif isinstance(message, Response):
            log.err("Received response")
            rst = Message.new_rst(message)
            rst = self.message_layer.matcher_response(rst)
            log.msg("Send RST")
            self.send(rst, host, port)
        elif isinstance(message, tuple):
            message, error = message
            response = Response()
            response.destination = (host, port)
            response.code = defines.responses[error]
            response = self.reliability_response(message, response)
            response = self.message_layer.matcher_response(response)
            log.msg("Send Error")
            self.send(response, host, port)
        elif message is not None:
            # ACK or RST
            log.msg("Received ACK or RST")
            self.message_layer.handle_message(message)
Exemplo n.º 38
0
def coap_encode(payload):
    message = Message()
    message.type = defines.Types['CON']
    message.token = 4321
    message.mid = 2
    message.options = None
    message.payload = str(payload)
    serializer = Serializer()
    messagestring = serializer.serialize(message)
    return messagestring
Exemplo n.º 39
0
 def handle_response(self, response):
     if response.type == defines.inv_types["CON"]:
         ack = Message.new_ack(response)
         self.send(ack, self._endpoint)
     key_token = hash(str(self._endpoint[0]) + str(self._endpoint[1]) + str(response.token))
     if key_token in self.sent_token.keys():
         self.received_token[key_token] = response
         req = self.sent_token[key_token]
         key = hash(str(self._endpoint[0]) + str(self._endpoint[1]) + str(req.mid))
         timer, counter = self.call_id[key]
         timer.cancel()
         self.received[key] = response
         self.condition.acquire()
         self._response = response
         self.condition.notify()
         self.condition.release()
Exemplo n.º 40
0
    def send_ack(self, list_request):
        """
        Send an ack to the client. Used mostly with separate.

        :param list_request: the request to be acknowledge.
        :type list_request: [Request] or Request
        """

        if isinstance(list_request, list):
            request = list_request[0]
        else:
            request = list_request
        del self.timer[request.mid]
        host, port = request.source
        ack = Message.new_ack(request)
        self.send(ack, host, port)
Exemplo n.º 41
0
    def send_ack(self, request):
        # Handle separate
        """
        Sends an ACK message for the request.

        :param request: [request, sleep_time] or request
        """
        if isinstance(request, list):
            if len(request) == 2:
                time.sleep(request[1])
            request = request[0]
        ack = Message.new_ack(request)
        host, port = request.source
        if not request.acknowledged:
            self._parent.send(ack, host, port)
            request.acknowledged = True
Exemplo n.º 42
0
    def finish_request(self, args):
        """
        Handler for received UDP datagram.

        :param args: (data, (client_ip, client_port)
        """
        data, client_address = args
        host = client_address[0]
        port = client_address[1]

        # logging.log(logging.INFO, "Datagram received from " + str(host) + ":" + str(port))
        serializer = Serializer()
        message = serializer.deserialize(data, host, port)
        # print "Message received from " + host + ":" + str(port)
        # print "----------------------------------------"
        # print message
        # print "----------------------------------------"
        if isinstance(message, Request):
            # log.msg("Received request")
            ret = self.request_layer.handle_request(message)
            if isinstance(ret, Request):
                response = self.request_layer.process(ret)
            else:
                response = ret
            self.schedule_retrasmission(message, response, None)
            # log.msg("Send Response")
            return response, host, port
        elif isinstance(message, Response):
            # log.err("Received response")
            rst = Message.new_rst(message)
            rst = self.message_layer.matcher_response(rst)
            # log.msg("Send RST")
            return rst, host, port
        elif isinstance(message, tuple):
            message, error = message
            response = Response()
            response.destination = (host, port)
            response.code = defines.responses[error]
            response = self.message_layer.reliability_response(message, response)
            response = self.message_layer.matcher_response(response)
            # log.msg("Send Error")
            return response, host, port
        elif message is not None:
            # ACK or RST
            # log.msg("Received ACK or RST")
            self.message_layer.handle_message(message)
            return None
Exemplo n.º 43
0
    def send_ack(self, list_request):
        """
        Send an ack to the client. Used mostly with separate.

        :param list_request: the request to be acknowledge.
        :type list_request: [Request] or Request
        """

        if isinstance(list_request, list):
            request = list_request[0]
        else:
            request = list_request
        key_timer = hash(str(request.source[0]) + str(request.source[1]) + str(request.mid))
        if self.timer.get(key_timer) is not None:
            del self.timer[key_timer]
        host, port = request.source
        ack = Message.new_ack(request)
        self.send(ack, host, port)
Exemplo n.º 44
0
    def cancel_observing(self, response, send_rst):  # pragma: no cover
        """
        Delete observing on the remote server.

        :param response: the last received response
        :param send_rst: if explicitly send RST message
        :type send_rst: bool
        """
        if send_rst:
            message = Message()
            message.destination = self.server
            message.code = defines.Codes.EMPTY.number
            message.type = defines.Types["RST"]
            message.token = response.token
            message.mid = response.mid
            self.protocol.send_message(message)
        self.stop()
Exemplo n.º 45
0
    def finish_request(self, request, client_address):
       
        
        host = client_address[0]
        port = client_address[1]
        data = request[0]
        self.socket = request[1]
 
        # log.msg("Datagram received from " + str(host) + ":" + str(port))
        serializer = Serializer()
        message = serializer.deserialize(data, host, port)
        # print "Message received from " + host + ":" + str(port)
        # print "----------------------------------------"
        # print message
        # print "----------------------------------------"
        if isinstance(message, Request):
            # log.msg("Received request")
            ret = self.request_layer.handle_request(message)
            if isinstance(ret, Request):
                self.forward_request(ret)
        elif isinstance(message, Response):
            # log.err("Received response")
            rst = Message.new_rst(message)
            rst = self.message_layer.matcher_response(rst)
            # log.msg("Send RST")
            self.send(rst, host, port)
        elif isinstance(message, tuple):
            message, error = message
            response = Response()
            response.destination = (host, port)
            response.code = defines.responses[error]
            response = self.message_layer.reliability_response(message, response)
            response = self.message_layer.matcher_response(response)
            # log.msg("Send Error")
            self.send(response, host, port)
        elif message is not None:
            # ACK or RST
            # log.msg("Received ACK or RST")
            self.message_layer.handle_message(message)
Exemplo n.º 46
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 = 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
Exemplo n.º 47
0
    def listen(self, timeout=10):
        """
        Listen for incoming messages. Timeout is used to check if the server must be switched off.

        :param timeout: Socket Timeout in seconds
        """
        self._socket.settimeout(float(timeout))
        while not self.stopped.isSet():
            try:
                data, client_address = self._socket.recvfrom(4096)
                if len(client_address) > 2:
                    client_address = (client_address[0], client_address[1])
            except socket.timeout:
                continue
            except Exception as e:
                if self._cb_ignore_listen_exception is not None and callable(self._cb_ignore_listen_exception):
                    if self._cb_ignore_listen_exception(e, self):
                        continue
                raise
            try:
                serializer = Serializer()
                message = serializer.deserialize(data, client_address)
                if isinstance(message, int):
                    logger.error("receive_datagram - BAD REQUEST")

                    rst = Message()
                    rst.destination = client_address
                    rst.type = defines.Types["RST"]
                    rst.code = message
                    rst.mid = self._messageLayer.fetch_mid()
                    self.send_datagram(rst)
                    continue

                logger.debug("receive_datagram - " + str(message))
                if isinstance(message, Request):
                    transaction = self._messageLayer.receive_request(message)
                    if transaction.request.duplicated and transaction.completed:
                        logger.debug("message duplicated, transaction completed")
                        if transaction.response is not None:
                            self.send_datagram(transaction.response)
                        continue
                    elif transaction.request.duplicated and not transaction.completed:
                        logger.debug("message duplicated, transaction NOT completed")
                        self._send_ack(transaction)
                        continue
                    args = (transaction, )
                    t = threading.Thread(target=self.receive_request, args=args)
                    t.start()
                # self.receive_datagram(data, client_address)
                elif isinstance(message, Response):
                    logger.error("Received response from %s", message.source)

                else:  # is Message
                    transaction = self._messageLayer.receive_empty(message)
                    if transaction is not None:
                        with transaction:
                            self._blockLayer.receive_empty(message, transaction)
                            self._observeLayer.receive_empty(message, transaction)
            except Exception as e:
                logger.error("Exception received in listen")
                logger.exception(traceback.format_exc())
                continue
            except RuntimeError:
                logger.exception("Exception with Executor")
        try:
            # Python does not close the OS FD on socket.close()
            # Ensure OS socket is closed with shutdown to prevent FD leak
            self._socket.shutdown(socket.SHUT_RDWR)
        except socket.error:
            pass
        self._socket.close()
Exemplo n.º 48
0
    def receive_datagram(self, args):
        """
        Handle messages coming from the udp socket.

        :param args: (data, client_address)
        """
        data, client_address = args

        logging.debug("receiving datagram")

        try:
            host, port = client_address
        except ValueError:
            host, port, tmp1, tmp2 = client_address

        client_address = (host, port)

        serializer = Serializer()
        message = serializer.deserialize(data, client_address)
        if isinstance(message, int):
            logger.error("receive_datagram - BAD REQUEST")

            rst = Message()
            rst.destination = client_address
            rst.type = defines.Types["RST"]
            rst.code = message
            self.send_datagram(rst)
            return
        logger.info("receive_datagram - " + str(message))
        if isinstance(message, Request):

            transaction = self._messageLayer.receive_request(message)

            if transaction.request.duplicated and transaction.completed:
                logger.debug("message duplicated, transaction completed")
                transaction = self._observeLayer.send_response(transaction)
                transaction = self._blockLayer.send_response(transaction)
                transaction = self._messageLayer.send_response(transaction)
                self.send_datagram(transaction.response)
                return
            elif transaction.request.duplicated and not transaction.completed:
                logger.debug("message duplicated, transaction NOT completed")
                self._send_ack(transaction)
                return

            transaction.separate_timer = self._start_separate_timer(
                transaction)

            transaction = self._blockLayer.receive_request(transaction)

            if transaction.block_transfer:
                self._stop_separate_timer(transaction.separate_timer)
                transaction = self._messageLayer.send_response(transaction)
                self.send_datagram(transaction.response)
                return

            transaction = self._observeLayer.receive_request(transaction)
            """
            call to the cache layer to check if there's a cached response for the request
            if not, call the forward layer
            """
            if self._cacheLayer is not None:
                transaction = self._cacheLayer.receive_request(transaction)

                if transaction.cacheHit is False:
                    logging.debug(transaction.request)
                    transaction = self._forwardLayer.receive_request(
                        transaction)
                    logging.debug(transaction.response)

                transaction = self._observeLayer.send_response(transaction)

                transaction = self._blockLayer.send_response(transaction)

                transaction = self._cacheLayer.send_response(transaction)
            else:
                transaction = self._forwardLayer.receive_request(transaction)

                transaction = self._observeLayer.send_response(transaction)

                transaction = self._blockLayer.send_response(transaction)

            self._stop_separate_timer(transaction.separate_timer)

            transaction = self._messageLayer.send_response(transaction)

            if transaction.response is not None:
                if transaction.response.type == defines.Types["CON"]:
                    self._start_retransmission(transaction,
                                               transaction.response)
                self.send_datagram(transaction.response)

        elif isinstance(message, Message):
            transaction = self._messageLayer.receive_empty(message)
            if transaction is not None:
                transaction = self._blockLayer.receive_empty(
                    message, transaction)
                self._observeLayer.receive_empty(message, transaction)

        else:  # is Response
            logger.error("Received response from %s", message.source)
Exemplo n.º 49
0
    def receive_datagram(self, args):
        """
        Handle messages coming from the udp socket.

        :param args: (data, client_address)
        """
        data, client_address = args

        logging.debug("receiving datagram")

        try:
            host, port = client_address
        except ValueError:
            host, port, tmp1, tmp2 = client_address

        client_address = (host, port)

        serializer = Serializer()
        message = serializer.deserialize(data, client_address)
        if isinstance(message, int):
            logger.error("receive_datagram - BAD REQUEST")
            rst = Message()
            rst.destination = client_address
            rst.type = Types["RST"]
            rst.code = message
            rst.mid = message.mid
            self.send_datagram(rst)
            return
        logger.debug("receive_datagram - " + str(message))

        if isinstance(message, Request):
            if not message.proxy_uri or message.uri_path != "coap2http":
                logger.error("receive_datagram - BAD REQUEST")
                rst = Message()
                rst.destination = client_address
                rst.type = Types["RST"]
                rst.code = Codes.BAD_REQUEST.number
                rst.mid = message.mid
                self.send_datagram(rst)
                return
            # Execute HTTP/HTTPS request
            http_response = CoAP_HTTP.execute_http_request(
                message.code, message.proxy_uri, message.payload)
            # HTTP response to CoAP response conversion
            coap_response = CoAP_HTTP.to_coap_response(http_response,
                                                       message.code,
                                                       client_address,
                                                       message.mid)
            # Send datagram and return
            self.send_datagram(coap_response)
            return

        elif isinstance(message, Message):
            logger.error("Received message from %s", message.source)

        else:  # is Response
            logger.error("Received response from %s", message.source)
Exemplo n.º 50
0
    def listen(self, timeout=10):
        """
        Listen for incoming messages. Timeout is used to check if the server must be switched off.

        :param timeout: Socket Timeout in seconds
        """
        self._socket.settimeout(float(timeout))
        empty = []
        while not self.stopped.isSet():
            try:
                data = None
                client_address = None
                readable, writable, exceptional = select.select(self._socketlist, empty, empty, timeout)
                for s in readable:
                    data, client_address = s.recvfrom(4096)
                    if len(client_address) > 2:
                        client_address = (client_address[0], client_address[1])
                        print ("listen : received ", client_address)
            except socket.timeout:
                print (".")
                continue
            except Exception as e:
                if self._cb_ignore_listen_exception is not None and isinstance(self._cb_ignore_listen_exception, collections.Callable):
                    if self._cb_ignore_listen_exception(e, self):
                        continue
                raise
            try:
                serializer = Serializer()
                if data is not None:
                    message = serializer.deserialize(data, client_address)
                
                    if isinstance(message, int):
                        logger.error("receive_datagram - BAD REQUEST")

                        rst = Message()
                        rst.destination = client_address
                        rst.type = defines.Types["RST"]
                        rst.code = message
                        rst.mid = self._messageLayer.fetch_mid()
                        self.send_datagram(rst)
                        continue

                    logger.debug("receive_datagram - " + str(message))
                    if isinstance(message, Request):
                        transaction = self._messageLayer.receive_request(message)
                        if transaction.request.duplicated and transaction.completed:
                            logger.debug("message duplicated, transaction completed")
                            if transaction.response is not None:
                                self.send_datagram(transaction.response)
                            continue
                        elif transaction.request.duplicated and not transaction.completed:
                            logger.debug("message duplicated, transaction NOT completed")
                            self._send_ack(transaction)
                            continue
                        args = (transaction, )
                        t = threading.Thread(target=self.receive_request, args=args)
                        t.start()
                    # self.receive_datagram(data, client_address)
                    elif isinstance(message, Response):
                        logger.error("Received response from %s", message.source)

                    else:  # is Message
                        transaction = self._messageLayer.receive_empty(message)
                        if transaction is not None:
                            with transaction:
                                self._blockLayer.receive_empty(message, transaction)
                                self._observeLayer.receive_empty(message, transaction)

            except RuntimeError:
                logger.exception("Exception with Executor")
        # close sockets
        for sock in self._socketlist:
            sock.close()
Exemplo n.º 51
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
Exemplo n.º 52
0
def main():  # pragma: no cover
    ip = "192.168.1.21"
    port = defines.COAP_DEFAULT_PORT
    multicast = False
    server = CoAPServer(ip, port, multicast)
    server.notify('/basic')
    try:
        # server.listen()
        while not server.stopped.isSet():
            data, client_address = server._socket.recvfrom(4096)
            try:
                serializer = Serializer()
                message = serializer.deserialize(data, client_address)
                if isinstance(message, int):
                    print("receive_datagram - BAD REQUEST")

                    rst = Message()
                    rst.destination = client_address
                    rst.type = defines.Types["RST"]
                    rst.code = message
                    rst.mid = server._messageLayer.fetch_mid()
                    server.send_datagram(rst)
                    continue

                # print("receive_datagram " + str(message.payload))
                database().insert_value('CoAP', datetime.datetime.now(),
                                        str(message.payload))

                if isinstance(message, Request):
                    transaction = server._messageLayer.receive_request(message)
                    if transaction.request.duplicated and transaction.completed:
                        print("message duplicated, transaction completed")
                        if transaction.response is not None:
                            server.send_datagram(transaction.response)
                        continue
                    elif transaction.request.duplicated and not transaction.completed:
                        print("message duplicated, transaction NOT completed")
                        server._send_ack(transaction)
                        continue
                    args = (transaction, )
                    t = threading.Thread(target=server.receive_request,
                                         args=args)
                    t.start()
                # self.receive_datagram(data, client_address)
                elif isinstance(message, Response):
                    print("Received response from %s", message.source)

                else:  # is Message
                    transaction = server._messageLayer.receive_empty(message)
                    if transaction is not None:
                        with transaction:
                            server._blockLayer.receive_empty(
                                message, transaction)
                            server._observeLayer.receive_empty(
                                message, transaction)

            except RuntimeError:
                print("Exception with Executor")
        server._socket.close()
    except KeyboardInterrupt:
        print("Server Shutdown")
        server.close()
        print("Exiting...")
Exemplo n.º 53
0
    def receive_datagram(self, args):
        """
        Receive datagram from the udp socket.

        :rtype : Message
        """
        data, client_address = args

        serializer = Serializer()
        message = serializer.deserialize(data, client_address)
        if isinstance(message, int):
            logger.error("receive_datagram - BAD REQUEST")

            rst = Message()
            rst.destination = client_address
            rst.type = defines.Types["RST"]
            rst.code = message
            self.send_datagram(rst)
            return
        logger.debug("receive_datagram - " + str(message))
        if isinstance(message, Request):

            transaction = self._messageLayer.receive_request(message)

            if transaction.request.duplicated and transaction.completed:
                logger.debug("message duplicated,transaction completed")
                transaction = self._observeLayer.send_response(transaction)
                transaction = self._blockLayer.send_response(transaction)
                transaction = self._messageLayer.send_response(transaction)
                self.send_datagram(transaction.response)
                return
            elif transaction.request.duplicated and not transaction.completed:
                logger.debug("message duplicated,transaction NOT completed")
                self._send_ack(transaction)
                return

            transaction.separate_timer = self._start_separate_timer(
                transaction)

            transaction = self._blockLayer.receive_request(transaction)

            if transaction.block_transfer:
                self._stop_separate_timer(transaction.separate_timer)
                transaction = self._messageLayer.send_response(transaction)
                self.send_datagram(transaction.response)
                return

            transaction = self._observeLayer.receive_request(transaction)

            transaction = self._forwardLayer.receive_request_reverse(
                transaction)

            transaction = self._observeLayer.send_response(transaction)

            transaction = self._blockLayer.send_response(transaction)

            self._stop_separate_timer(transaction.separate_timer)

            transaction = self._messageLayer.send_response(transaction)

            if transaction.response is not None:
                if transaction.response.type == defines.Types["CON"]:
                    self._start_retrasmission(transaction,
                                              transaction.response)
                self.send_datagram(transaction.response)

        elif isinstance(message, Message):
            transaction = self._messageLayer.receive_empty(message)
            if transaction is not None:
                transaction = self._blockLayer.receive_empty(
                    message, transaction)
                self._observeLayer.receive_empty(message, transaction)

        else:  # pragma: no cover
            logger.error("Received response from %s", message.source)
Exemplo n.º 54
0
    def listen(self, timeout=10):
        """
        Listen for incoming messages. Timeout is used to check if the server must be switched off.

        :param timeout: Socket Timeout in seconds
        """
        self._socket.settimeout(float(timeout))
        while not self.stopped.isSet():
            try:
                data, client_address = self._socket.recvfrom(4096)
                if len(client_address) > 2:
                    client_address = (client_address[0], client_address[1])
            except socket.timeout:
                continue
            try:
                serializer = Serializer()
                message = serializer.deserialize(data, client_address)
                if isinstance(message, int):
                    logger.error("receive_datagram - BAD REQUEST")

                    rst = Message()
                    rst.destination = client_address
                    rst.type = defines.Types["RST"]
                    rst.code = message
                    rst.mid = self._messageLayer._current_mid
                    self._messageLayer._current_mid += 1 % 65535
                    self.send_datagram(rst)
                    continue

                logger.debug("receive_datagram - " + str(message))
                if isinstance(message, Request):
                    transaction = self._messageLayer.receive_request(message)
                    if transaction.request.duplicated and transaction.completed:
                        logger.debug(
                            "message duplicated, transaction completed")
                        if transaction.response is not None:
                            self.send_datagram(transaction.response)
                        continue
                    elif transaction.request.duplicated and not transaction.completed:
                        logger.debug(
                            "message duplicated, transaction NOT completed")
                        self._send_ack(transaction)
                        continue
                    args = (transaction, )
                    t = threading.Thread(target=self.receive_request,
                                         args=args)
                    t.start()
                # self.receive_datagram(data, client_address)
                elif isinstance(message, Response):
                    logger.error("Received response from %s", message.source)

                else:  # is Message
                    transaction = self._messageLayer.receive_empty(message)
                    if transaction is not None:
                        with transaction:
                            self._blockLayer.receive_empty(
                                message, transaction)
                            self._observeLayer.receive_empty(
                                message, transaction)

            except RuntimeError:
                print "Exception with Executor"
        self._socket.close()