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)
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()
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")
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()
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()
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
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
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)
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)
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)
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)
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)
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)
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(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: # is Response logger.error("Received response from %s", message.source)
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)
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")
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 RuntimeError: logger.exception("Exception with Executor") self._socket.close()
def receive_datagram(self, args): """ Handle messages coming from the udp socket. :param args: (data, client_address) """ 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) """ 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: logger.debug(transaction.request) transaction = self._forwardLayer.receive_request_reverse( transaction) logger.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_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)
message = serializer.deserialize(datagram, source) if isinstance(message, Response): transaction, send_ack = self._messageLayer.receive_response(message) if send_ack: self._send_ack(transaction) transaction = self._blockLayer.receive_response(transaction) if transaction.block_transfer: transaction = self._messageLayer.send_request(transaction.request) self.send_datagram(transaction.request) continue transaction = self._observeLayer.receive_response(transaction) if transaction.notification: 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): transaction = self._messageLayer.receive_empty(message) def _send_ack(self, transaction): # Handle separate """ Sends an ACK message for the request. :param request: [request, sleep_time] or request """
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.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) """ 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)