1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*cfb92d14SAndroid Build Coastguard Worker# 3*cfb92d14SAndroid Build Coastguard Worker# Copyright (c) 2016, The OpenThread Authors. 4*cfb92d14SAndroid Build Coastguard Worker# All rights reserved. 5*cfb92d14SAndroid Build Coastguard Worker# 6*cfb92d14SAndroid Build Coastguard Worker# Redistribution and use in source and binary forms, with or without 7*cfb92d14SAndroid Build Coastguard Worker# modification, are permitted provided that the following conditions are met: 8*cfb92d14SAndroid Build Coastguard Worker# 1. Redistributions of source code must retain the above copyright 9*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer. 10*cfb92d14SAndroid Build Coastguard Worker# 2. Redistributions in binary form must reproduce the above copyright 11*cfb92d14SAndroid Build Coastguard Worker# notice, this list of conditions and the following disclaimer in the 12*cfb92d14SAndroid Build Coastguard Worker# documentation and/or other materials provided with the distribution. 13*cfb92d14SAndroid Build Coastguard Worker# 3. Neither the name of the copyright holder nor the 14*cfb92d14SAndroid Build Coastguard Worker# names of its contributors may be used to endorse or promote products 15*cfb92d14SAndroid Build Coastguard Worker# derived from this software without specific prior written permission. 16*cfb92d14SAndroid Build Coastguard Worker# 17*cfb92d14SAndroid Build Coastguard Worker# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18*cfb92d14SAndroid Build Coastguard Worker# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*cfb92d14SAndroid Build Coastguard Worker# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*cfb92d14SAndroid Build Coastguard Worker# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21*cfb92d14SAndroid Build Coastguard Worker# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22*cfb92d14SAndroid Build Coastguard Worker# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23*cfb92d14SAndroid Build Coastguard Worker# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24*cfb92d14SAndroid Build Coastguard Worker# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25*cfb92d14SAndroid Build Coastguard Worker# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26*cfb92d14SAndroid Build Coastguard Worker# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27*cfb92d14SAndroid Build Coastguard Worker# POSSIBILITY OF SUCH DAMAGE. 28*cfb92d14SAndroid Build Coastguard Worker# 29*cfb92d14SAndroid Build Coastguard Worker 30*cfb92d14SAndroid Build Coastguard Workerimport io 31*cfb92d14SAndroid Build Coastguard Workerimport ipaddress 32*cfb92d14SAndroid Build Coastguard Workerimport struct 33*cfb92d14SAndroid Build Coastguard Worker 34*cfb92d14SAndroid Build Coastguard Workerimport coap 35*cfb92d14SAndroid Build Coastguard Workerimport common 36*cfb92d14SAndroid Build Coastguard Workerimport dtls 37*cfb92d14SAndroid Build Coastguard Workerimport ipv6 38*cfb92d14SAndroid Build Coastguard Workerimport mac802154 39*cfb92d14SAndroid Build Coastguard Workerimport mle 40*cfb92d14SAndroid Build Coastguard Worker 41*cfb92d14SAndroid Build Coastguard Workerfrom enum import IntEnum 42*cfb92d14SAndroid Build Coastguard Worker 43*cfb92d14SAndroid Build Coastguard Worker 44*cfb92d14SAndroid Build Coastguard Workerclass DropPacketException(Exception): 45*cfb92d14SAndroid Build Coastguard Worker pass 46*cfb92d14SAndroid Build Coastguard Worker 47*cfb92d14SAndroid Build Coastguard Worker 48*cfb92d14SAndroid Build Coastguard Workerclass MessageType(IntEnum): 49*cfb92d14SAndroid Build Coastguard Worker MLE = 0 50*cfb92d14SAndroid Build Coastguard Worker COAP = 1 51*cfb92d14SAndroid Build Coastguard Worker ICMP = 2 52*cfb92d14SAndroid Build Coastguard Worker ACK = 3 53*cfb92d14SAndroid Build Coastguard Worker BEACON = 4 54*cfb92d14SAndroid Build Coastguard Worker DATA = 5 55*cfb92d14SAndroid Build Coastguard Worker COMMAND = 6 56*cfb92d14SAndroid Build Coastguard Worker DTLS = 7 57*cfb92d14SAndroid Build Coastguard Worker 58*cfb92d14SAndroid Build Coastguard Worker 59*cfb92d14SAndroid Build Coastguard Workerclass Message(object): 60*cfb92d14SAndroid Build Coastguard Worker 61*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 62*cfb92d14SAndroid Build Coastguard Worker self._type = None 63*cfb92d14SAndroid Build Coastguard Worker self._channel = None 64*cfb92d14SAndroid Build Coastguard Worker self._mac_header = None 65*cfb92d14SAndroid Build Coastguard Worker self._ipv6_packet = None 66*cfb92d14SAndroid Build Coastguard Worker self._coap = None 67*cfb92d14SAndroid Build Coastguard Worker self._mle = None 68*cfb92d14SAndroid Build Coastguard Worker self._icmp = None 69*cfb92d14SAndroid Build Coastguard Worker self._dtls = None 70*cfb92d14SAndroid Build Coastguard Worker 71*cfb92d14SAndroid Build Coastguard Worker def _extract_udp_datagram(self, udp_datagram): 72*cfb92d14SAndroid Build Coastguard Worker if isinstance(udp_datagram.payload, mle.MleMessage): 73*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.MLE 74*cfb92d14SAndroid Build Coastguard Worker self._mle = udp_datagram.payload 75*cfb92d14SAndroid Build Coastguard Worker 76*cfb92d14SAndroid Build Coastguard Worker elif isinstance(udp_datagram.payload, (coap.CoapMessage, coap.CoapMessageProxy)): 77*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.COAP 78*cfb92d14SAndroid Build Coastguard Worker self._coap = udp_datagram.payload 79*cfb92d14SAndroid Build Coastguard Worker 80*cfb92d14SAndroid Build Coastguard Worker # DTLS message factory returns a list of messages 81*cfb92d14SAndroid Build Coastguard Worker elif isinstance(udp_datagram.payload, list): 82*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.DTLS 83*cfb92d14SAndroid Build Coastguard Worker self._dtls = udp_datagram.payload 84*cfb92d14SAndroid Build Coastguard Worker 85*cfb92d14SAndroid Build Coastguard Worker def _extract_upper_layer_protocol(self, upper_layer_protocol): 86*cfb92d14SAndroid Build Coastguard Worker if isinstance(upper_layer_protocol, ipv6.ICMPv6): 87*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.ICMP 88*cfb92d14SAndroid Build Coastguard Worker self._icmp = upper_layer_protocol 89*cfb92d14SAndroid Build Coastguard Worker 90*cfb92d14SAndroid Build Coastguard Worker elif isinstance(upper_layer_protocol, ipv6.UDPDatagram): 91*cfb92d14SAndroid Build Coastguard Worker self._extract_udp_datagram(upper_layer_protocol) 92*cfb92d14SAndroid Build Coastguard Worker 93*cfb92d14SAndroid Build Coastguard Worker def try_extract_dtls_messages(self): 94*cfb92d14SAndroid Build Coastguard Worker """Extract multiple dtls messages that are sent in a single UDP datagram 95*cfb92d14SAndroid Build Coastguard Worker """ 96*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.DTLS: 97*cfb92d14SAndroid Build Coastguard Worker return [self.clone()] 98*cfb92d14SAndroid Build Coastguard Worker 99*cfb92d14SAndroid Build Coastguard Worker assert isinstance(self.dtls, list) 100*cfb92d14SAndroid Build Coastguard Worker ret = [] 101*cfb92d14SAndroid Build Coastguard Worker for dtls in self.dtls: 102*cfb92d14SAndroid Build Coastguard Worker msg = self.clone() 103*cfb92d14SAndroid Build Coastguard Worker msg._dtls = dtls 104*cfb92d14SAndroid Build Coastguard Worker ret.append(msg) 105*cfb92d14SAndroid Build Coastguard Worker return ret 106*cfb92d14SAndroid Build Coastguard Worker 107*cfb92d14SAndroid Build Coastguard Worker def clone(self): 108*cfb92d14SAndroid Build Coastguard Worker msg = Message() 109*cfb92d14SAndroid Build Coastguard Worker msg._type = self.type 110*cfb92d14SAndroid Build Coastguard Worker msg._channel = self.channel 111*cfb92d14SAndroid Build Coastguard Worker msg._mac_header = self.mac_header 112*cfb92d14SAndroid Build Coastguard Worker msg._ipv6_packet = self.ipv6_packet 113*cfb92d14SAndroid Build Coastguard Worker msg._coap = self.coap 114*cfb92d14SAndroid Build Coastguard Worker msg._mle = self.mle 115*cfb92d14SAndroid Build Coastguard Worker msg._icmp = self.icmp 116*cfb92d14SAndroid Build Coastguard Worker msg._dtls = self.dtls 117*cfb92d14SAndroid Build Coastguard Worker return msg 118*cfb92d14SAndroid Build Coastguard Worker 119*cfb92d14SAndroid Build Coastguard Worker @property 120*cfb92d14SAndroid Build Coastguard Worker def type(self): 121*cfb92d14SAndroid Build Coastguard Worker return self._type 122*cfb92d14SAndroid Build Coastguard Worker 123*cfb92d14SAndroid Build Coastguard Worker @type.setter 124*cfb92d14SAndroid Build Coastguard Worker def type(self, value): 125*cfb92d14SAndroid Build Coastguard Worker self._type = value 126*cfb92d14SAndroid Build Coastguard Worker 127*cfb92d14SAndroid Build Coastguard Worker @property 128*cfb92d14SAndroid Build Coastguard Worker def channel(self): 129*cfb92d14SAndroid Build Coastguard Worker return self._channel 130*cfb92d14SAndroid Build Coastguard Worker 131*cfb92d14SAndroid Build Coastguard Worker @channel.setter 132*cfb92d14SAndroid Build Coastguard Worker def channel(self, value): 133*cfb92d14SAndroid Build Coastguard Worker self._channel = value 134*cfb92d14SAndroid Build Coastguard Worker 135*cfb92d14SAndroid Build Coastguard Worker @property 136*cfb92d14SAndroid Build Coastguard Worker def mac_header(self): 137*cfb92d14SAndroid Build Coastguard Worker return self._mac_header 138*cfb92d14SAndroid Build Coastguard Worker 139*cfb92d14SAndroid Build Coastguard Worker @mac_header.setter 140*cfb92d14SAndroid Build Coastguard Worker def mac_header(self, value): 141*cfb92d14SAndroid Build Coastguard Worker self._mac_header = value 142*cfb92d14SAndroid Build Coastguard Worker 143*cfb92d14SAndroid Build Coastguard Worker if self._mac_header.frame_type == mac802154.MacHeader.FrameType.BEACON: 144*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.BEACON 145*cfb92d14SAndroid Build Coastguard Worker 146*cfb92d14SAndroid Build Coastguard Worker elif self._mac_header.frame_type == mac802154.MacHeader.FrameType.ACK: 147*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.ACK 148*cfb92d14SAndroid Build Coastguard Worker 149*cfb92d14SAndroid Build Coastguard Worker elif self._mac_header.frame_type == mac802154.MacHeader.FrameType.DATA: 150*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.DATA 151*cfb92d14SAndroid Build Coastguard Worker elif (self._mac_header.frame_type == mac802154.MacHeader.FrameType.COMMAND): 152*cfb92d14SAndroid Build Coastguard Worker self._type = MessageType.COMMAND 153*cfb92d14SAndroid Build Coastguard Worker else: 154*cfb92d14SAndroid Build Coastguard Worker raise ValueError('Invalid mac frame type %d' % self._mac_header.frame_type) 155*cfb92d14SAndroid Build Coastguard Worker 156*cfb92d14SAndroid Build Coastguard Worker @property 157*cfb92d14SAndroid Build Coastguard Worker def ipv6_packet(self): 158*cfb92d14SAndroid Build Coastguard Worker return self._ipv6_packet 159*cfb92d14SAndroid Build Coastguard Worker 160*cfb92d14SAndroid Build Coastguard Worker @ipv6_packet.setter 161*cfb92d14SAndroid Build Coastguard Worker def ipv6_packet(self, value): 162*cfb92d14SAndroid Build Coastguard Worker self._ipv6_packet = value 163*cfb92d14SAndroid Build Coastguard Worker self._extract_upper_layer_protocol(value.upper_layer_protocol) 164*cfb92d14SAndroid Build Coastguard Worker 165*cfb92d14SAndroid Build Coastguard Worker @property 166*cfb92d14SAndroid Build Coastguard Worker def coap(self): 167*cfb92d14SAndroid Build Coastguard Worker return self._coap 168*cfb92d14SAndroid Build Coastguard Worker 169*cfb92d14SAndroid Build Coastguard Worker @property 170*cfb92d14SAndroid Build Coastguard Worker def mle(self): 171*cfb92d14SAndroid Build Coastguard Worker return self._mle 172*cfb92d14SAndroid Build Coastguard Worker 173*cfb92d14SAndroid Build Coastguard Worker @property 174*cfb92d14SAndroid Build Coastguard Worker def icmp(self): 175*cfb92d14SAndroid Build Coastguard Worker return self._icmp 176*cfb92d14SAndroid Build Coastguard Worker 177*cfb92d14SAndroid Build Coastguard Worker @icmp.setter 178*cfb92d14SAndroid Build Coastguard Worker def icmp(self, value): 179*cfb92d14SAndroid Build Coastguard Worker self._icmp = value 180*cfb92d14SAndroid Build Coastguard Worker 181*cfb92d14SAndroid Build Coastguard Worker @property 182*cfb92d14SAndroid Build Coastguard Worker def dtls(self): 183*cfb92d14SAndroid Build Coastguard Worker return self._dtls 184*cfb92d14SAndroid Build Coastguard Worker 185*cfb92d14SAndroid Build Coastguard Worker def get_mle_message_tlv(self, tlv_class_type): 186*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.MLE: 187*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected MLE message.") 188*cfb92d14SAndroid Build Coastguard Worker 189*cfb92d14SAndroid Build Coastguard Worker for tlv in self.mle.command.tlvs: 190*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 191*cfb92d14SAndroid Build Coastguard Worker return tlv 192*cfb92d14SAndroid Build Coastguard Worker 193*cfb92d14SAndroid Build Coastguard Worker def assertMleMessageIsType(self, command_type): 194*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.MLE: 195*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected MLE message.") 196*cfb92d14SAndroid Build Coastguard Worker 197*cfb92d14SAndroid Build Coastguard Worker assert self.mle.command.type == command_type 198*cfb92d14SAndroid Build Coastguard Worker 199*cfb92d14SAndroid Build Coastguard Worker def assertMleMessageContainsTlv(self, tlv_class_type): 200*cfb92d14SAndroid Build Coastguard Worker """To confirm if Mle message contains the TLV type. 201*cfb92d14SAndroid Build Coastguard Worker 202*cfb92d14SAndroid Build Coastguard Worker Args: 203*cfb92d14SAndroid Build Coastguard Worker tlv_class_type: tlv's type. 204*cfb92d14SAndroid Build Coastguard Worker 205*cfb92d14SAndroid Build Coastguard Worker Returns: 206*cfb92d14SAndroid Build Coastguard Worker mle.Route64: If contains the TLV, return it. 207*cfb92d14SAndroid Build Coastguard Worker """ 208*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.MLE: 209*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected MLE message.") 210*cfb92d14SAndroid Build Coastguard Worker 211*cfb92d14SAndroid Build Coastguard Worker contains_tlv = False 212*cfb92d14SAndroid Build Coastguard Worker for tlv in self.mle.command.tlvs: 213*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 214*cfb92d14SAndroid Build Coastguard Worker contains_tlv = True 215*cfb92d14SAndroid Build Coastguard Worker break 216*cfb92d14SAndroid Build Coastguard Worker 217*cfb92d14SAndroid Build Coastguard Worker assert contains_tlv 218*cfb92d14SAndroid Build Coastguard Worker return tlv 219*cfb92d14SAndroid Build Coastguard Worker 220*cfb92d14SAndroid Build Coastguard Worker def assertAssignedRouterQuantity(self, router_quantity): 221*cfb92d14SAndroid Build Coastguard Worker """Confirm if Leader contains the Route64 TLV with router_quantity assigned Router IDs. 222*cfb92d14SAndroid Build Coastguard Worker 223*cfb92d14SAndroid Build Coastguard Worker Args: 224*cfb92d14SAndroid Build Coastguard Worker router_quantity: the quantity of router. 225*cfb92d14SAndroid Build Coastguard Worker """ 226*cfb92d14SAndroid Build Coastguard Worker tlv = self.assertMleMessageContainsTlv(mle.Route64) 227*cfb92d14SAndroid Build Coastguard Worker router_id_mask = tlv.router_id_mask 228*cfb92d14SAndroid Build Coastguard Worker 229*cfb92d14SAndroid Build Coastguard Worker count = 0 230*cfb92d14SAndroid Build Coastguard Worker for i in range(1, 65): 231*cfb92d14SAndroid Build Coastguard Worker count += router_id_mask & 1 232*cfb92d14SAndroid Build Coastguard Worker router_id_mask = router_id_mask >> 1 233*cfb92d14SAndroid Build Coastguard Worker assert count == router_quantity 234*cfb92d14SAndroid Build Coastguard Worker 235*cfb92d14SAndroid Build Coastguard Worker def assertMleMessageDoesNotContainTlv(self, tlv_class_type): 236*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.MLE: 237*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected MLE message.") 238*cfb92d14SAndroid Build Coastguard Worker 239*cfb92d14SAndroid Build Coastguard Worker contains_tlv = False 240*cfb92d14SAndroid Build Coastguard Worker for tlv in self.mle.command.tlvs: 241*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 242*cfb92d14SAndroid Build Coastguard Worker contains_tlv = True 243*cfb92d14SAndroid Build Coastguard Worker break 244*cfb92d14SAndroid Build Coastguard Worker 245*cfb92d14SAndroid Build Coastguard Worker assert contains_tlv is False 246*cfb92d14SAndroid Build Coastguard Worker 247*cfb92d14SAndroid Build Coastguard Worker def assertMleMessageContainsOptionalTlv(self, tlv_class_type): 248*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.MLE: 249*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected MLE message.") 250*cfb92d14SAndroid Build Coastguard Worker 251*cfb92d14SAndroid Build Coastguard Worker contains_tlv = False 252*cfb92d14SAndroid Build Coastguard Worker for tlv in self.mle.command.tlvs: 253*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 254*cfb92d14SAndroid Build Coastguard Worker contains_tlv = True 255*cfb92d14SAndroid Build Coastguard Worker break 256*cfb92d14SAndroid Build Coastguard Worker 257*cfb92d14SAndroid Build Coastguard Worker if contains_tlv: 258*cfb92d14SAndroid Build Coastguard Worker print("MleMessage contains optional TLV: {}".format(tlv_class_type)) 259*cfb92d14SAndroid Build Coastguard Worker else: 260*cfb92d14SAndroid Build Coastguard Worker print("MleMessage doesn't contain optional TLV: {}".format(tlv_class_type)) 261*cfb92d14SAndroid Build Coastguard Worker 262*cfb92d14SAndroid Build Coastguard Worker def get_coap_message_tlv(self, tlv_class_type): 263*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.COAP: 264*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected CoAP message.") 265*cfb92d14SAndroid Build Coastguard Worker 266*cfb92d14SAndroid Build Coastguard Worker for tlv in self.coap.payload: 267*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 268*cfb92d14SAndroid Build Coastguard Worker return tlv 269*cfb92d14SAndroid Build Coastguard Worker 270*cfb92d14SAndroid Build Coastguard Worker def assertCoapMessageContainsTlv(self, tlv_class_type): 271*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.COAP: 272*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected CoAP message.") 273*cfb92d14SAndroid Build Coastguard Worker 274*cfb92d14SAndroid Build Coastguard Worker contains_tlv = False 275*cfb92d14SAndroid Build Coastguard Worker for tlv in self.coap.payload: 276*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 277*cfb92d14SAndroid Build Coastguard Worker contains_tlv = True 278*cfb92d14SAndroid Build Coastguard Worker break 279*cfb92d14SAndroid Build Coastguard Worker 280*cfb92d14SAndroid Build Coastguard Worker assert contains_tlv 281*cfb92d14SAndroid Build Coastguard Worker 282*cfb92d14SAndroid Build Coastguard Worker def assertCoapMessageDoesNotContainTlv(self, tlv_class_type): 283*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.COAP: 284*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected COAP message.") 285*cfb92d14SAndroid Build Coastguard Worker 286*cfb92d14SAndroid Build Coastguard Worker contains_tlv = False 287*cfb92d14SAndroid Build Coastguard Worker for tlv in self.coap.payload: 288*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 289*cfb92d14SAndroid Build Coastguard Worker contains_tlv = True 290*cfb92d14SAndroid Build Coastguard Worker break 291*cfb92d14SAndroid Build Coastguard Worker 292*cfb92d14SAndroid Build Coastguard Worker assert contains_tlv is False 293*cfb92d14SAndroid Build Coastguard Worker 294*cfb92d14SAndroid Build Coastguard Worker def assertCoapMessageContainsOptionalTlv(self, tlv_class_type): 295*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.COAP: 296*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected CoAP message.") 297*cfb92d14SAndroid Build Coastguard Worker 298*cfb92d14SAndroid Build Coastguard Worker for tlv in self.coap.payload: 299*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, tlv_class_type): 300*cfb92d14SAndroid Build Coastguard Worker break 301*cfb92d14SAndroid Build Coastguard Worker 302*cfb92d14SAndroid Build Coastguard Worker print("CoapMessage doesn't contain optional TLV: {}".format(tlv_class_type)) 303*cfb92d14SAndroid Build Coastguard Worker 304*cfb92d14SAndroid Build Coastguard Worker def assertCoapMessageRequestUriPath(self, uri_path): 305*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.COAP: 306*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected CoAP message.") 307*cfb92d14SAndroid Build Coastguard Worker 308*cfb92d14SAndroid Build Coastguard Worker assert uri_path == self.coap.uri_path 309*cfb92d14SAndroid Build Coastguard Worker 310*cfb92d14SAndroid Build Coastguard Worker def assertCoapMessageCode(self, code): 311*cfb92d14SAndroid Build Coastguard Worker if self.type != MessageType.COAP: 312*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Invalid message type. Expected CoAP message.") 313*cfb92d14SAndroid Build Coastguard Worker 314*cfb92d14SAndroid Build Coastguard Worker assert code == self.coap.code 315*cfb92d14SAndroid Build Coastguard Worker 316*cfb92d14SAndroid Build Coastguard Worker def assertSentToNode(self, node): 317*cfb92d14SAndroid Build Coastguard Worker sent_to_node = False 318*cfb92d14SAndroid Build Coastguard Worker dst_addr = self.ipv6_packet.ipv6_header.destination_address 319*cfb92d14SAndroid Build Coastguard Worker 320*cfb92d14SAndroid Build Coastguard Worker for addr in node.get_addrs(): 321*cfb92d14SAndroid Build Coastguard Worker if dst_addr == ipaddress.ip_address(addr): 322*cfb92d14SAndroid Build Coastguard Worker sent_to_node = True 323*cfb92d14SAndroid Build Coastguard Worker 324*cfb92d14SAndroid Build Coastguard Worker if self.mac_header.dest_address.type == common.MacAddressType.SHORT: 325*cfb92d14SAndroid Build Coastguard Worker mac_address = common.MacAddress.from_rloc16(node.get_addr16()) 326*cfb92d14SAndroid Build Coastguard Worker if self.mac_header.dest_address == mac_address: 327*cfb92d14SAndroid Build Coastguard Worker sent_to_node = True 328*cfb92d14SAndroid Build Coastguard Worker 329*cfb92d14SAndroid Build Coastguard Worker elif self.mac_header.dest_address.type == common.MacAddressType.LONG: 330*cfb92d14SAndroid Build Coastguard Worker mac_address = common.MacAddress.from_eui64(bytearray(node.get_addr64(), encoding="utf-8")) 331*cfb92d14SAndroid Build Coastguard Worker if self.mac_header.dest_address == mac_address: 332*cfb92d14SAndroid Build Coastguard Worker sent_to_node = True 333*cfb92d14SAndroid Build Coastguard Worker 334*cfb92d14SAndroid Build Coastguard Worker assert sent_to_node 335*cfb92d14SAndroid Build Coastguard Worker 336*cfb92d14SAndroid Build Coastguard Worker def assertSentToDestinationAddress(self, ipv6_address): 337*cfb92d14SAndroid Build Coastguard Worker assert (self.ipv6_packet.ipv6_header.destination_address == ipaddress.ip_address(ipv6_address)) 338*cfb92d14SAndroid Build Coastguard Worker 339*cfb92d14SAndroid Build Coastguard Worker def assertSentFromSourceAddress(self, ipv6_address): 340*cfb92d14SAndroid Build Coastguard Worker assert (self.ipv6_packet.ipv6_header.source_address == ipaddress.ip_address(ipv6_address)) 341*cfb92d14SAndroid Build Coastguard Worker 342*cfb92d14SAndroid Build Coastguard Worker def assertSentWithHopLimit(self, hop_limit): 343*cfb92d14SAndroid Build Coastguard Worker assert self.ipv6_packet.ipv6_header.hop_limit == hop_limit 344*cfb92d14SAndroid Build Coastguard Worker 345*cfb92d14SAndroid Build Coastguard Worker def isMacAddressTypeLong(self): 346*cfb92d14SAndroid Build Coastguard Worker return self.mac_header.dest_address.type == common.MacAddressType.LONG 347*cfb92d14SAndroid Build Coastguard Worker 348*cfb92d14SAndroid Build Coastguard Worker def get_dst_udp_port(self): 349*cfb92d14SAndroid Build Coastguard Worker assert isinstance(self.ipv6_packet.upper_layer_protocol, ipv6.UDPDatagram) 350*cfb92d14SAndroid Build Coastguard Worker return self.ipv6_packet.upper_layer_protocol.header.dst_port 351*cfb92d14SAndroid Build Coastguard Worker 352*cfb92d14SAndroid Build Coastguard Worker def is_data_poll(self): 353*cfb92d14SAndroid Build Coastguard Worker return self._type == MessageType.COMMAND and \ 354*cfb92d14SAndroid Build Coastguard Worker self._mac_header.command_type == mac802154.MacHeader.CommandIdentifier.DATA_REQUEST 355*cfb92d14SAndroid Build Coastguard Worker 356*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 357*cfb92d14SAndroid Build Coastguard Worker if (self.type == MessageType.DTLS and self.dtls.content_type == dtls.ContentType.HANDSHAKE): 358*cfb92d14SAndroid Build Coastguard Worker return "Message(type={})".format(str(self.dtls.handshake_type)) 359*cfb92d14SAndroid Build Coastguard Worker return "Message(type={})".format(MessageType(self.type).name) 360*cfb92d14SAndroid Build Coastguard Worker 361*cfb92d14SAndroid Build Coastguard Worker 362*cfb92d14SAndroid Build Coastguard Workerclass MessagesSet(object): 363*cfb92d14SAndroid Build Coastguard Worker 364*cfb92d14SAndroid Build Coastguard Worker def __init__(self, messages, commissioning_messages=()): 365*cfb92d14SAndroid Build Coastguard Worker self._messages = messages 366*cfb92d14SAndroid Build Coastguard Worker self._commissioning_messages = commissioning_messages 367*cfb92d14SAndroid Build Coastguard Worker 368*cfb92d14SAndroid Build Coastguard Worker @property 369*cfb92d14SAndroid Build Coastguard Worker def messages(self): 370*cfb92d14SAndroid Build Coastguard Worker return self._messages 371*cfb92d14SAndroid Build Coastguard Worker 372*cfb92d14SAndroid Build Coastguard Worker @property 373*cfb92d14SAndroid Build Coastguard Worker def commissioning_messages(self): 374*cfb92d14SAndroid Build Coastguard Worker return self._commissioning_messages 375*cfb92d14SAndroid Build Coastguard Worker 376*cfb92d14SAndroid Build Coastguard Worker def next_data_poll(self): 377*cfb92d14SAndroid Build Coastguard Worker while True: 378*cfb92d14SAndroid Build Coastguard Worker message = self.next_message_of(MessageType.COMMAND, False) 379*cfb92d14SAndroid Build Coastguard Worker if not message: 380*cfb92d14SAndroid Build Coastguard Worker break 381*cfb92d14SAndroid Build Coastguard Worker elif message.is_data_poll(): 382*cfb92d14SAndroid Build Coastguard Worker return message 383*cfb92d14SAndroid Build Coastguard Worker 384*cfb92d14SAndroid Build Coastguard Worker def next_coap_message(self, code, uri_path=None, assert_enabled=True): 385*cfb92d14SAndroid Build Coastguard Worker message = None 386*cfb92d14SAndroid Build Coastguard Worker 387*cfb92d14SAndroid Build Coastguard Worker while self.messages: 388*cfb92d14SAndroid Build Coastguard Worker m = self.messages.pop(0) 389*cfb92d14SAndroid Build Coastguard Worker 390*cfb92d14SAndroid Build Coastguard Worker if m.type != MessageType.COAP: 391*cfb92d14SAndroid Build Coastguard Worker continue 392*cfb92d14SAndroid Build Coastguard Worker 393*cfb92d14SAndroid Build Coastguard Worker if uri_path is not None and m.coap.uri_path != uri_path: 394*cfb92d14SAndroid Build Coastguard Worker continue 395*cfb92d14SAndroid Build Coastguard Worker 396*cfb92d14SAndroid Build Coastguard Worker else: 397*cfb92d14SAndroid Build Coastguard Worker if not m.coap.code.is_equal_dotted(code): 398*cfb92d14SAndroid Build Coastguard Worker continue 399*cfb92d14SAndroid Build Coastguard Worker 400*cfb92d14SAndroid Build Coastguard Worker message = m 401*cfb92d14SAndroid Build Coastguard Worker break 402*cfb92d14SAndroid Build Coastguard Worker 403*cfb92d14SAndroid Build Coastguard Worker if assert_enabled: 404*cfb92d14SAndroid Build Coastguard Worker assert (message is not None), "Could not find CoapMessage with code: {}".format(code) 405*cfb92d14SAndroid Build Coastguard Worker 406*cfb92d14SAndroid Build Coastguard Worker return message 407*cfb92d14SAndroid Build Coastguard Worker 408*cfb92d14SAndroid Build Coastguard Worker def last_mle_message(self, command_type, assert_enabled=True): 409*cfb92d14SAndroid Build Coastguard Worker """Get the last Mle Message with specified type from existing capture. 410*cfb92d14SAndroid Build Coastguard Worker 411*cfb92d14SAndroid Build Coastguard Worker Args: 412*cfb92d14SAndroid Build Coastguard Worker command_type: the specified mle type. 413*cfb92d14SAndroid Build Coastguard Worker assert_enabled: interrupt or not when get the mle. 414*cfb92d14SAndroid Build Coastguard Worker 415*cfb92d14SAndroid Build Coastguard Worker Returns: 416*cfb92d14SAndroid Build Coastguard Worker message.Message: the last Mle Message with specified type. 417*cfb92d14SAndroid Build Coastguard Worker """ 418*cfb92d14SAndroid Build Coastguard Worker message = None 419*cfb92d14SAndroid Build Coastguard Worker size = len(self.messages) 420*cfb92d14SAndroid Build Coastguard Worker 421*cfb92d14SAndroid Build Coastguard Worker for i in range(size - 1, -1, -1): 422*cfb92d14SAndroid Build Coastguard Worker m = self.messages[i] 423*cfb92d14SAndroid Build Coastguard Worker 424*cfb92d14SAndroid Build Coastguard Worker if m.type != MessageType.MLE: 425*cfb92d14SAndroid Build Coastguard Worker continue 426*cfb92d14SAndroid Build Coastguard Worker 427*cfb92d14SAndroid Build Coastguard Worker # for command_type in command_types: 428*cfb92d14SAndroid Build Coastguard Worker if m.mle.command.type == command_type: 429*cfb92d14SAndroid Build Coastguard Worker message = m 430*cfb92d14SAndroid Build Coastguard Worker break 431*cfb92d14SAndroid Build Coastguard Worker 432*cfb92d14SAndroid Build Coastguard Worker if assert_enabled: 433*cfb92d14SAndroid Build Coastguard Worker assert (message is not None), "Could not find MleMessage with type: {}".format(command_type) 434*cfb92d14SAndroid Build Coastguard Worker 435*cfb92d14SAndroid Build Coastguard Worker return message 436*cfb92d14SAndroid Build Coastguard Worker 437*cfb92d14SAndroid Build Coastguard Worker def next_mle_message(self, command_type, assert_enabled=True, sent_to_node=None): 438*cfb92d14SAndroid Build Coastguard Worker message = self.next_mle_message_of_one_of_command_types(command_type) 439*cfb92d14SAndroid Build Coastguard Worker 440*cfb92d14SAndroid Build Coastguard Worker if assert_enabled: 441*cfb92d14SAndroid Build Coastguard Worker assert (message is not None), "Could not find MleMessage of the type: {}".format(command_type) 442*cfb92d14SAndroid Build Coastguard Worker 443*cfb92d14SAndroid Build Coastguard Worker if sent_to_node is not None: 444*cfb92d14SAndroid Build Coastguard Worker message.assertSentToNode(sent_to_node) 445*cfb92d14SAndroid Build Coastguard Worker 446*cfb92d14SAndroid Build Coastguard Worker return message 447*cfb92d14SAndroid Build Coastguard Worker 448*cfb92d14SAndroid Build Coastguard Worker def next_mle_message_of_one_of_command_types(self, *command_types): 449*cfb92d14SAndroid Build Coastguard Worker message = None 450*cfb92d14SAndroid Build Coastguard Worker 451*cfb92d14SAndroid Build Coastguard Worker while self.messages: 452*cfb92d14SAndroid Build Coastguard Worker m = self.messages.pop(0) 453*cfb92d14SAndroid Build Coastguard Worker 454*cfb92d14SAndroid Build Coastguard Worker if m.type != MessageType.MLE: 455*cfb92d14SAndroid Build Coastguard Worker continue 456*cfb92d14SAndroid Build Coastguard Worker 457*cfb92d14SAndroid Build Coastguard Worker command_found = False 458*cfb92d14SAndroid Build Coastguard Worker 459*cfb92d14SAndroid Build Coastguard Worker for command_type in command_types: 460*cfb92d14SAndroid Build Coastguard Worker if m.mle.command.type == command_type: 461*cfb92d14SAndroid Build Coastguard Worker command_found = True 462*cfb92d14SAndroid Build Coastguard Worker break 463*cfb92d14SAndroid Build Coastguard Worker 464*cfb92d14SAndroid Build Coastguard Worker if command_found: 465*cfb92d14SAndroid Build Coastguard Worker message = m 466*cfb92d14SAndroid Build Coastguard Worker break 467*cfb92d14SAndroid Build Coastguard Worker 468*cfb92d14SAndroid Build Coastguard Worker return message 469*cfb92d14SAndroid Build Coastguard Worker 470*cfb92d14SAndroid Build Coastguard Worker def next_message(self, assert_enabled=True): 471*cfb92d14SAndroid Build Coastguard Worker message = self.messages.pop(0) 472*cfb92d14SAndroid Build Coastguard Worker if assert_enabled: 473*cfb92d14SAndroid Build Coastguard Worker assert message is not None, "Could not find next Message" 474*cfb92d14SAndroid Build Coastguard Worker return message 475*cfb92d14SAndroid Build Coastguard Worker 476*cfb92d14SAndroid Build Coastguard Worker def next_message_of(self, message_type, assert_enabled=True): 477*cfb92d14SAndroid Build Coastguard Worker message = None 478*cfb92d14SAndroid Build Coastguard Worker 479*cfb92d14SAndroid Build Coastguard Worker while self.messages: 480*cfb92d14SAndroid Build Coastguard Worker m = self.messages.pop(0) 481*cfb92d14SAndroid Build Coastguard Worker if m.type != message_type: 482*cfb92d14SAndroid Build Coastguard Worker continue 483*cfb92d14SAndroid Build Coastguard Worker 484*cfb92d14SAndroid Build Coastguard Worker message = m 485*cfb92d14SAndroid Build Coastguard Worker break 486*cfb92d14SAndroid Build Coastguard Worker 487*cfb92d14SAndroid Build Coastguard Worker if assert_enabled: 488*cfb92d14SAndroid Build Coastguard Worker assert (message is not None), "Could not find Message of the type: {}".format(message_type) 489*cfb92d14SAndroid Build Coastguard Worker 490*cfb92d14SAndroid Build Coastguard Worker return message 491*cfb92d14SAndroid Build Coastguard Worker 492*cfb92d14SAndroid Build Coastguard Worker def next_data_message(self): 493*cfb92d14SAndroid Build Coastguard Worker return self.next_message_of(MessageType.DATA) 494*cfb92d14SAndroid Build Coastguard Worker 495*cfb92d14SAndroid Build Coastguard Worker def next_command_message(self): 496*cfb92d14SAndroid Build Coastguard Worker return self.next_message_of(MessageType.COMMAND) 497*cfb92d14SAndroid Build Coastguard Worker 498*cfb92d14SAndroid Build Coastguard Worker def next_dtls_message(self, content_type, handshake_type=None): 499*cfb92d14SAndroid Build Coastguard Worker while self.messages: 500*cfb92d14SAndroid Build Coastguard Worker msg = self.messages.pop(0) 501*cfb92d14SAndroid Build Coastguard Worker if msg.type != MessageType.DTLS: 502*cfb92d14SAndroid Build Coastguard Worker continue 503*cfb92d14SAndroid Build Coastguard Worker if msg.dtls.content_type != content_type: 504*cfb92d14SAndroid Build Coastguard Worker continue 505*cfb92d14SAndroid Build Coastguard Worker if (content_type == dtls.ContentType.HANDSHAKE and msg.dtls.handshake_type != handshake_type): 506*cfb92d14SAndroid Build Coastguard Worker continue 507*cfb92d14SAndroid Build Coastguard Worker return msg 508*cfb92d14SAndroid Build Coastguard Worker 509*cfb92d14SAndroid Build Coastguard Worker t = (handshake_type if content_type == dtls.ContentType.HANDSHAKE else content_type) 510*cfb92d14SAndroid Build Coastguard Worker raise ValueError("Could not find DTLS message of type: {}".format(str(t))) 511*cfb92d14SAndroid Build Coastguard Worker 512*cfb92d14SAndroid Build Coastguard Worker def contains_icmp_message(self): 513*cfb92d14SAndroid Build Coastguard Worker for m in self.messages: 514*cfb92d14SAndroid Build Coastguard Worker if m.type == MessageType.ICMP: 515*cfb92d14SAndroid Build Coastguard Worker return True 516*cfb92d14SAndroid Build Coastguard Worker 517*cfb92d14SAndroid Build Coastguard Worker return False 518*cfb92d14SAndroid Build Coastguard Worker 519*cfb92d14SAndroid Build Coastguard Worker def get_icmp_message(self, icmp_type): 520*cfb92d14SAndroid Build Coastguard Worker for m in self.messages: 521*cfb92d14SAndroid Build Coastguard Worker if m.type != MessageType.ICMP: 522*cfb92d14SAndroid Build Coastguard Worker continue 523*cfb92d14SAndroid Build Coastguard Worker 524*cfb92d14SAndroid Build Coastguard Worker if m.icmp.header.type == icmp_type: 525*cfb92d14SAndroid Build Coastguard Worker return m 526*cfb92d14SAndroid Build Coastguard Worker 527*cfb92d14SAndroid Build Coastguard Worker return None 528*cfb92d14SAndroid Build Coastguard Worker 529*cfb92d14SAndroid Build Coastguard Worker def contains_mle_message(self, command_type): 530*cfb92d14SAndroid Build Coastguard Worker for m in self.messages: 531*cfb92d14SAndroid Build Coastguard Worker if m.type != MessageType.MLE: 532*cfb92d14SAndroid Build Coastguard Worker continue 533*cfb92d14SAndroid Build Coastguard Worker 534*cfb92d14SAndroid Build Coastguard Worker if m.mle.command.type == command_type: 535*cfb92d14SAndroid Build Coastguard Worker return True 536*cfb92d14SAndroid Build Coastguard Worker 537*cfb92d14SAndroid Build Coastguard Worker return False 538*cfb92d14SAndroid Build Coastguard Worker 539*cfb92d14SAndroid Build Coastguard Worker def does_not_contain_coap_message(self): 540*cfb92d14SAndroid Build Coastguard Worker for m in self.messages: 541*cfb92d14SAndroid Build Coastguard Worker if m.type != MessageType.COAP: 542*cfb92d14SAndroid Build Coastguard Worker continue 543*cfb92d14SAndroid Build Coastguard Worker 544*cfb92d14SAndroid Build Coastguard Worker return False 545*cfb92d14SAndroid Build Coastguard Worker 546*cfb92d14SAndroid Build Coastguard Worker return True 547*cfb92d14SAndroid Build Coastguard Worker 548*cfb92d14SAndroid Build Coastguard Worker def clone(self): 549*cfb92d14SAndroid Build Coastguard Worker """Make a copy of current MessageSet. 550*cfb92d14SAndroid Build Coastguard Worker """ 551*cfb92d14SAndroid Build Coastguard Worker return MessagesSet(self.messages[:], self.commissioning_messages[:]) 552*cfb92d14SAndroid Build Coastguard Worker 553*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 554*cfb92d14SAndroid Build Coastguard Worker return str(self.messages) 555*cfb92d14SAndroid Build Coastguard Worker 556*cfb92d14SAndroid Build Coastguard Worker 557*cfb92d14SAndroid Build Coastguard Workerclass MessageFactory: 558*cfb92d14SAndroid Build Coastguard Worker 559*cfb92d14SAndroid Build Coastguard Worker def __init__(self, lowpan_parser): 560*cfb92d14SAndroid Build Coastguard Worker self._lowpan_parser = lowpan_parser 561*cfb92d14SAndroid Build Coastguard Worker 562*cfb92d14SAndroid Build Coastguard Worker def _add_device_descriptors(self, message): 563*cfb92d14SAndroid Build Coastguard Worker for tlv in message.mle.command.tlvs: 564*cfb92d14SAndroid Build Coastguard Worker 565*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, mle.SourceAddress): 566*cfb92d14SAndroid Build Coastguard Worker mac802154.DeviceDescriptors.add(tlv.address, message.mac_header.src_address) 567*cfb92d14SAndroid Build Coastguard Worker 568*cfb92d14SAndroid Build Coastguard Worker if isinstance(tlv, mle.Address16): 569*cfb92d14SAndroid Build Coastguard Worker mac802154.DeviceDescriptors.add(tlv.address, message.mac_header.dest_address) 570*cfb92d14SAndroid Build Coastguard Worker 571*cfb92d14SAndroid Build Coastguard Worker def _parse_mac_frame(self, data): 572*cfb92d14SAndroid Build Coastguard Worker mac_frame = mac802154.MacFrame() 573*cfb92d14SAndroid Build Coastguard Worker mac_frame.parse(data) 574*cfb92d14SAndroid Build Coastguard Worker return mac_frame 575*cfb92d14SAndroid Build Coastguard Worker 576*cfb92d14SAndroid Build Coastguard Worker def set_lowpan_context(self, cid, prefix): 577*cfb92d14SAndroid Build Coastguard Worker self._lowpan_parser.set_lowpan_context(cid, prefix) 578*cfb92d14SAndroid Build Coastguard Worker 579*cfb92d14SAndroid Build Coastguard Worker def create(self, data): 580*cfb92d14SAndroid Build Coastguard Worker try: 581*cfb92d14SAndroid Build Coastguard Worker message = Message() 582*cfb92d14SAndroid Build Coastguard Worker message.channel = struct.unpack(">B", data.read(1)) 583*cfb92d14SAndroid Build Coastguard Worker 584*cfb92d14SAndroid Build Coastguard Worker # Parse MAC header 585*cfb92d14SAndroid Build Coastguard Worker mac_frame = self._parse_mac_frame(data) 586*cfb92d14SAndroid Build Coastguard Worker message.mac_header = mac_frame.header 587*cfb92d14SAndroid Build Coastguard Worker 588*cfb92d14SAndroid Build Coastguard Worker if message.mac_header.frame_type != mac802154.MacHeader.FrameType.DATA: 589*cfb92d14SAndroid Build Coastguard Worker return [message] 590*cfb92d14SAndroid Build Coastguard Worker 591*cfb92d14SAndroid Build Coastguard Worker message_info = common.MessageInfo() 592*cfb92d14SAndroid Build Coastguard Worker message_info.source_mac_address = message.mac_header.src_address 593*cfb92d14SAndroid Build Coastguard Worker message_info.destination_mac_address = message.mac_header.dest_address 594*cfb92d14SAndroid Build Coastguard Worker 595*cfb92d14SAndroid Build Coastguard Worker # Create stream with 6LoWPAN datagram 596*cfb92d14SAndroid Build Coastguard Worker lowpan_payload = io.BytesIO(mac_frame.payload.data) 597*cfb92d14SAndroid Build Coastguard Worker 598*cfb92d14SAndroid Build Coastguard Worker ipv6_packet = self._lowpan_parser.parse(lowpan_payload, message_info) 599*cfb92d14SAndroid Build Coastguard Worker if ipv6_packet is None: 600*cfb92d14SAndroid Build Coastguard Worker return [message] 601*cfb92d14SAndroid Build Coastguard Worker 602*cfb92d14SAndroid Build Coastguard Worker message.ipv6_packet = ipv6_packet 603*cfb92d14SAndroid Build Coastguard Worker 604*cfb92d14SAndroid Build Coastguard Worker if message.type == MessageType.MLE: 605*cfb92d14SAndroid Build Coastguard Worker self._add_device_descriptors(message) 606*cfb92d14SAndroid Build Coastguard Worker 607*cfb92d14SAndroid Build Coastguard Worker return message.try_extract_dtls_messages() 608*cfb92d14SAndroid Build Coastguard Worker 609*cfb92d14SAndroid Build Coastguard Worker except mac802154.KeyIdMode0Exception: 610*cfb92d14SAndroid Build Coastguard Worker print('Received packet with key_id_mode = 0, cannot be handled in test scripts') 611*cfb92d14SAndroid Build Coastguard Worker raise DropPacketException 612