diff --git a/coapthon/client/coap.py b/coapthon/client/coap.py index 8627f8e..d2bed4c 100644 --- a/coapthon/client/coap.py +++ b/coapthon/client/coap.py @@ -14,18 +14,13 @@ from coapthon.messages.message import Message from coapthon.messages.request import Request from coapthon.messages.response import Response from coapthon.serializer import Serializer -from coapthon.utils import create_logging import collections __author__ = 'Giacomo Tanganelli' -if not os.path.isfile("logging.conf"): - create_logging() - logger = logging.getLogger(__name__) -logging.config.fileConfig("logging.conf", disable_existing_loggers=False) class CoAP(object): @@ -165,8 +160,16 @@ class CoAP(object): if not self._cb_ignore_write_exception(e, self): raise + # if you're explicitly setting that you don't want a response, don't wait for it + # https://tools.ietf.org/html/rfc7967#section-2.1 + for opt in message.options: + if opt.number == defines.OptionRegistry.NO_RESPONSE.number: + if opt.value == 26: + return + if self._receiver_thread is None or not self._receiver_thread.isAlive(): self._receiver_thread = threading.Thread(target=self.receive_datagram) + self._receiver_thread.daemon = True self._receiver_thread.start() def _start_retransmission(self, transaction, message): diff --git a/coapthon/client/helperclient.py b/coapthon/client/helperclient.py index af2a693..d204b68 100644 --- a/coapthon/client/helperclient.py +++ b/coapthon/client/helperclient.py @@ -152,7 +152,7 @@ class HelperClient(object): return self.send_request(request, callback, timeout) - def post(self, path, payload, callback=None, timeout=None, **kwargs): # pragma: no cover + def post(self, path, payload, callback=None, timeout=None, no_response=False, **kwargs): # pragma: no cover """ Perform a POST on a certain path. @@ -166,13 +166,17 @@ class HelperClient(object): request.token = generate_random_token(2) request.payload = payload + if no_response: + request.add_no_response() + request.type = defines.Types["NON"] + for k, v in kwargs.items(): if hasattr(request, k): setattr(request, k, v) - return self.send_request(request, callback, timeout) + return self.send_request(request, callback, timeout, no_response=no_response) - def put(self, path, payload, callback=None, timeout=None, **kwargs): # pragma: no cover + def put(self, path, payload, callback=None, timeout=None, no_response=False, **kwargs): # pragma: no cover """ Perform a PUT on a certain path. @@ -186,11 +190,15 @@ class HelperClient(object): request.token = generate_random_token(2) request.payload = payload + if no_response: + request.add_no_response() + request.type = defines.Types["NON"] + for k, v in kwargs.items(): if hasattr(request, k): setattr(request, k, v) - return self.send_request(request, callback, timeout) + return self.send_request(request, callback, timeout, no_response=no_response) def discover(self, callback=None, timeout=None, **kwargs): # pragma: no cover """ @@ -208,7 +216,7 @@ class HelperClient(object): return self.send_request(request, callback, timeout) - def send_request(self, request, callback=None, timeout=None): # pragma: no cover + def send_request(self, request, callback=None, timeout=None, no_response=False): # pragma: no cover """ Send a request to the remote server. @@ -222,6 +230,8 @@ class HelperClient(object): thread.start() else: self.protocol.send_message(request) + if no_response: + return try: response = self.queue.get(block=True, timeout=timeout) except Empty: diff --git a/coapthon/defines.py b/coapthon/defines.py index b786021..9b081ea 100644 --- a/coapthon/defines.py +++ b/coapthon/defines.py @@ -127,6 +127,7 @@ class OptionRegistry(object): PROXY_URI = OptionItem(35, "Proxy-Uri", STRING, False, None) PROXY_SCHEME = OptionItem(39, "Proxy-Schema", STRING, False, None) SIZE1 = OptionItem(60, "Size1", INTEGER, False, None) + NO_RESPONSE = OptionItem(258, "No-Response", INTEGER, False, None) RM_MESSAGE_SWITCHING = OptionItem(65524, "Routing", OPAQUE, False, None) LIST = { @@ -149,6 +150,7 @@ class OptionRegistry(object): 35: PROXY_URI, 39: PROXY_SCHEME, 60: SIZE1, + 258: NO_RESPONSE, 65524: RM_MESSAGE_SWITCHING } diff --git a/coapthon/forward_proxy/coap.py b/coapthon/forward_proxy/coap.py index 5b42ddb..b448cca 100644 --- a/coapthon/forward_proxy/coap.py +++ b/coapthon/forward_proxy/coap.py @@ -17,15 +17,12 @@ from coapthon.messages.message import Message from coapthon.messages.request import Request from coapthon.resources.resource import Resource from coapthon.serializer import Serializer -from coapthon.utils import Tree, create_logging +from coapthon.utils import Tree __author__ = 'Giacomo Tanganelli' -if not os.path.isfile("logging.conf"): - create_logging() logger = logging.getLogger(__name__) -logging.config.fileConfig("logging.conf", disable_existing_loggers=False) class CoAP(object): diff --git a/coapthon/layers/blocklayer.py b/coapthon/layers/blocklayer.py index 451ba3c..8f698a3 100644 --- a/coapthon/layers/blocklayer.py +++ b/coapthon/layers/blocklayer.py @@ -141,10 +141,10 @@ class BlockLayer(object): item.num += 1 item.byte += item.size if len(item.payload) <= item.byte: - m = 0 + item.m = 0 else: - m = 1 - request.block1 = (item.num, m, item.size) + item.m = 1 + request.block1 = (item.num, item.m, item.size) elif transaction.response.block2 is not None: num, m, size = transaction.response.block2 diff --git a/coapthon/messages/request.py b/coapthon/messages/request.py index 9eee41d..f6067d0 100644 --- a/coapthon/messages/request.py +++ b/coapthon/messages/request.py @@ -187,6 +187,16 @@ class Request(Message): option.value = None self.add_option(option) + def add_no_response(self): + """ + Add the no-response option to the request + # https://tools.ietf.org/html/rfc7967#section-2.1 + """ + option = Option() + option.number = defines.OptionRegistry.NO_RESPONSE.number + option.value = 26 + self.add_option(option) + @if_none_match.deleter def if_none_match(self): """ diff --git a/coapthon/reverse_proxy/coap.py b/coapthon/reverse_proxy/coap.py index 50db0d2..61ba364 100644 --- a/coapthon/reverse_proxy/coap.py +++ b/coapthon/reverse_proxy/coap.py @@ -21,16 +21,12 @@ from coapthon.messages.request import Request from coapthon.resources.remoteResource import RemoteResource from coapthon.resources.resource import Resource from coapthon.serializer import Serializer -from coapthon.utils import Tree, create_logging +from coapthon.utils import Tree __author__ = 'Giacomo Tanganelli' -if not os.path.isfile("logging.conf"): - create_logging() - logger = logging.getLogger(__name__) -logging.config.fileConfig("logging.conf", disable_existing_loggers=False) class CoAP(object): diff --git a/coapthon/serializer.py b/coapthon/serializer.py index c85445d..f938eeb 100644 --- a/coapthon/serializer.py +++ b/coapthon/serializer.py @@ -219,8 +219,12 @@ class Serializer(object): fmt += "B" values.append(defines.PAYLOAD_MARKER) - fmt += str(len(bytes(payload, "utf-8"))) + "s" - values.append(bytes(payload, "utf-8")) + if isinstance(payload, bytes): + fmt += str(len(payload)) + "s" + values.append(payload) + else: + fmt += str(len(bytes(payload, "utf-8"))) + "s" + values.append(bytes(payload, "utf-8")) # for b in str(payload): # fmt += "c" # values.append(bytes(b, "utf-8")) diff --git a/coapthon/server/coap.py b/coapthon/server/coap.py index e2b4e5e..5a52102 100644 --- a/coapthon/server/coap.py +++ b/coapthon/server/coap.py @@ -17,18 +17,13 @@ from coapthon.messages.response import Response from coapthon.resources.resource import Resource from coapthon.serializer import Serializer from coapthon.utils import Tree -from coapthon.utils import create_logging import collections __author__ = 'Giacomo Tanganelli' -if not os.path.isfile("logging.conf"): - create_logging() - logger = logging.getLogger(__name__) -logging.config.fileConfig("logging.conf", disable_existing_loggers=False) class CoAP(object):