Beispiel #1
0
    def block2(self, value):
        """
        Set the Block2 option.

        :param value: the Block2 value, (num, m, size)
        """
        option = Option()
        option.number = defines.inv_options['Block2']
        num, m, size = value

        if size > 1024:
            szx = 6
        elif 512 < size <= 1024:
            szx = 6
        elif 256 < size <= 512:
            szx = 5
        elif 128 < size <= 256:
            szx = 4
        elif 64 < size <= 128:
            szx = 3
        elif 32 < size <= 64:
            szx = 2
        elif 16 < size <= 32:
            szx = 1
        else:
            szx = 0

        value = (num << 4)
        value |= (m << 3)
        value |= szx

        option.value = value
        self.add_option(option)
Beispiel #2
0
    def block2(self, value):
        """
        Set the Block2 option.

        :param value: the Block2 value
        """
        option = Option()
        option.number = defines.OptionRegistry.BLOCK2.number
        num, m, size = value
        if size > 512:
            szx = 6
        elif 256 < size <= 512:
            szx = 5
        elif 128 < size <= 256:
            szx = 4
        elif 64 < size <= 128:
            szx = 3
        elif 32 < size <= 64:
            szx = 2
        elif 16 < size <= 32:
            szx = 1
        else:
            szx = 0

        value = (num << 4)
        value |= (m << 3)
        value |= szx

        option.value = value
        self.add_option(option)
Beispiel #3
0
    def add_block2(self, num, m, size):
        """
        Add and format a Block2 option to a request.

        :param num: num
        :param m: more blocks
        :param size: size in byte
        """
        option = Option()
        option.number = defines.inv_options['Block2']
        if size > 1024:
            szx = 6
        elif 512 < size <= 1024:
            szx = 6
        elif 256 < size <= 512:
            szx = 5
        elif 128 < size <= 256:
            szx = 4
        elif 64 < size <= 128:
            szx = 3
        elif 32 < size <= 64:
            szx = 2
        elif 16 < size <= 32:
            szx = 1
        else:
            szx = 0
        value = (num << 4)
        value |= (m << 3)
        value |= szx

        option.value = value
        self.add_option(option)
Beispiel #4
0
    def test_get_separate(self):
        print "\nGET /separate\n"
        args = ("/separate",)
        kwargs = {}
        path = args[0]
        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["CON"]
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        expected.payload = "Separate"

        self.current_mid += 1
        self._test_separate(req, expected)
Beispiel #5
0
    def block1(self, value):
        """
        Set the Block1 option.

        :param value: the Block1 value
        """
        option = Option()
        option.number = defines.OptionRegistry.BLOCK1.number
        num, m, size = value
        if size > 512:
            szx = 6
        elif 256 < size <= 512:
            szx = 5
        elif 128 < size <= 256:
            szx = 4
        elif 64 < size <= 128:
            szx = 3
        elif 32 < size <= 64:
            szx = 2
        elif 16 < size <= 32:
            szx = 1
        else:
            szx = 0

        value = (num << 4)
        value |= (m << 3)
        value |= szx

        option.value = value
        self.add_option(option)
Beispiel #6
0
    def test_get_not_found(self):
        print "\nGET /not_found\n"
        args = ("/not_found",)
        kwargs = {}
        path = args[0]
        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["NOT_FOUND"]
        expected.token = None
        expected.payload = None

        self.current_mid += 1
        self._test(req, expected)
Beispiel #7
0
    def test_long(self):
        print "\nGET /long\n"
        args = ("/long",)
        kwargs = {}
        path = args[0]
        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = None
        expected.token = None
        expected.payload = None

        expected2 = Response()
        expected2.type = defines.inv_types["CON"]
        expected2.code = defines.responses["CONTENT"]
        expected2.token = None
        expected2.payload = "Long Time"

        self.current_mid += 1
        self._test_modular([(req, expected), (None, expected2)])
Beispiel #8
0
    def block2(self, value):
        option = Option()
        option.number = defines.OptionRegistry.BLOCK2.number
        num, m, size = value
        if size > 1024:
            szx = 6
        elif 512 < size <= 1024:
            szx = 6
        elif 256 < size <= 512:
            szx = 5
        elif 128 < size <= 256:
            szx = 4
        elif 64 < size <= 128:
            szx = 3
        elif 32 < size <= 64:
            szx = 2
        elif 16 < size <= 32:
            szx = 1
        else:
            szx = 0

        value = (num << 4)
        value |= (m << 3)
        value |= szx

        option.value = value
        self.add_option(option)
Beispiel #9
0
 def if_match(self, values):
     assert isinstance(values, list)
     for v in values:
         option = Option()
         option.number = defines.OptionRegistry.IF_MATCH.number
         option.value = v
         self.add_option(option)
Beispiel #10
0
 def delete(self, client_callback, *args, **kwargs):
     if isinstance(args[0], str):
         path = str(args[0])
         req = Request()
         req.uri_path = path
         if "Token" in kwargs.keys():
             req.token = kwargs.get("Token")
             del kwargs["Token"]
         if "MID" in kwargs.keys():
             req.mid = kwargs.get("MID")
             del kwargs["MID"]
         if "Server" in kwargs.keys():
             req.destination = kwargs.get("Server")
             del kwargs["Server"]
     else:
         req = args[0]
     for key in kwargs:
         try:
             o = Option()
             o.number = defines.inv_options[key]
             o.value = kwargs[key]
             req.add_option(o)
         except KeyError:
             pass
     req.code = defines.inv_codes['DELETE']
     req.type = defines.inv_types["CON"]
     self.send_callback(req, self.delete_results, client_callback)
Beispiel #11
0
    def test_td_coap_core_07(self):
        print "TD_COAP_CORE_07"
        path = "/test"
        req = Request()

        req.code = defines.inv_codes['PUT']
        req.uri_path = path
        req.type = defines.inv_types["NON"]
        o = Option()
        o.number = defines.inv_options["Content-Type"]
        o.value = defines.inv_content_types["application/xml"]
        req.add_option(o)
        req._mid = self.current_mid
        req.destination = self.server_address
        req.payload = "<value>test</value>"

        expected = Response()
        expected.type = defines.inv_types["NON"]
        expected._mid = None
        expected.code = defines.responses["CHANGED"]
        expected.token = None
        expected.payload = None

        self.current_mid += 1
        self._test_plugtest(req, expected)
Beispiel #12
0
    def add_observing(self, resource, request, response):
        """
        Add an observer to a resource and sets the Observe option in the response.

        :param resource: the resource of interest
        :param request: the request
        :param response: the response
        :return: response
        """
        host, port = response.destination
        key = hash(str(host) + str(port) + str(response.token))
        observers = self._parent.relation.get(resource)
        now = int(round(time.time() * 1000))
        observe_count = resource.observe_count
        if observers is None:
            # log.msg("Initiate an observe relation between " + str(host) + ":" +
            #        str(port) + " and resource " + str(resource.path))
            observers = {key: (now, request, response)}
        elif key not in observers:
            # log.msg("Initiate an observe relation between " + str(host) + ":" +
            #         str(port) + " and resource " + str(resource.path))
            observers[key] = (now, request, response)
        else:
            # log.msg("Update observe relation between " + str(host) + ":" +
            #         str(port) + " and resource " + str(resource.path))
            old, request, response = observers[key]
            observers[key] = (now, request, response)
        self._parent.relation[resource] = observers
        option = Option()
        option.number = defines.inv_options['Observe']
        option.value = observe_count
        response.add_option(option)
        return response
Beispiel #13
0
 def if_match(self, values):
     assert isinstance(values, list)
     for v in values:
         option = Option()
         option.number = defines.OptionRegistry.IF_MATCH.number
         option.value = v
         self.add_option(option)
Beispiel #14
0
 def add_if_none_match(self):
     """
     Add the if-none-match option to the request.
     """
     option = Option()
     option.number = defines.OptionRegistry.IF_NONE_MATCH.number
     option.value = None
     self.add_option(option)
Beispiel #15
0
 def location_query(self, value):
     del self.location_query
     queries = value.split("&")
     for q in queries:
         option = Option()
         option.number = defines.OptionRegistry.LOCATION_QUERY.number
         option.value = str(q)
         self.add_option(option)
Beispiel #16
0
 def location_query(self, value):
     del self.location_query
     queries = value.split("&")
     for q in queries:
         option = Option()
         option.number = defines.OptionRegistry.LOCATION_QUERY.number
         option.value = str(q)
         self.add_option(option)
Beispiel #17
0
 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)
Beispiel #18
0
    def block1(self, value):
        option = Option()
        option.number = defines.inv_options["Block1"]
        num, m, size = value
        value = num << 4
        value |= m << 3
        value |= size

        option.value = value
Beispiel #19
0
 def ocf_content_format_version(self, value):
     """
     Add the ocf_content_format_version option to the request.
     """
     option = Option()
     #print (" setting ocf_content_format_version :", int(value))
     option.number = defines.OptionRegistry.OCF_CONTENT_FORMAT_VERSION.number
     option.value = int(value)
     print("request: ocf_content_format_version (setter)", option)
     self.add_option(option)
Beispiel #20
0
    def max_age(self, value):
        """
        Set the Max-Age option of a request.

        :param value: the Proxy-Schema value
        """
        option = Option()
        option.number = defines.OptionRegistry.MAX_AGE.number
        option.value = int(value)
        self.add_option(option)
Beispiel #21
0
 def location_path(self, path):
     path = path.strip("/")
     tmp = path.split("?")
     path = tmp[0]
     paths = path.split("/")
     for p in paths:
         option = Option()
         option.number = defines.OptionRegistry.LOCATION_PATH.number
         option.value = p
         self.add_option(option)
Beispiel #22
0
    def etag(self, etag):
        """
        Add an ETag option to the message.

        :param etag: the etag
        """
        option = Option()
        option.number = defines.inv_options['ETag']
        option.value = etag
        self.add_option(option)
Beispiel #23
0
    def uri_query(self, value):
        """
                Set the uri_query option of a request.

                :param value: the uri_query value
                """
        option = Option()
        option.number = defines.OptionRegistry.URI_QUERY.number
        option.value = str(value)
        self.add_option(option)
Beispiel #24
0
    def etag(self, etag):
        """
        Add an ETag option to the message.

        :param etag: the etag
        """
        option = Option()
        option.number = defines.OptionRegistry.ETAG.number
        option.value = etag
        self.add_option(option)
Beispiel #25
0
    def max_age(self, max_age):
        """
        Set the Max-Age option of a response.

        :param max_age: the Max-Age in seconds
        """
        option = Option()
        option.number = defines.inv_options["Max-Age"]
        option.value = int(max_age)
        self.add_option(option)
Beispiel #26
0
    def size2(self, value):
        """
        Set the Size2 option.

        :param value: the Block2 value
        """
        option = Option()
        option.number = defines.OptionRegistry.SIZE2.number
        option.value = value
        self.add_option(option)
Beispiel #27
0
 def location_path(self, path):
     path = path.strip("/")
     tmp = path.split("?")
     path = tmp[0]
     paths = path.split("/")
     for p in paths:
         option = Option()
         option.number = defines.OptionRegistry.LOCATION_PATH.number
         option.value = p
         self.add_option(option)
Beispiel #28
0
    def proxy_schema(self, value):
        """
        Set the Proxy-Schema option of a request.

        :param value: the Proxy-Schema value
        """
        option = Option()
        option.number = defines.OptionRegistry.PROXY_SCHEME.number
        option.value = str(value)
        self.add_option(option)
 def post(self, path, payload, callback=None, timeout=None, *options):
     request = self.mk_request(defines.Codes.POST, path)
     request.token = generate_random_token(2)
     request.payload = payload
     for number, value in options:
         option = Option()
         option.number = number
         option.value = value
         request.add_option(option)
     return self.send_request(request, callback, timeout)
Beispiel #30
0
    def proxy_uri(self, uri):
        """
        Set the Proxy-Uri option of a request.

        :param uri: the Proxy-Uri values
        """
        option = Option()
        option.number = defines.inv_options['Proxy-Uri']
        option.value = str(uri)
        self.add_option(option)
Beispiel #31
0
    def proxy_uri(self, value):
        """
        Set the Proxy-Uri option of a request.

        :param value: the Proxy-Uri value
        """
        option = Option()
        option.number = defines.OptionRegistry.PROXY_URI.number
        option.value = str(value)
        self.add_option(option)
Beispiel #32
0
    def proxy_schema(self, value):
        """
        Set the Proxy-Uri option of a request.

        :param value: the Proxy-Uri value
        """
        option = Option()
        option.number = defines.OptionRegistry.PROXY_SCHEME.number
        option.value = str(value)
        self.add_option(option)
Beispiel #33
0
    def add_no_response(self,value=26):
        """
        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
        #26 means 16+8+2: not interested in all responses
        option.value = value

        self.add_option(option)
Beispiel #34
0
    def accept(self, value):
        """
        Add an Accept option to a request.

        :param value: the Accept value
        """
        if value in defines.Content_types.values():
            option = Option()
            option.number = defines.OptionRegistry.ACCEPT.number
            option.value = value
            self.add_option(option)
Beispiel #35
0
    def observe(self, ob):
        """
        Add the Observe option.

        :param ob: observe count
        """
        option = Option()
        option.number = defines.inv_options['Observe']
        option.value = ob
        self.del_option_name("Observe")
        self.add_option(option)
Beispiel #36
0
    def content_type(self, content_type):
        """
        Set the Content-Type option of a response.

        :type content_type: int
        :param content_type: the Content-Type
        """
        option = Option()
        option.number = defines.inv_options['Content-Type']
        option.value = int(content_type)
        self.add_option(option)
Beispiel #37
0
    def observe(self, ob):
        """
        Add the Observe option.

        :param ob: observe count
        """
        option = Option()
        option.number = defines.OptionRegistry.OBSERVE.number
        option.value = ob
        self.del_option_by_number(defines.OptionRegistry.OBSERVE.number)
        self.add_option(option)
Beispiel #38
0
 def add_query(self, q):
     """
     Adds a query.
     :param q: the query
     """
     queries = q.split("&")
     for q in queries:
         option = Option()
         option.number = defines.inv_options['Uri-Query']
         option.value = str(q)
         self.add_option(option)
Beispiel #39
0
    def content_type(self, content_type):
        """
        Set the Content-Type option of a response.

        :type content_type: int
        :param content_type: the Content-Type
        """
        option = Option()
        option.number = defines.OptionRegistry.CONTENT_TYPE.number
        option.value = int(content_type)
        self.add_option(option)
Beispiel #40
0
    def content_type(self, content_type):
        """
        Set the Content-Type option of a response.

        :type content_type: int
        :param content_type: the Content-Type
        """
        option = Option()
        option.number = defines.OptionRegistry.CONTENT_TYPE.number
        option.value = int(content_type)
        self.add_option(option)
Beispiel #41
0
    def observe(self, ob):
        """
        Add the Observe option.

        :param ob: observe count
        """
        option = Option()
        option.number = defines.OptionRegistry.OBSERVE.number
        option.value = ob
        self.del_option_by_number(defines.OptionRegistry.OBSERVE.number)
        self.add_option(option)
Beispiel #42
0
    def if_none_match(self, value):
        """
        Set the If-Match option of a request.

        :param value: True/False
        :type values : bool
        """
        assert isinstance(value, bool)
        option = Option()
        option.number = defines.OptionRegistry.IF_NONE_MATCH.number
        option.value = None
        self.add_option(option)
Beispiel #43
0
    def max_age(self, value):
        """
        Set the MaxAge of the response.

        :type value: int
        :param value: the MaxAge option
        """
        option = Option()
        option.number = defines.OptionRegistry.MAX_AGE.number
        option.value = int(value)
        self.del_option_by_number(defines.OptionRegistry.MAX_AGE.number)
        self.add_option(option)
Beispiel #44
0
    def test_post_and_get_storage(self):
        print "\nPOST /storage/data1 - GET /storage/data1\n"
        args = ("/storage/data1",)
        kwargs = {}
        path = args[0]
        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['POST']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.payload = "Created"
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CREATED"]
        expected.token = None
        expected.payload = None
        option = Option()
        option.number = defines.inv_options["Location-Path"]
        option.value = "/storage/data1"
        expected.add_option(option)

        self.current_mid += 1

        self._test(req, expected)

        req = Request()
        for key in kwargs:
            o = Option()
            o.number = defines.inv_options[key]
            o.value = kwargs[key]
            req.add_option(o)

        req.code = defines.inv_codes['GET']
        req.uri_path = path
        req.type = defines.inv_types["CON"]
        req._mid = self.current_mid
        req.destination = self.server_address

        expected = Response()
        expected.type = defines.inv_types["ACK"]
        expected._mid = self.current_mid
        expected.code = defines.responses["CONTENT"]
        expected.token = None
        expected.payload = "Created"

        self.current_mid += 1

        self._test(req, expected)
Beispiel #45
0
    def uri_query(self, value):
        """
        Adds a query.

        :param value: the query
        """
        del self.uri_query
        queries = value.split("&")
        for q in queries:
            option = Option()
            option.number = defines.OptionRegistry.URI_QUERY.number
            option.value = str(q)
            self.add_option(option)
Beispiel #46
0
    def if_match(self, values):
        """
        Set the If-Match option of a request.

        :param values: the If-Match values
        :type values : list
        """
        assert isinstance(values, list)
        for v in values:
            option = Option()
            option.number = defines.OptionRegistry.IF_MATCH.number
            option.value = v
            self.add_option(option)
Beispiel #47
0
    def uri_query(self, value):
        """
        Adds a query.

        :param value: the query
        """
        del self.uri_query
        queries = value.split("&")
        for q in queries:
            option = Option()
            option.number = defines.OptionRegistry.URI_QUERY.number
            option.value = str(q)
            self.add_option(option)
Beispiel #48
0
    def etag(self, etag):
        """
        Add an ETag option to the message.

        :param etag: the etag
        """
        if not isinstance(etag, list):
            etag = [etag]
        for e in etag:
            option = Option()
            option.number = defines.OptionRegistry.ETAG.number
            option.value = e
            self.add_option(option)
Beispiel #49
0
    def ocf_accept_content_format_version(self, value):
        """
        Set the OCF_ACCEPT_CONTENT_FORMAT_VERSION of the response.

        :type value: int
        :param value: the OCF_ACCEPT_CONTENT_FORMAT_VERSION option
        """
        option = Option()
        option.number = defines.OptionRegistry.OCF_ACCEPT_CONTENT_FORMAT_VERSION.number
        option.value = int(value)
        self.del_option_by_number(defines.OptionRegistry.OCF_ACCEPT_CONTENT_FORMAT_VERSION.number)
        print ("response: ocf_accept_content_format_version (setter)",option)
        self.add_option(option)
Beispiel #50
0
def build_request(request, headers, device):
    """
    Helper method to organized required headers into the CoAP Request.
    :param request: Request being build
    :param headers: Data from AMQP message which contains data to forward OpenC2 Command.
    :param device:  Device specific data from headers sent by O.I.F.
    """
    orc_host, orc_port = headers["transport"]["socket"].split(
        ":", 1)  # location of orchestrator-side CoAP server
    request.source = (orc_host, safe_cast(orc_port, int, 5683))

    dev_host, dev_port = device["socket"].split(
        ":", 1)  # location of device-side CoAP server
    request.destination = (dev_host, safe_cast(dev_port, int, 5683))

    encoding = f"application/{device['encoding']}"  # Content Serialization
    request.content_type = defines.Content_types[
        encoding]  # using application/json, TODO: add define to openc2+json
    request.mid = int("0x" + headers["correlationID"],
                      16)  # 16-bit correlationID
    request.timestamp = headers[
        "date"]  # time message was sent from orchestrator

    # Add OIF-unique value used for routing to the desired actuator
    profile = Option()
    profile.number = 8
    profile.value = device.get("profile", "")[0]
    request.add_option(profile)

    source_socket = Option()
    source_socket.number = 3
    source_socket.value = headers["transport"]["socket"]
    request.add_option(source_socket)

    return request
Beispiel #51
0
    def location_query(self, value):
        """
        Set the Location-Query of the response.

        :type path: String
        :param path: the Location-Query as a string
        """
        del self.location_query
        queries = value.split("&")
        for q in queries:
            option = Option()
            option.number = defines.OptionRegistry.LOCATION_QUERY.number
            option.value = str(q)
            self.add_option(option)
Beispiel #52
0
    def location_path(self, path):
        """
        Set the Location-Path of the response.

        :type path: String
        :param path: the Location-Path as a string
        """
        path = path.strip("/")
        tmp = path.split("?")
        path = tmp[0]
        paths = path.split("/")
        for p in paths:
            option = Option()
            option.number = defines.OptionRegistry.LOCATION_PATH.number
            option.value = p
            self.add_option(option)
Beispiel #53
0
    def etag(self, etag):
        """
        Add an ETag option to the message.

        :param etag: the etag
        """
        if not isinstance(etag, list):
            etag = [etag]
        for e in etag:
            option = Option()
            option.number = defines.OptionRegistry.ETAG.number
            if isinstance(e, str):
                # if etag was accidentally set to str, convert it to bytes
                e = bytes(e, "utf-8")
            option.value = e
            self.add_option(option)
Beispiel #54
0
    def uri_path(self, path):
        """
        Set the Uri-Path of a request.

        :param path: the Uri-Path
        """
        path = path.strip("/")
        tmp = path.split("?")
        path = tmp[0]
        paths = path.split("/")
        for p in paths:
            option = Option()
            option.number = defines.OptionRegistry.URI_PATH.number
            option.value = p
            self.add_option(option)
        if len(tmp) > 1:
            query = tmp[1]
            self.uri_query = query
Beispiel #55
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
Beispiel #56
0
 def max_age(self, value):
     option = Option()
     option.number = defines.OptionRegistry.MAX_AGE.number
     option.value = int(value)
     self.add_option(option)