Add CoAP support to thread-cert. (#1063)

This commit is contained in:
Przemysław Fierek
2016-12-12 10:10:52 -08:00
committed by Jonathan Hui
parent b38faa8fa0
commit bc8b1a4cd1
30 changed files with 2476 additions and 231 deletions
+45 -21
View File
@@ -53,6 +53,7 @@ UPPER_LAYER_PROTOCOLS = [
]
# ICMP Protocol codes
ICMP_DESTINATION_UNREACHABLE = 0
ICMP_ECHO_REQUEST = 128
ICMP_ECHO_RESPONSE = 129
@@ -92,11 +93,12 @@ class PacketFactory(object):
""" Interface for classes that produce objects from data. """
def parse(self, data):
def parse(self, data, message_info):
""" Convert data to object.
Args:
data (bytes)
data (BytesIO)
message_info (MessageInfo)
"""
raise NotImplementedError
@@ -442,7 +444,7 @@ class IPv6Packet(ConvertibleToBytes):
return ipv6_packet
def __repr__(self):
return "IPv6Packet(\n\theader={})".format(self.ipv6_header)
return "IPv6Packet(header={}, upper_layer_protocol={})".format(self.ipv6_header, self.upper_layer_protocol)
class UDPHeader(ConvertibleToBytes, BuildableFromBytes):
@@ -953,34 +955,56 @@ class UDPHeaderFactory:
return UDPHeader.from_bytes(data)
class UdpBasedOnSrcDstPortsPayloadFactory:
# TODO: Unittests
""" Factory that produces UDP payload. """
def __init__(self, src_dst_port_based_payload_factories):
"""
Args:
src_dst_port_based_payload_factories (PacketFactory): Factories parse UDP payload based on source or destination port.
"""
self._factories = src_dst_port_based_payload_factories
def parse(self, data, message_info):
factory = None
if message_info.dst_port in self._factories:
factory = self._factories[message_info.dst_port]
if message_info.src_port in self._factories:
factory = self._factories[message_info.src_port]
if factory is None:
raise RuntimeError("Could not find factory to build UDP payload.")
return factory.parse(data, message_info)
class UDPDatagramFactory(PacketFactory):
# TODO: Unittests
""" Factory that produces UDP datagrams. """
def __init__(self, udp_header_factory, dst_port_factories=None):
"""
Args:
dst_port_factories (PacketFactory): Factories parse UDP payload based on destination port.
"""
def __init__(self, udp_header_factory, udp_payload_factory):
self._udp_header_factory = udp_header_factory
self._dst_port_factories = dst_port_factories if dst_port_factories is not None else {}
def _get_payload_factory(self, dst_port):
try:
return self._dst_port_factories[dst_port]
except KeyError:
raise RuntimeError(
"Could not find factory to parse UDP datagram payload based on destination port: {}".format(dst_port))
self._udp_payload_factory = udp_payload_factory
def parse(self, data, message_info):
udp_header = self._udp_header_factory.parse(data, message_info)
header = self._udp_header_factory.parse(data, message_info)
factory = self._get_payload_factory(udp_header.dst_port)
# Update message payload length: UDP header (8B) + payload length
message_info.payload_length += len(header) + (len(data.getvalue()) - data.tell())
message_info.payload_length += len(udp_header) + (len(data.getvalue()) - data.tell())
message_info.src_port = header.src_port
message_info.dst_port = header.dst_port
return UDPDatagram(udp_header, factory.parse(data, message_info))
payload = self._udp_payload_factory.parse(data, message_info)
return UDPDatagram(header, payload)
class ICMPv6Factory(PacketFactory):