mirror of
https://github.com/espressif/openthread.git
synced 2026-09-08 10:10:06 +00:00
[style] update python style to conform to PEP 8 (#3951)
With the exception of line length set to 119 vs. 79. Add tests/ and tools/ to py-pretty-check.
This commit is contained in:
+261
-115
@@ -27,14 +27,12 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
import collections
|
||||
import io
|
||||
import ipaddress
|
||||
import struct
|
||||
import sys
|
||||
|
||||
import common
|
||||
import config
|
||||
import ipv6
|
||||
|
||||
|
||||
@@ -118,7 +116,8 @@ class LowpanIPHC:
|
||||
return cls(tf, nh, hlim, cid, sac, sam, m, dac, dam)
|
||||
|
||||
def __repr__(self):
|
||||
return "LowpanIPHC(tf={}, nh={}, hlim={}, cid={}, sac={}, sam={}, m={}, dac={}, dam={})".format(self.tf, self.nh, self.hlim, self.cid, self.sac, self.sam, self.m, self.dac, self.dam)
|
||||
return "LowpanIPHC(tf={}, nh={}, hlim={}, cid={}, sac={}, sam={}, m={}, dac={}, dam={})".format(
|
||||
self.tf, self.nh, self.hlim, self.cid, self.sac, self.sam, self.m, self.dac, self.dam, )
|
||||
|
||||
|
||||
class LowpanNHC:
|
||||
@@ -189,8 +188,8 @@ class LowpanUDPHC:
|
||||
def from_bytes(cls, data_bytes):
|
||||
data_byte = data_bytes[0]
|
||||
|
||||
hdr = (data_byte >> 3) & 0x1f
|
||||
if hdr != 0x1e:
|
||||
hdr = (data_byte >> 3) & 0x1F
|
||||
if hdr != 0x1E:
|
||||
raise RuntimeError("Not a 6LowPAN UDP header.")
|
||||
|
||||
c = (data_byte >> 2) & 0x01
|
||||
@@ -214,7 +213,9 @@ class LowpanHopByHopFactory:
|
||||
|
||||
ext_header_data = data.read(ext_header_length)
|
||||
|
||||
options = self._hop_by_hop_options_factory.parse(io.BytesIO(ext_header_data), message_info)
|
||||
options = self._hop_by_hop_options_factory.parse(
|
||||
io.BytesIO(ext_header_data), message_info
|
||||
)
|
||||
|
||||
ext_header = ipv6.HopByHop(next_header, options)
|
||||
|
||||
@@ -231,7 +232,9 @@ class LowpanExtensionHeadersFactory:
|
||||
NHC_NH_COMPRESSED = 1
|
||||
|
||||
def __init__(self, ext_headers_factories):
|
||||
self._ext_headers_factories = ext_headers_factories if ext_headers_factories is not None else {}
|
||||
self._ext_headers_factories = (
|
||||
ext_headers_factories if ext_headers_factories is not None else {}
|
||||
)
|
||||
|
||||
def _decompress_nh(self, hc, data):
|
||||
if hc.nh == self.NHC_NH_INLINE:
|
||||
@@ -244,8 +247,12 @@ class LowpanExtensionHeadersFactory:
|
||||
try:
|
||||
return self._ext_headers_factories[eid]
|
||||
|
||||
except:
|
||||
raise RuntimeError("Could not find an extension header factory for the EID type: {}".format(eid))
|
||||
except BaseException:
|
||||
raise RuntimeError(
|
||||
"Could not find an extension header factory for the EID type: {}".format(
|
||||
eid
|
||||
)
|
||||
)
|
||||
|
||||
def parse(self, data, message_info):
|
||||
nhc = LowpanNHC.from_bytes(bytearray(data.read(1)))
|
||||
@@ -310,8 +317,7 @@ class LowpanUdpHeaderFactory:
|
||||
return header
|
||||
|
||||
|
||||
class Context():
|
||||
|
||||
class Context:
|
||||
def __init__(self, prefix, prefix_length=None):
|
||||
if isinstance(prefix, str):
|
||||
if sys.version_info[0] == 2:
|
||||
@@ -327,15 +333,19 @@ class Context():
|
||||
|
||||
elif isinstance(prefix, bytearray):
|
||||
self._prefix = prefix
|
||||
self._prefix_length = prefix_length if prefix_length is not None else len(self._prefix) * 8
|
||||
self._prefix_length = (
|
||||
prefix_length
|
||||
if prefix_length is not None
|
||||
else len(self._prefix) * 8
|
||||
)
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
return self._prefix[:self.prefix_length_all_bytes]
|
||||
return self._prefix[: self.prefix_length_all_bytes]
|
||||
|
||||
@property
|
||||
def prefix_full_bytes(self):
|
||||
return self._prefix[:self.prefix_length_full_bytes]
|
||||
return self._prefix[: self.prefix_length_full_bytes]
|
||||
|
||||
@property
|
||||
def prefix_length(self):
|
||||
@@ -352,7 +362,7 @@ class Context():
|
||||
@property
|
||||
def prefix_length_all_bytes(self):
|
||||
if self.prefix_length_rest_bits > 0:
|
||||
return (self.prefix_length_full_bytes + 1)
|
||||
return self.prefix_length_full_bytes + 1
|
||||
|
||||
return self.prefix_length_full_bytes
|
||||
|
||||
@@ -363,7 +373,11 @@ class ContextManager(dict):
|
||||
|
||||
def __check_index(self, index):
|
||||
if index < 0 or index > 15:
|
||||
raise IndexError("Invalid index: {}. Valid index is in range [0, 15]".format(index))
|
||||
raise IndexError(
|
||||
"Invalid index: {}. Valid index is in range [0, 15]".format(
|
||||
index
|
||||
)
|
||||
)
|
||||
|
||||
def __check_type(self, value):
|
||||
if not isinstance(value, Context):
|
||||
@@ -385,7 +399,9 @@ class LowpanIpv6HeaderFactory:
|
||||
|
||||
""" Factory that produces IPv6 header. """
|
||||
|
||||
IPV6_LINKLOCAL_PREFIX = bytearray([0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
|
||||
IPV6_LINKLOCAL_PREFIX = bytearray(
|
||||
[0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
|
||||
)
|
||||
|
||||
SHORT_ADDR_PADDING_BYTES = bytearray([0x00, 0x00, 0x00, 0xff, 0xfe, 0x00])
|
||||
|
||||
@@ -449,10 +465,10 @@ class LowpanIpv6HeaderFactory:
|
||||
return (dscp << 2) | ecn
|
||||
|
||||
def _unpack_dscp(self, data_byte):
|
||||
return (data_byte & 0x3F)
|
||||
return data_byte & 0x3F
|
||||
|
||||
def _unpack_ecn(self, data_byte):
|
||||
return (data_byte >> 6)
|
||||
return data_byte >> 6
|
||||
|
||||
def _decompress_tf_4bytes(self, data):
|
||||
data_bytes = [b for b in bytearray(data.read(4))]
|
||||
@@ -523,8 +539,8 @@ class LowpanIpv6HeaderFactory:
|
||||
if iphc.cid == self.IPHC_CID_SET:
|
||||
cid = ord(data.read(1))
|
||||
|
||||
sci = (cid >> 4) & 0x0f
|
||||
dci = cid & 0x0f
|
||||
sci = (cid >> 4) & 0x0F
|
||||
dci = cid & 0x0F
|
||||
|
||||
return sci, dci
|
||||
|
||||
@@ -539,7 +555,11 @@ class LowpanIpv6HeaderFactory:
|
||||
return self.IPV6_LINKLOCAL_PREFIX + bytearray(data.read(8))
|
||||
|
||||
elif iphc.sam == self.IPHC_SAM_16B:
|
||||
return self.IPV6_LINKLOCAL_PREFIX + self.SHORT_ADDR_PADDING_BYTES + bytearray(data.read(2))
|
||||
return (
|
||||
self.IPV6_LINKLOCAL_PREFIX
|
||||
+ self.SHORT_ADDR_PADDING_BYTES
|
||||
+ bytearray(data.read(2))
|
||||
)
|
||||
|
||||
elif iphc.sam == self.IPHC_SAM_ELIDED:
|
||||
return self.IPV6_LINKLOCAL_PREFIX + src_mac_addr.convert_to_iid()
|
||||
@@ -557,7 +577,7 @@ class LowpanIpv6HeaderFactory:
|
||||
|
||||
# Case in which some bytes overlap
|
||||
if (prefix_length_all_bytes + len(address_bytes)) > required_bytes:
|
||||
###############################################################################################
|
||||
###################################################################
|
||||
# Example:
|
||||
#
|
||||
# Total address length: 128 bits
|
||||
@@ -570,7 +590,7 @@ class LowpanIpv6HeaderFactory:
|
||||
# +--------------------+---------------------+
|
||||
# | prefix (68 bits) | address (64 bits) |
|
||||
# +--------------------+---------------------+
|
||||
###############################################################################################
|
||||
###################################################################
|
||||
|
||||
src_addr = prefix[:prefix_length_full_bytes]
|
||||
required_bytes -= prefix_length_full_bytes
|
||||
@@ -579,8 +599,12 @@ class LowpanIpv6HeaderFactory:
|
||||
prefix_overlapping_byte = prefix[prefix_length_all_bytes - 1]
|
||||
address_overlapping_byte = address_bytes[-required_bytes]
|
||||
|
||||
overlapping_byte = prefix_overlapping_byte & ~(0xff >> prefix_length_rest_bits)
|
||||
overlapping_byte |= address_overlapping_byte & (0xff >> prefix_length_rest_bits)
|
||||
overlapping_byte = prefix_overlapping_byte & ~(
|
||||
0xff >> prefix_length_rest_bits
|
||||
)
|
||||
overlapping_byte |= address_overlapping_byte & (
|
||||
0xff >> prefix_length_rest_bits
|
||||
)
|
||||
|
||||
src_addr += bytearray([overlapping_byte])
|
||||
required_bytes -= 1
|
||||
@@ -592,7 +616,11 @@ class LowpanIpv6HeaderFactory:
|
||||
required_bytes -= prefix_length_all_bytes
|
||||
required_bytes -= len(address_bytes)
|
||||
|
||||
src_addr = prefix[:prefix_length_all_bytes] + bytearray([0x00] * required_bytes) + address_bytes
|
||||
src_addr = (
|
||||
prefix[:prefix_length_all_bytes]
|
||||
+ bytearray([0x00] * required_bytes)
|
||||
+ address_bytes
|
||||
)
|
||||
|
||||
return src_addr
|
||||
|
||||
@@ -603,31 +631,43 @@ class LowpanIpv6HeaderFactory:
|
||||
elif iphc.sam == self.IPHC_SAM_64B:
|
||||
context = self._context_manager[sci]
|
||||
|
||||
return self._merge_prefix_with_address(prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=bytearray(data.read(8)))
|
||||
return self._merge_prefix_with_address(
|
||||
prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=bytearray(data.read(8)),
|
||||
)
|
||||
|
||||
elif iphc.sam == self.IPHC_SAM_16B:
|
||||
context = self._context_manager[sci]
|
||||
address_bytes = self.SHORT_ADDR_PADDING_BYTES + bytearray(data.read(2))
|
||||
address_bytes = self.SHORT_ADDR_PADDING_BYTES + bytearray(
|
||||
data.read(2)
|
||||
)
|
||||
|
||||
return self._merge_prefix_with_address(prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=address_bytes)
|
||||
return self._merge_prefix_with_address(
|
||||
prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=address_bytes,
|
||||
)
|
||||
|
||||
elif iphc.sam == self.IPHC_SAM_0B:
|
||||
context = self._context_manager[sci]
|
||||
|
||||
return self._merge_prefix_with_address(prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=src_mac_addr.convert_to_iid())
|
||||
return self._merge_prefix_with_address(
|
||||
prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=src_mac_addr.convert_to_iid(),
|
||||
)
|
||||
|
||||
def _decompress_src_addr(self, iphc, src_mac_addr, sci, data):
|
||||
if iphc.sac == self.IPHC_SAC_STATELESS:
|
||||
return self._decompress_src_addr_stateless(iphc, src_mac_addr, data)
|
||||
return self._decompress_src_addr_stateless(
|
||||
iphc, src_mac_addr, data
|
||||
)
|
||||
|
||||
elif iphc.sac == self.IPHC_SAC_STATEFUL:
|
||||
return self._decompress_src_addr_stateful(iphc, src_mac_addr, sci, data)
|
||||
return self._decompress_src_addr_stateful(
|
||||
iphc, src_mac_addr, sci, data
|
||||
)
|
||||
|
||||
def _decompress_unicast_dst_addr_stateless(self, iphc, dst_mac_addr, data):
|
||||
if iphc.dam == self.IPHC_DAM_128B:
|
||||
@@ -637,43 +677,61 @@ class LowpanIpv6HeaderFactory:
|
||||
return self.IPV6_LINKLOCAL_PREFIX + bytearray(data.read(8))
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_16B:
|
||||
return self.IPV6_LINKLOCAL_PREFIX + self.SHORT_ADDR_PADDING_BYTES + bytearray(data.read(2))
|
||||
return (
|
||||
self.IPV6_LINKLOCAL_PREFIX
|
||||
+ self.SHORT_ADDR_PADDING_BYTES
|
||||
+ bytearray(data.read(2))
|
||||
)
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_ELIDED:
|
||||
return self.IPV6_LINKLOCAL_PREFIX + dst_mac_addr.convert_to_iid()
|
||||
|
||||
def _decompress_unicast_dst_addr_stateful(self, iphc, dst_mac_addr, dci, data):
|
||||
def _decompress_unicast_dst_addr_stateful(
|
||||
self, iphc, dst_mac_addr, dci, data
|
||||
):
|
||||
if iphc.dam == self.IPHC_DAM_128B:
|
||||
raise RuntimeError("Reserved")
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_64B:
|
||||
context = self._context_manager[dci]
|
||||
|
||||
return self._merge_prefix_with_address(prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=bytearray(data.read(8)))
|
||||
return self._merge_prefix_with_address(
|
||||
prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=bytearray(data.read(8)),
|
||||
)
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_16B:
|
||||
context = self._context_manager[dci]
|
||||
address_bytes = self.SHORT_ADDR_PADDING_BYTES + bytearray(data.read(2))
|
||||
address_bytes = self.SHORT_ADDR_PADDING_BYTES + bytearray(
|
||||
data.read(2)
|
||||
)
|
||||
|
||||
return self._merge_prefix_with_address(prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=address_bytes)
|
||||
return self._merge_prefix_with_address(
|
||||
prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=address_bytes,
|
||||
)
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_0B:
|
||||
context = self._context_manager[dci]
|
||||
|
||||
return self._merge_prefix_with_address(prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=dst_mac_addr.convert_to_iid())
|
||||
return self._merge_prefix_with_address(
|
||||
prefix=context.prefix,
|
||||
prefix_length=context.prefix_length,
|
||||
address_bytes=dst_mac_addr.convert_to_iid(),
|
||||
)
|
||||
|
||||
def _decompress_unicast_dst_addr(self, iphc, dst_mac_addr, dci, data):
|
||||
if iphc.dac == self.IPHC_DAC_STATELESS:
|
||||
return self._decompress_unicast_dst_addr_stateless(iphc, dst_mac_addr, data)
|
||||
return self._decompress_unicast_dst_addr_stateless(
|
||||
iphc, dst_mac_addr, data
|
||||
)
|
||||
|
||||
elif iphc.dac == self.IPHC_DAC_STATEFUL:
|
||||
return self._decompress_unicast_dst_addr_stateful(iphc, dst_mac_addr, dci, data)
|
||||
return self._decompress_unicast_dst_addr_stateful(
|
||||
iphc, dst_mac_addr, dci, data
|
||||
)
|
||||
|
||||
def _decompress_multicast_dst_addr_stateless(self, iphc, data):
|
||||
if iphc.dam == self.IPHC_DAM_128B:
|
||||
@@ -681,14 +739,24 @@ class LowpanIpv6HeaderFactory:
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_48B:
|
||||
addr48b = bytearray(data.read(6))
|
||||
return bytearray([0xff, addr48b[0]]) + bytearray([0x00] * 9) + addr48b[1:]
|
||||
return (
|
||||
bytearray([0xff, addr48b[0]])
|
||||
+ bytearray([0x00] * 9)
|
||||
+ addr48b[1:]
|
||||
)
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_32B:
|
||||
addr32b = bytearray(data.read(4))
|
||||
return bytearray([0xFF, addr32b[0]]) + bytearray([0x00] * 11) + addr32b[1:]
|
||||
return (
|
||||
bytearray([0xff, addr32b[0]])
|
||||
+ bytearray([0x00] * 11)
|
||||
+ addr32b[1:]
|
||||
)
|
||||
|
||||
elif iphc.dam == self.IPHC_DAM_8B:
|
||||
return bytearray([0xFF, 0x02]) + bytearray([0x00] * 13) + data.read(1)
|
||||
return (
|
||||
bytearray([0xff, 0x02]) + bytearray([0x00] * 13) + data.read(1)
|
||||
)
|
||||
|
||||
def _decompress_multicast_dst_addr_stateful(self, iphc, dci, data):
|
||||
if iphc.dam == self.IPHC_M_DAM_00:
|
||||
@@ -706,7 +774,13 @@ class LowpanIpv6HeaderFactory:
|
||||
if missing_bytes > 0:
|
||||
prefix += bytearray([0x00] * missing_bytes)
|
||||
|
||||
return bytearray([0xff]) + addr48b[:2] + bytearray([prefix_length]) + prefix + addr48b[2:]
|
||||
return (
|
||||
bytearray([0xff])
|
||||
+ addr48b[:2]
|
||||
+ bytearray([prefix_length])
|
||||
+ prefix
|
||||
+ addr48b[2:]
|
||||
)
|
||||
|
||||
elif iphc.dam == self.IPHC_M_DAM_01:
|
||||
raise RuntimeError("Reserved")
|
||||
@@ -722,11 +796,15 @@ class LowpanIpv6HeaderFactory:
|
||||
return self._decompress_multicast_dst_addr_stateless(iphc, data)
|
||||
|
||||
elif iphc.dac == self.IPHC_DAC_STATEFUL:
|
||||
return self._decompress_multicast_dst_addr_stateful(iphc, dci, data)
|
||||
return self._decompress_multicast_dst_addr_stateful(
|
||||
iphc, dci, data
|
||||
)
|
||||
|
||||
def _decompress_dst_addr(self, iphc, dst_mac_addr, dci, data):
|
||||
if iphc.m == self.IPHC_M_NO:
|
||||
return self._decompress_unicast_dst_addr(iphc, dst_mac_addr, dci, data)
|
||||
return self._decompress_unicast_dst_addr(
|
||||
iphc, dst_mac_addr, dci, data
|
||||
)
|
||||
|
||||
elif iphc.m == self.IPHC_M_YES:
|
||||
return self._decompress_multicast_dst_addr(iphc, dci, data)
|
||||
@@ -745,11 +823,17 @@ class LowpanIpv6HeaderFactory:
|
||||
|
||||
hop_limit = self._decompress_hlim(iphc, data)
|
||||
|
||||
src_address = self._decompress_src_addr(iphc, message_info.source_mac_address, sci, data)
|
||||
src_address = self._decompress_src_addr(
|
||||
iphc, message_info.source_mac_address, sci, data
|
||||
)
|
||||
|
||||
dst_address = self._decompress_dst_addr(iphc, message_info.destination_mac_address, dci, data)
|
||||
dst_address = self._decompress_dst_addr(
|
||||
iphc, message_info.destination_mac_address, dci, data
|
||||
)
|
||||
|
||||
header = ipv6.IPv6Header(src_address, dst_address, traffic_class, flow_label, hop_limit)
|
||||
header = ipv6.IPv6Header(
|
||||
src_address, dst_address, traffic_class, flow_label, hop_limit
|
||||
)
|
||||
|
||||
header.next_header = next_header
|
||||
|
||||
@@ -760,16 +844,23 @@ class LowpanDecompressor:
|
||||
|
||||
""" Class decompressing 6LoWPAN packets. """
|
||||
|
||||
def __init__(self, lowpan_ip_header_factory, lowpan_extension_headers_factory, lowpan_udp_header_factory):
|
||||
def __init__(
|
||||
self,
|
||||
lowpan_ip_header_factory,
|
||||
lowpan_extension_headers_factory,
|
||||
lowpan_udp_header_factory,
|
||||
):
|
||||
self._lowpan_ip_header_factory = lowpan_ip_header_factory
|
||||
self._lowpan_extension_headers_factory = lowpan_extension_headers_factory
|
||||
self._lowpan_extension_headers_factory = (
|
||||
lowpan_extension_headers_factory
|
||||
)
|
||||
self._lowpan_udp_header_factory = lowpan_udp_header_factory
|
||||
|
||||
def _is_ipv6_extension_header(self, header_first_byte):
|
||||
return ((header_first_byte >> 4) & 0x0f) == 0x0e
|
||||
return ((header_first_byte >> 4) & 0x0F) == 0x0E
|
||||
|
||||
def _is_udp_header(self, header_first_byte):
|
||||
return ((header_first_byte >> 4) & 0x0f) == 0x0f
|
||||
return ((header_first_byte >> 4) & 0x0F) == 0x0F
|
||||
|
||||
def _peek_n_bytes(self, data, n):
|
||||
read_data = data.read(n)
|
||||
@@ -777,7 +868,7 @@ class LowpanDecompressor:
|
||||
return read_data
|
||||
|
||||
def _is_next_header_compressed(self, header):
|
||||
return (header.next_header is None)
|
||||
return header.next_header is None
|
||||
|
||||
def set_lowpan_context(self, cid, prefix):
|
||||
self._lowpan_ip_header_factory.set_lowpan_context(cid, prefix)
|
||||
@@ -796,7 +887,8 @@ class LowpanDecompressor:
|
||||
header_first_byte = ord(self._peek_n_bytes(data, 1))
|
||||
|
||||
if self._is_ipv6_extension_header(header_first_byte):
|
||||
extension_header = self._lowpan_extension_headers_factory.parse(data, message_info)
|
||||
extension_header = self._lowpan_extension_headers_factory.parse(
|
||||
data, message_info)
|
||||
extension_headers.append(extension_header)
|
||||
|
||||
# Update next header field in the previous header
|
||||
@@ -808,7 +900,9 @@ class LowpanDecompressor:
|
||||
break
|
||||
|
||||
elif self._is_udp_header(header_first_byte):
|
||||
udp_header = self._lowpan_udp_header_factory.parse(data, message_info)
|
||||
udp_header = self._lowpan_udp_header_factory.parse(
|
||||
data, message_info
|
||||
)
|
||||
|
||||
# Update next header field in the previous header
|
||||
previous_header.next_header = udp_header.type
|
||||
@@ -823,7 +917,9 @@ class LowpanMeshHeader(object):
|
||||
|
||||
""" Class representing 6LoWPAN mesh header (RFC 4944 5.2). """
|
||||
|
||||
def __init__(self, hops_left, originator_address, final_destination_address):
|
||||
def __init__(
|
||||
self, hops_left, originator_address, final_destination_address
|
||||
):
|
||||
self._hops_left = hops_left
|
||||
self._originator_address = originator_address
|
||||
self._final_destination_address = final_destination_address
|
||||
@@ -842,7 +938,6 @@ class LowpanMeshHeader(object):
|
||||
|
||||
|
||||
class LowpanMeshHeaderFactory:
|
||||
|
||||
def _parse_address(self, data, is_short):
|
||||
if is_short:
|
||||
return common.MacAddress.from_rloc16(bytearray(data.read(2)))
|
||||
@@ -855,19 +950,24 @@ class LowpanMeshHeaderFactory:
|
||||
is_short_originator_address = bool(data_byte & 0x20)
|
||||
is_short_final_destination_address = bool(data_byte & 0x10)
|
||||
|
||||
if (data_byte & 0x0f) != 0x0f:
|
||||
hops_left = (data_byte & 0x0f)
|
||||
if (data_byte & 0x0F) != 0x0F:
|
||||
hops_left = data_byte & 0x0F
|
||||
else:
|
||||
hops_left = ord(data.read(1))
|
||||
|
||||
originator_address = self._parse_address(data, is_short_originator_address)
|
||||
final_destination_address = self._parse_address(data, is_short_final_destination_address)
|
||||
originator_address = self._parse_address(
|
||||
data, is_short_originator_address
|
||||
)
|
||||
final_destination_address = self._parse_address(
|
||||
data, is_short_final_destination_address
|
||||
)
|
||||
|
||||
return LowpanMeshHeader(hops_left, originator_address, final_destination_address)
|
||||
return LowpanMeshHeader(
|
||||
hops_left, originator_address, final_destination_address
|
||||
)
|
||||
|
||||
|
||||
class LowpanFragmentationHeader(object):
|
||||
|
||||
def __init__(self, datagram_size, datagram_tag, datagram_offset=0):
|
||||
self._datagram_size = datagram_size
|
||||
self._datagram_tag = datagram_tag
|
||||
@@ -892,9 +992,9 @@ class LowpanFragmentationHeader(object):
|
||||
@classmethod
|
||||
def from_bytes(cls, data):
|
||||
datagram_size = struct.unpack(">H", data.read(2))[0]
|
||||
has_offset = ((datagram_size >> 11) & 0x1f) == 0x1c
|
||||
has_offset = ((datagram_size >> 11) & 0x1F) == 0x1C
|
||||
|
||||
datagram_size &= 0x7ff
|
||||
datagram_size &= 0x7FF
|
||||
datagram_tag = struct.unpack(">H", data.read(2))[0]
|
||||
datagram_offset = 0
|
||||
|
||||
@@ -905,14 +1005,15 @@ class LowpanFragmentationHeader(object):
|
||||
|
||||
|
||||
class LowpanFragmentsBuffer(object):
|
||||
|
||||
def __init__(self, buffer_size):
|
||||
self._buffer = [None] * buffer_size
|
||||
self._position = 0
|
||||
|
||||
def write(self, data):
|
||||
if (self._position + len(data)) > len(self._buffer):
|
||||
raise ValueError("Write failure. Data length is bigger than the destination buffer length.")
|
||||
raise ValueError(
|
||||
"Write failure. Data length is bigger than the destination buffer length."
|
||||
)
|
||||
|
||||
for i, byte in enumerate(data):
|
||||
self._buffer[self._position + i] = byte
|
||||
@@ -922,7 +1023,9 @@ class LowpanFragmentsBuffer(object):
|
||||
|
||||
def seek(self, offset):
|
||||
if offset >= len(self._buffer):
|
||||
raise ValueError("Could not seek current offset. Offset value is bigger than the buffer length.")
|
||||
raise ValueError(
|
||||
"Could not seek current offset. Offset value is bigger than the buffer length."
|
||||
)
|
||||
|
||||
self._position = offset
|
||||
|
||||
@@ -934,7 +1037,9 @@ class LowpanFragmentsBuffer(object):
|
||||
|
||||
def read(self):
|
||||
if not self.whole_packet_received():
|
||||
raise ValueError("Only a part of the packet has been stored in the buffer.")
|
||||
raise ValueError(
|
||||
"Only a part of the packet has been stored in the buffer."
|
||||
)
|
||||
|
||||
return bytearray(self._buffer)
|
||||
|
||||
@@ -943,29 +1048,36 @@ class LowpanFragmentsBuffer(object):
|
||||
|
||||
|
||||
class LowpanFragmentsBuffersManager(object):
|
||||
|
||||
def __init__(self):
|
||||
self._fragments_buffers = {}
|
||||
|
||||
def _create_key(self, message_info, datagram_tag):
|
||||
key = bytes(message_info.source_mac_address.mac_address) +\
|
||||
bytes(message_info.destination_mac_address.mac_address) +\
|
||||
bytes(datagram_tag)
|
||||
key = (
|
||||
bytes(message_info.source_mac_address.mac_address)
|
||||
+ bytes(message_info.destination_mac_address.mac_address)
|
||||
+ bytes(datagram_tag)
|
||||
)
|
||||
return key
|
||||
|
||||
def _allocate_fragments_buffer(self, key, datagram_size):
|
||||
if datagram_size is None or datagram_size < 0:
|
||||
raise ValueError("Could not allocate fragments buffer. Invalid datagram size: {}".format(datagram_size))
|
||||
raise ValueError(
|
||||
"Could not allocate fragments buffer. Invalid datagram size: {}".format(
|
||||
datagram_size
|
||||
)
|
||||
)
|
||||
|
||||
fragments_buffer = LowpanFragmentsBuffer(datagram_size)
|
||||
|
||||
self._fragments_buffers[key] = fragments_buffer
|
||||
return fragments_buffer
|
||||
|
||||
def get_fragments_buffer(self, message_info, datagram_tag, datagram_size=None):
|
||||
def get_fragments_buffer(
|
||||
self, message_info, datagram_tag, datagram_size=None
|
||||
):
|
||||
key = self._create_key(message_info, datagram_tag)
|
||||
|
||||
if not key in self._fragments_buffers:
|
||||
if key not in self._fragments_buffers:
|
||||
self._allocate_fragments_buffer(key, datagram_size)
|
||||
|
||||
return self._fragments_buffers[key]
|
||||
@@ -977,11 +1089,18 @@ class LowpanFragmentsBuffersManager(object):
|
||||
|
||||
|
||||
class LowpanParser(object):
|
||||
|
||||
def __init__(self, lowpan_mesh_header_factory, lowpan_decompressor, lowpan_fragements_buffers_manager, ipv6_packet_factory):
|
||||
def __init__(
|
||||
self,
|
||||
lowpan_mesh_header_factory,
|
||||
lowpan_decompressor,
|
||||
lowpan_fragements_buffers_manager,
|
||||
ipv6_packet_factory,
|
||||
):
|
||||
self._lowpan_mesh_header_factory = lowpan_mesh_header_factory
|
||||
self._lowpan_decompressor = lowpan_decompressor
|
||||
self._lowpan_fragments_buffers_manager = lowpan_fragements_buffers_manager
|
||||
self._lowpan_fragments_buffers_manager = (
|
||||
lowpan_fragements_buffers_manager
|
||||
)
|
||||
self._ipv6_packet_factory = ipv6_packet_factory
|
||||
|
||||
def _peek_n_bytes(self, data, n):
|
||||
@@ -990,16 +1109,16 @@ class LowpanParser(object):
|
||||
return data_bytes
|
||||
|
||||
def _is_mesh_header(self, first_byte):
|
||||
return (((first_byte >> 6) & 0x03) == 0x02)
|
||||
return ((first_byte >> 6) & 0x03) == 0x02
|
||||
|
||||
def _is_first_fragmentation_header(self, first_byte):
|
||||
return (((first_byte >> 3) & 0x1f) == 0x18)
|
||||
return ((first_byte >> 3) & 0x1F) == 0x18
|
||||
|
||||
def _is_subsequent_fragmentation_header(self, first_byte):
|
||||
return (((first_byte >> 3) & 0x1f) == 0x1c)
|
||||
return ((first_byte >> 3) & 0x1F) == 0x1C
|
||||
|
||||
def _is_iphc(self, first_byte):
|
||||
return (((first_byte >> 5) & 0x07) == 0x03)
|
||||
return ((first_byte >> 5) & 0x07) == 0x03
|
||||
|
||||
def _decompress_iphc(self, data, message_info):
|
||||
return self._lowpan_decompressor.decompress(data, message_info)
|
||||
@@ -1008,14 +1127,21 @@ class LowpanParser(object):
|
||||
fragmentation_header = LowpanFragmentationHeader.from_bytes(data)
|
||||
|
||||
fragments_buffer = self._lowpan_fragments_buffers_manager.get_fragments_buffer(
|
||||
message_info, fragmentation_header.datagram_tag, fragmentation_header.datagram_size)
|
||||
message_info,
|
||||
fragmentation_header.datagram_tag,
|
||||
fragmentation_header.datagram_size,
|
||||
)
|
||||
|
||||
ipv6_header, extension_headers, udp_header = self._decompress_iphc(data, message_info)
|
||||
ipv6_header, extension_headers, udp_header = self._decompress_iphc(
|
||||
data, message_info
|
||||
)
|
||||
|
||||
uncompressed_data = data.read()
|
||||
|
||||
# Update payload lengths
|
||||
ipv6_header.payload_length = fragmentation_header.datagram_size - len(ipv6_header)
|
||||
ipv6_header.payload_length = fragmentation_header.datagram_size - len(
|
||||
ipv6_header
|
||||
)
|
||||
|
||||
fragments_buffer.seek(0)
|
||||
fragments_buffer.write(ipv6_header.to_bytes())
|
||||
@@ -1031,8 +1157,9 @@ class LowpanParser(object):
|
||||
if fragments_buffer.whole_packet_received():
|
||||
data = io.BytesIO(fragments_buffer.read())
|
||||
|
||||
self._lowpan_fragments_buffers_manager.free_fragments_buffer(message_info,
|
||||
fragmentation_header.datagram_tag)
|
||||
self._lowpan_fragments_buffers_manager.free_fragments_buffer(
|
||||
message_info, fragmentation_header.datagram_tag
|
||||
)
|
||||
|
||||
return self._ipv6_packet_factory.parse(data, message_info)
|
||||
|
||||
@@ -1042,9 +1169,12 @@ class LowpanParser(object):
|
||||
fragmentation_header = LowpanFragmentationHeader.from_bytes(data)
|
||||
|
||||
fragments_buffer = self._lowpan_fragments_buffers_manager.get_fragments_buffer(
|
||||
message_info, fragmentation_header.datagram_tag, fragmentation_header.datagram_size)
|
||||
message_info,
|
||||
fragmentation_header.datagram_tag,
|
||||
fragmentation_header.datagram_size,
|
||||
)
|
||||
|
||||
offset = (fragmentation_header.datagram_offset * 8)
|
||||
offset = fragmentation_header.datagram_offset * 8
|
||||
|
||||
fragments_buffer.seek(offset)
|
||||
fragments_buffer.write(data.read())
|
||||
@@ -1052,15 +1182,18 @@ class LowpanParser(object):
|
||||
if fragments_buffer.whole_packet_received():
|
||||
data = io.BytesIO(fragments_buffer.read())
|
||||
|
||||
self._lowpan_fragments_buffers_manager.free_fragments_buffer(message_info,
|
||||
fragmentation_header.datagram_tag)
|
||||
self._lowpan_fragments_buffers_manager.free_fragments_buffer(
|
||||
message_info, fragmentation_header.datagram_tag
|
||||
)
|
||||
|
||||
return self._ipv6_packet_factory.parse(data, message_info)
|
||||
|
||||
return None
|
||||
|
||||
def _handle_iphc_header(self, data, message_info):
|
||||
ipv6_header, extension_headers, udp_header = self._decompress_iphc(data, message_info)
|
||||
ipv6_header, extension_headers, udp_header = self._decompress_iphc(
|
||||
data, message_info
|
||||
)
|
||||
|
||||
uncompressed_data = data.read()
|
||||
|
||||
@@ -1080,7 +1213,9 @@ class LowpanParser(object):
|
||||
|
||||
decompressed_data = ipv6_header.to_bytes() + decompressed_data
|
||||
|
||||
return self._ipv6_packet_factory.parse(io.BytesIO(decompressed_data), message_info)
|
||||
return self._ipv6_packet_factory.parse(
|
||||
io.BytesIO(decompressed_data), message_info
|
||||
)
|
||||
|
||||
def set_lowpan_context(self, cid, prefix):
|
||||
self._lowpan_decompressor.set_lowpan_context(cid, prefix)
|
||||
@@ -1091,20 +1226,31 @@ class LowpanParser(object):
|
||||
first_byte = ord(self._peek_n_bytes(data, n=1))
|
||||
|
||||
if self._is_mesh_header(first_byte):
|
||||
mesh_header = self._lowpan_mesh_header_factory.parse(data, message_info)
|
||||
mesh_header = self._lowpan_mesh_header_factory.parse(
|
||||
data, message_info
|
||||
)
|
||||
|
||||
message_info.source_mac_address = mesh_header.originator_address
|
||||
message_info.destination_mac_address = mesh_header.final_destination_address
|
||||
message_info.source_mac_address = (
|
||||
mesh_header.originator_address
|
||||
)
|
||||
message_info.destination_mac_address = (
|
||||
mesh_header.final_destination_address
|
||||
)
|
||||
|
||||
elif self._is_first_fragmentation_header(first_byte):
|
||||
return self._handle_first_fragmentation_header(data, message_info)
|
||||
return self._handle_first_fragmentation_header(
|
||||
data, message_info
|
||||
)
|
||||
|
||||
elif self._is_subsequent_fragmentation_header(first_byte):
|
||||
return self._handle_subsequent_fragmentation_header(data, message_info)
|
||||
return self._handle_subsequent_fragmentation_header(
|
||||
data, message_info
|
||||
)
|
||||
|
||||
elif self._is_iphc(first_byte):
|
||||
return self._handle_iphc_header(data, message_info)
|
||||
|
||||
else:
|
||||
raise RuntimeError("Unsupported header type: 0x{:02x}".format(first_byte))
|
||||
|
||||
raise RuntimeError(
|
||||
"Unsupported header type: 0x{:02x}".format(first_byte)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user