def block2(self, value: Tuple[int, int, int]): """ Set the Block2 option. :param value: the Block2 value """ option = Option(defines.OptionRegistry.BLOCK2) 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)
def if_none_match(self, v: bool = True): """ Add the if-none-match option to the request. """ del self.if_none_match if v: option = Option(defines.OptionRegistry.IF_NONE_MATCH) option.value = None self.add_option(option)
def proxy_schema(self, value: str): """ Set the Proxy-Schema option of a request. :param value: the Proxy-Schema value """ del self.proxy_schema option = Option(defines.OptionRegistry.PROXY_SCHEME) option.value = value self.add_option(option)
def proxy_uri(self, value: str): """ Set the Proxy-Uri option of a request. :param value: the Proxy-Uri value """ del self.proxy_uri option = Option(defines.OptionRegistry.PROXY_URI) option.value = value self.add_option(option)
def no_response(self, v: bool = True): """ Add the no-response option to the request # https://tools.ietf.org/html/rfc7967#section-2.1 """ del self.no_response if v: option = Option(defines.OptionRegistry.NO_RESPONSE) option.value = 26 self.add_option(option)
def observe(self, ob: int): """ Add the Observe option. :param ob: observe count """ option = Option(defines.OptionRegistry.OBSERVE) option.value = ob self.del_option_by_number(defines.OptionRegistry.OBSERVE.value) self.add_option(option)
def max_age(self, value: int): """ Set the MaxAge of the response. :type value: int :param value: the MaxAge option """ del self.max_age option = Option(defines.OptionRegistry.MAX_AGE) option.value = value self.add_option(option)
def uri_query(self, value: str): """ Adds a query. :param value: the query """ del self.uri_query queries = value.split("&") for q in queries: option = Option(defines.OptionRegistry.URI_QUERY) option.value = q self.add_option(option)
def location_query(self, value: str): """ Set the Location-Query of the response. :type value: String :param value: the Location-Query as a string """ del self.location_query queries = value.split("&") for q in queries: option = Option(defines.OptionRegistry.LOCATION_QUERY) option.value = str(q) self.add_option(option)
def content_type(self, content_type: Union[defines.ContentType, int]): """ Set the Content-Type option of a response. :type content_type: int :param content_type: the Content-Type """ option = Option(defines.OptionRegistry.CONTENT_TYPE) if isinstance(content_type, defines.ContentType): option.value = content_type.value elif isinstance(content_type, int): option.value = content_type self.add_option(option)
def if_match(self, values: Union[List[bytes], bytes]): """ Set the If-Match option of a request. :param values: the If-Match values :type values : list """ del self.if_match if isinstance(values, bytes): values = [values] for v in values: option = Option(defines.OptionRegistry.IF_MATCH) option.value = v self.add_option(option)
def accept(self, value: int): """ Add an Accept option to a request. :param value: the Accept value """ del self.accept try: value = defines.ContentType(value) option = Option(defines.OptionRegistry.ACCEPT) option.value = value self.add_option(option) except ValueError: # pragma: no cover raise errors.CoAPException("Unknown Accept value")
def uri_path(self, path: str): """ Set the Uri-Path of a request. :param path: the Uri-Path """ del self.uri_path path = path.strip("/") tmp = path.split("?") path = tmp[0] paths = path.split("/") for p in paths: option = Option(defines.OptionRegistry.URI_PATH) option.value = p self.add_option(option)
def location_path(self, path: str): """ Set the Location-Path of the response. :type path: String :param path: the Location-Path as a string """ del self.location_path path = path.strip("/") tmp = path.split("?") path = tmp[0] paths = path.split("/") for p in paths: option = Option(defines.OptionRegistry.LOCATION_PATH) option.value = p self.add_option(option)
def etag(self, etag: List[Union[str, bytes]]): """ Add an ETag option to the message. :param etag: the etag """ if not isinstance(etag, list): etag = [etag] for e in etag: option = Option(defines.OptionRegistry.ETAG) if isinstance(e, str): e = e.encode("utf-8") if isinstance(e, bytes): option.value = e else: # pragma: no cover raise errors.CoAPException("ETAG must be Opaque") self.add_option(option)
def _deserialize_options(cls, data: bytes) -> Tuple[bytes, List[Option]]: ret = [] option_number = 0 while data: if data[0] == defines.PAYLOAD_MARKER: return data, ret field = data[0] delta = (field & 0xF0) >> 4 length = (field & 0x0F) data = data[1:] data, delta = Serializer._read_extended_value(delta, data) data, length = Serializer._read_extended_value(length, data) option_number += delta if len(data) < length: # pragma: no cover raise errors.CoAPException("Option value is not present") try: option_item = OptionRegistry(option_number) except KeyError or ValueError: (opt_critical, _, _) = OptionRegistry.get_option_flags(option_number) if opt_critical: # pragma: no cover raise errors.CoAPException( "Critical option {0} unknown".format(option_number)) else: # If the non-critical option is unknown # (vendor-specific, proprietary) - just skip it pass else: if length == 0: value = bytes() else: value = data[:length] option = Option(option_item) option.raw_value = value ret.append(option) finally: data = data[length:] return data, ret