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 logging 32*cfb92d14SAndroid Build Coastguard Workerimport struct 33*cfb92d14SAndroid Build Coastguard Worker 34*cfb92d14SAndroid Build Coastguard Workerfrom binascii import hexlify 35*cfb92d14SAndroid Build Coastguard Worker 36*cfb92d14SAndroid Build Coastguard Workerimport common 37*cfb92d14SAndroid Build Coastguard Worker 38*cfb92d14SAndroid Build Coastguard Workerfrom enum import IntEnum 39*cfb92d14SAndroid Build Coastguard Workerfrom tlvs_parsing import UnknownTlvFactory 40*cfb92d14SAndroid Build Coastguard Worker 41*cfb92d14SAndroid Build Coastguard Worker 42*cfb92d14SAndroid Build Coastguard Workerclass CommandType(IntEnum): 43*cfb92d14SAndroid Build Coastguard Worker LINK_REQUEST = 0 44*cfb92d14SAndroid Build Coastguard Worker LINK_ACCEPT = 1 45*cfb92d14SAndroid Build Coastguard Worker LINK_ACCEPT_AND_REQUEST = 2 46*cfb92d14SAndroid Build Coastguard Worker LINK_REJECT = 3 47*cfb92d14SAndroid Build Coastguard Worker ADVERTISEMENT = 4 48*cfb92d14SAndroid Build Coastguard Worker UPDATE = 5 49*cfb92d14SAndroid Build Coastguard Worker UPDATE_REQUEST = 6 50*cfb92d14SAndroid Build Coastguard Worker DATA_REQUEST = 7 51*cfb92d14SAndroid Build Coastguard Worker DATA_RESPONSE = 8 52*cfb92d14SAndroid Build Coastguard Worker PARENT_REQUEST = 9 53*cfb92d14SAndroid Build Coastguard Worker PARENT_RESPONSE = 10 54*cfb92d14SAndroid Build Coastguard Worker CHILD_ID_REQUEST = 11 55*cfb92d14SAndroid Build Coastguard Worker CHILD_ID_RESPONSE = 12 56*cfb92d14SAndroid Build Coastguard Worker CHILD_UPDATE_REQUEST = 13 57*cfb92d14SAndroid Build Coastguard Worker CHILD_UPDATE_RESPONSE = 14 58*cfb92d14SAndroid Build Coastguard Worker ANNOUNCE = 15 59*cfb92d14SAndroid Build Coastguard Worker DISCOVERY_REQUEST = 16 60*cfb92d14SAndroid Build Coastguard Worker DISCOVERY_RESPONSE = 17 61*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_MANAGEMENT_REQUEST = 18 62*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_MANAGEMENT_RESPONSE = 19 63*cfb92d14SAndroid Build Coastguard Worker LINK_PROBE = 20 64*cfb92d14SAndroid Build Coastguard Worker TIME_SYNC = 99 65*cfb92d14SAndroid Build Coastguard Worker 66*cfb92d14SAndroid Build Coastguard Worker 67*cfb92d14SAndroid Build Coastguard Workerclass TlvType(IntEnum): 68*cfb92d14SAndroid Build Coastguard Worker SOURCE_ADDRESS = 0 69*cfb92d14SAndroid Build Coastguard Worker MODE = 1 70*cfb92d14SAndroid Build Coastguard Worker TIMEOUT = 2 71*cfb92d14SAndroid Build Coastguard Worker CHALLENGE = 3 72*cfb92d14SAndroid Build Coastguard Worker RESPONSE = 4 73*cfb92d14SAndroid Build Coastguard Worker LINK_LAYER_FRAME_COUNTER = 5 74*cfb92d14SAndroid Build Coastguard Worker MLE_FRAME_COUNTER = 8 75*cfb92d14SAndroid Build Coastguard Worker ROUTE64 = 9 76*cfb92d14SAndroid Build Coastguard Worker ADDRESS16 = 10 77*cfb92d14SAndroid Build Coastguard Worker LEADER_DATA = 11 78*cfb92d14SAndroid Build Coastguard Worker NETWORK_DATA = 12 79*cfb92d14SAndroid Build Coastguard Worker TLV_REQUEST = 13 80*cfb92d14SAndroid Build Coastguard Worker SCAN_MASK = 14 81*cfb92d14SAndroid Build Coastguard Worker CONNECTIVITY = 15 82*cfb92d14SAndroid Build Coastguard Worker LINK_MARGIN = 16 83*cfb92d14SAndroid Build Coastguard Worker STATUS = 17 84*cfb92d14SAndroid Build Coastguard Worker VERSION = 18 85*cfb92d14SAndroid Build Coastguard Worker ADDRESS_REGISTRATION = 19 86*cfb92d14SAndroid Build Coastguard Worker CHANNEL = 20 87*cfb92d14SAndroid Build Coastguard Worker PANID = 21 88*cfb92d14SAndroid Build Coastguard Worker ACTIVE_TIMESTAMP = 22 89*cfb92d14SAndroid Build Coastguard Worker PENDING_TIMESTAMP = 23 90*cfb92d14SAndroid Build Coastguard Worker ACTIVE_OPERATIONAL_DATASET = 24 91*cfb92d14SAndroid Build Coastguard Worker PENDING_OPERATIONAL_DATASET = 25 92*cfb92d14SAndroid Build Coastguard Worker THREAD_DISCOVERY = 26 93*cfb92d14SAndroid Build Coastguard Worker SUPERVISION_INTERVAL = 27 94*cfb92d14SAndroid Build Coastguard Worker CSL_CHANNEL = 80 95*cfb92d14SAndroid Build Coastguard Worker CSL_SYNCHRONIZED_TIMEOUT = 85 96*cfb92d14SAndroid Build Coastguard Worker CSL_CLOCK_ACCURACY = 86 97*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_QUERY = 87 98*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_MANAGEMENT = 88 99*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_REPORT = 89 100*cfb92d14SAndroid Build Coastguard Worker LINK_PROBE = 90 101*cfb92d14SAndroid Build Coastguard Worker TIME_REQUEST = 252 102*cfb92d14SAndroid Build Coastguard Worker TIME_PARAMETER = 253 103*cfb92d14SAndroid Build Coastguard Worker 104*cfb92d14SAndroid Build Coastguard Worker 105*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsSubTlvType(IntEnum): 106*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_REPORT = 0 107*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_QUERY_ID = 1 108*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_QUERY_OPTIONS = 2 109*cfb92d14SAndroid Build Coastguard Worker FORWARD_PROBING_REGISTRATION = 3 110*cfb92d14SAndroid Build Coastguard Worker LINK_METRICS_STATUS = 5 111*cfb92d14SAndroid Build Coastguard Worker ENHANCED_ACK_LINK_METRICS_CONFIGURATION = 7 112*cfb92d14SAndroid Build Coastguard Worker 113*cfb92d14SAndroid Build Coastguard Worker 114*cfb92d14SAndroid Build Coastguard Workerclass SourceAddress(object): 115*cfb92d14SAndroid Build Coastguard Worker 116*cfb92d14SAndroid Build Coastguard Worker def __init__(self, address): 117*cfb92d14SAndroid Build Coastguard Worker self._address = address 118*cfb92d14SAndroid Build Coastguard Worker 119*cfb92d14SAndroid Build Coastguard Worker @property 120*cfb92d14SAndroid Build Coastguard Worker def address(self): 121*cfb92d14SAndroid Build Coastguard Worker return self._address 122*cfb92d14SAndroid Build Coastguard Worker 123*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 124*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 125*cfb92d14SAndroid Build Coastguard Worker 126*cfb92d14SAndroid Build Coastguard Worker return self.address == other.address 127*cfb92d14SAndroid Build Coastguard Worker 128*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 129*cfb92d14SAndroid Build Coastguard Worker return "SourceAddress(address={})".format(hex(self._address)) 130*cfb92d14SAndroid Build Coastguard Worker 131*cfb92d14SAndroid Build Coastguard Worker 132*cfb92d14SAndroid Build Coastguard Workerclass SourceAddressFactory: 133*cfb92d14SAndroid Build Coastguard Worker 134*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 135*cfb92d14SAndroid Build Coastguard Worker address = struct.unpack(">H", data.read(2))[0] 136*cfb92d14SAndroid Build Coastguard Worker return SourceAddress(address) 137*cfb92d14SAndroid Build Coastguard Worker 138*cfb92d14SAndroid Build Coastguard Worker 139*cfb92d14SAndroid Build Coastguard Workerclass Mode(object): 140*cfb92d14SAndroid Build Coastguard Worker 141*cfb92d14SAndroid Build Coastguard Worker def __init__(self, receiver, secure, device_type, network_data): 142*cfb92d14SAndroid Build Coastguard Worker self._receiver = receiver 143*cfb92d14SAndroid Build Coastguard Worker self._secure = secure 144*cfb92d14SAndroid Build Coastguard Worker self._device_type = device_type 145*cfb92d14SAndroid Build Coastguard Worker self._network_data = network_data 146*cfb92d14SAndroid Build Coastguard Worker 147*cfb92d14SAndroid Build Coastguard Worker @property 148*cfb92d14SAndroid Build Coastguard Worker def receiver(self): 149*cfb92d14SAndroid Build Coastguard Worker return self._receiver 150*cfb92d14SAndroid Build Coastguard Worker 151*cfb92d14SAndroid Build Coastguard Worker @property 152*cfb92d14SAndroid Build Coastguard Worker def secure(self): 153*cfb92d14SAndroid Build Coastguard Worker return self._secure 154*cfb92d14SAndroid Build Coastguard Worker 155*cfb92d14SAndroid Build Coastguard Worker @property 156*cfb92d14SAndroid Build Coastguard Worker def device_type(self): 157*cfb92d14SAndroid Build Coastguard Worker return self._device_type 158*cfb92d14SAndroid Build Coastguard Worker 159*cfb92d14SAndroid Build Coastguard Worker @property 160*cfb92d14SAndroid Build Coastguard Worker def network_data(self): 161*cfb92d14SAndroid Build Coastguard Worker return self._network_data 162*cfb92d14SAndroid Build Coastguard Worker 163*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 164*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 165*cfb92d14SAndroid Build Coastguard Worker 166*cfb92d14SAndroid Build Coastguard Worker return (self.receiver == other.receiver and self.secure == other.secure and 167*cfb92d14SAndroid Build Coastguard Worker self.device_type == other.device_type and self.network_data == other.network_data) 168*cfb92d14SAndroid Build Coastguard Worker 169*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 170*cfb92d14SAndroid Build Coastguard Worker return "Mode(receiver={}, secure={}, device_type={}, network_data={})".format( 171*cfb92d14SAndroid Build Coastguard Worker self.receiver, self.secure, self.device_type, self.network_data) 172*cfb92d14SAndroid Build Coastguard Worker 173*cfb92d14SAndroid Build Coastguard Worker 174*cfb92d14SAndroid Build Coastguard Workerclass ModeFactory: 175*cfb92d14SAndroid Build Coastguard Worker 176*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 177*cfb92d14SAndroid Build Coastguard Worker mode = ord(data.read(1)) 178*cfb92d14SAndroid Build Coastguard Worker receiver = (mode >> 3) & 0x01 179*cfb92d14SAndroid Build Coastguard Worker secure = (mode >> 2) & 0x01 180*cfb92d14SAndroid Build Coastguard Worker device_type = (mode >> 1) & 0x01 181*cfb92d14SAndroid Build Coastguard Worker network_data = (mode >> 0) & 0x01 182*cfb92d14SAndroid Build Coastguard Worker return Mode(receiver, secure, device_type, network_data) 183*cfb92d14SAndroid Build Coastguard Worker 184*cfb92d14SAndroid Build Coastguard Worker 185*cfb92d14SAndroid Build Coastguard Workerclass Timeout(object): 186*cfb92d14SAndroid Build Coastguard Worker 187*cfb92d14SAndroid Build Coastguard Worker def __init__(self, timeout): 188*cfb92d14SAndroid Build Coastguard Worker self._timeout = timeout 189*cfb92d14SAndroid Build Coastguard Worker 190*cfb92d14SAndroid Build Coastguard Worker @property 191*cfb92d14SAndroid Build Coastguard Worker def timeout(self): 192*cfb92d14SAndroid Build Coastguard Worker return self._timeout 193*cfb92d14SAndroid Build Coastguard Worker 194*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 195*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 196*cfb92d14SAndroid Build Coastguard Worker 197*cfb92d14SAndroid Build Coastguard Worker return self.timeout == other.timeout 198*cfb92d14SAndroid Build Coastguard Worker 199*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 200*cfb92d14SAndroid Build Coastguard Worker return "Timeout(timeout={})".format(self.timeout) 201*cfb92d14SAndroid Build Coastguard Worker 202*cfb92d14SAndroid Build Coastguard Worker 203*cfb92d14SAndroid Build Coastguard Workerclass TimeoutFactory: 204*cfb92d14SAndroid Build Coastguard Worker 205*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 206*cfb92d14SAndroid Build Coastguard Worker timeout = struct.unpack(">I", data.read(4))[0] 207*cfb92d14SAndroid Build Coastguard Worker return Timeout(timeout) 208*cfb92d14SAndroid Build Coastguard Worker 209*cfb92d14SAndroid Build Coastguard Worker 210*cfb92d14SAndroid Build Coastguard Workerclass Challenge(object): 211*cfb92d14SAndroid Build Coastguard Worker 212*cfb92d14SAndroid Build Coastguard Worker def __init__(self, challenge): 213*cfb92d14SAndroid Build Coastguard Worker self._challenge = challenge 214*cfb92d14SAndroid Build Coastguard Worker 215*cfb92d14SAndroid Build Coastguard Worker @property 216*cfb92d14SAndroid Build Coastguard Worker def challenge(self): 217*cfb92d14SAndroid Build Coastguard Worker return self._challenge 218*cfb92d14SAndroid Build Coastguard Worker 219*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 220*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 221*cfb92d14SAndroid Build Coastguard Worker 222*cfb92d14SAndroid Build Coastguard Worker return self.challenge == other.challenge 223*cfb92d14SAndroid Build Coastguard Worker 224*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 225*cfb92d14SAndroid Build Coastguard Worker return "Challenge(challenge={})".format(hexlify(self.challenge)) 226*cfb92d14SAndroid Build Coastguard Worker 227*cfb92d14SAndroid Build Coastguard Worker 228*cfb92d14SAndroid Build Coastguard Workerclass ChallengeFactory: 229*cfb92d14SAndroid Build Coastguard Worker 230*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 231*cfb92d14SAndroid Build Coastguard Worker challenge = data.read() 232*cfb92d14SAndroid Build Coastguard Worker return Challenge(challenge) 233*cfb92d14SAndroid Build Coastguard Worker 234*cfb92d14SAndroid Build Coastguard Worker 235*cfb92d14SAndroid Build Coastguard Workerclass Response(object): 236*cfb92d14SAndroid Build Coastguard Worker 237*cfb92d14SAndroid Build Coastguard Worker def __init__(self, response): 238*cfb92d14SAndroid Build Coastguard Worker self._response = response 239*cfb92d14SAndroid Build Coastguard Worker 240*cfb92d14SAndroid Build Coastguard Worker @property 241*cfb92d14SAndroid Build Coastguard Worker def response(self): 242*cfb92d14SAndroid Build Coastguard Worker return self._response 243*cfb92d14SAndroid Build Coastguard Worker 244*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 245*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 246*cfb92d14SAndroid Build Coastguard Worker 247*cfb92d14SAndroid Build Coastguard Worker return self.response == other.response 248*cfb92d14SAndroid Build Coastguard Worker 249*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 250*cfb92d14SAndroid Build Coastguard Worker return "Response(response={})".format(hexlify(self.response)) 251*cfb92d14SAndroid Build Coastguard Worker 252*cfb92d14SAndroid Build Coastguard Worker 253*cfb92d14SAndroid Build Coastguard Workerclass ResponseFactory: 254*cfb92d14SAndroid Build Coastguard Worker 255*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 256*cfb92d14SAndroid Build Coastguard Worker response = data.read() 257*cfb92d14SAndroid Build Coastguard Worker return Response(response) 258*cfb92d14SAndroid Build Coastguard Worker 259*cfb92d14SAndroid Build Coastguard Worker 260*cfb92d14SAndroid Build Coastguard Workerclass LinkLayerFrameCounter(object): 261*cfb92d14SAndroid Build Coastguard Worker 262*cfb92d14SAndroid Build Coastguard Worker def __init__(self, frame_counter): 263*cfb92d14SAndroid Build Coastguard Worker self._frame_counter = frame_counter 264*cfb92d14SAndroid Build Coastguard Worker 265*cfb92d14SAndroid Build Coastguard Worker @property 266*cfb92d14SAndroid Build Coastguard Worker def frame_counter(self): 267*cfb92d14SAndroid Build Coastguard Worker return self._frame_counter 268*cfb92d14SAndroid Build Coastguard Worker 269*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 270*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 271*cfb92d14SAndroid Build Coastguard Worker 272*cfb92d14SAndroid Build Coastguard Worker return self.frame_counter == other.frame_counter 273*cfb92d14SAndroid Build Coastguard Worker 274*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 275*cfb92d14SAndroid Build Coastguard Worker return "LinkLayerFrameCounter(frame_counter={})".format(self.frame_counter) 276*cfb92d14SAndroid Build Coastguard Worker 277*cfb92d14SAndroid Build Coastguard Worker 278*cfb92d14SAndroid Build Coastguard Workerclass LinkLayerFrameCounterFactory: 279*cfb92d14SAndroid Build Coastguard Worker 280*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 281*cfb92d14SAndroid Build Coastguard Worker frame_counter = struct.unpack(">I", data.read(4))[0] 282*cfb92d14SAndroid Build Coastguard Worker return LinkLayerFrameCounter(frame_counter) 283*cfb92d14SAndroid Build Coastguard Worker 284*cfb92d14SAndroid Build Coastguard Worker 285*cfb92d14SAndroid Build Coastguard Workerclass MleFrameCounter(object): 286*cfb92d14SAndroid Build Coastguard Worker 287*cfb92d14SAndroid Build Coastguard Worker def __init__(self, frame_counter): 288*cfb92d14SAndroid Build Coastguard Worker self._frame_counter = frame_counter 289*cfb92d14SAndroid Build Coastguard Worker 290*cfb92d14SAndroid Build Coastguard Worker @property 291*cfb92d14SAndroid Build Coastguard Worker def frame_counter(self): 292*cfb92d14SAndroid Build Coastguard Worker return self._frame_counter 293*cfb92d14SAndroid Build Coastguard Worker 294*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 295*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 296*cfb92d14SAndroid Build Coastguard Worker 297*cfb92d14SAndroid Build Coastguard Worker return self.frame_counter == other.frame_counter 298*cfb92d14SAndroid Build Coastguard Worker 299*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 300*cfb92d14SAndroid Build Coastguard Worker return "MleFrameCounter(frame_counter={})".format(self.frame_counter) 301*cfb92d14SAndroid Build Coastguard Worker 302*cfb92d14SAndroid Build Coastguard Worker 303*cfb92d14SAndroid Build Coastguard Workerclass MleFrameCounterFactory: 304*cfb92d14SAndroid Build Coastguard Worker 305*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 306*cfb92d14SAndroid Build Coastguard Worker frame_counter = struct.unpack(">I", data.read(4))[0] 307*cfb92d14SAndroid Build Coastguard Worker return MleFrameCounter(frame_counter) 308*cfb92d14SAndroid Build Coastguard Worker 309*cfb92d14SAndroid Build Coastguard Worker 310*cfb92d14SAndroid Build Coastguard Workerclass LinkQualityAndRouteData(object): 311*cfb92d14SAndroid Build Coastguard Worker 312*cfb92d14SAndroid Build Coastguard Worker def __init__(self, output, _input, route): 313*cfb92d14SAndroid Build Coastguard Worker self._output = output 314*cfb92d14SAndroid Build Coastguard Worker self._input = _input 315*cfb92d14SAndroid Build Coastguard Worker self._route = route 316*cfb92d14SAndroid Build Coastguard Worker 317*cfb92d14SAndroid Build Coastguard Worker @property 318*cfb92d14SAndroid Build Coastguard Worker def output(self): 319*cfb92d14SAndroid Build Coastguard Worker return self._output 320*cfb92d14SAndroid Build Coastguard Worker 321*cfb92d14SAndroid Build Coastguard Worker @property 322*cfb92d14SAndroid Build Coastguard Worker def input(self): 323*cfb92d14SAndroid Build Coastguard Worker return self._input 324*cfb92d14SAndroid Build Coastguard Worker 325*cfb92d14SAndroid Build Coastguard Worker @property 326*cfb92d14SAndroid Build Coastguard Worker def route(self): 327*cfb92d14SAndroid Build Coastguard Worker return self._route 328*cfb92d14SAndroid Build Coastguard Worker 329*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 330*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 331*cfb92d14SAndroid Build Coastguard Worker 332*cfb92d14SAndroid Build Coastguard Worker return (self.output == other.output and self.input == other.input and self.route == other.route) 333*cfb92d14SAndroid Build Coastguard Worker 334*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 335*cfb92d14SAndroid Build Coastguard Worker return "LinkQualityAndRouteData(output={}, input={}, route={})".format(self.output, self.input, self.route) 336*cfb92d14SAndroid Build Coastguard Worker 337*cfb92d14SAndroid Build Coastguard Worker 338*cfb92d14SAndroid Build Coastguard Workerclass LinkQualityAndRouteDataFactory: 339*cfb92d14SAndroid Build Coastguard Worker 340*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 341*cfb92d14SAndroid Build Coastguard Worker lqrd = ord(data.read(1)) 342*cfb92d14SAndroid Build Coastguard Worker output = (lqrd >> 6) & 0x3 343*cfb92d14SAndroid Build Coastguard Worker _input = (lqrd >> 4) & 0x3 344*cfb92d14SAndroid Build Coastguard Worker route = lqrd & 0x0F 345*cfb92d14SAndroid Build Coastguard Worker return LinkQualityAndRouteData(output, _input, route) 346*cfb92d14SAndroid Build Coastguard Worker 347*cfb92d14SAndroid Build Coastguard Worker 348*cfb92d14SAndroid Build Coastguard Workerclass Route64(object): 349*cfb92d14SAndroid Build Coastguard Worker 350*cfb92d14SAndroid Build Coastguard Worker def __init__(self, id_sequence, router_id_mask, link_quality_and_route_data): 351*cfb92d14SAndroid Build Coastguard Worker self._id_sequence = id_sequence 352*cfb92d14SAndroid Build Coastguard Worker self._router_id_mask = router_id_mask 353*cfb92d14SAndroid Build Coastguard Worker self._link_quality_and_route_data = link_quality_and_route_data 354*cfb92d14SAndroid Build Coastguard Worker 355*cfb92d14SAndroid Build Coastguard Worker @property 356*cfb92d14SAndroid Build Coastguard Worker def id_sequence(self): 357*cfb92d14SAndroid Build Coastguard Worker return self._id_sequence 358*cfb92d14SAndroid Build Coastguard Worker 359*cfb92d14SAndroid Build Coastguard Worker @property 360*cfb92d14SAndroid Build Coastguard Worker def router_id_mask(self): 361*cfb92d14SAndroid Build Coastguard Worker return self._router_id_mask 362*cfb92d14SAndroid Build Coastguard Worker 363*cfb92d14SAndroid Build Coastguard Worker @property 364*cfb92d14SAndroid Build Coastguard Worker def link_quality_and_route_data(self): 365*cfb92d14SAndroid Build Coastguard Worker return self._link_quality_and_route_data 366*cfb92d14SAndroid Build Coastguard Worker 367*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 368*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 369*cfb92d14SAndroid Build Coastguard Worker 370*cfb92d14SAndroid Build Coastguard Worker return (self.id_sequence == other.id_sequence and self.router_id_mask == other.router_id_mask and 371*cfb92d14SAndroid Build Coastguard Worker self.link_quality_and_route_data == other.link_quality_and_route_data) 372*cfb92d14SAndroid Build Coastguard Worker 373*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 374*cfb92d14SAndroid Build Coastguard Worker lqrd_str = ", ".join(["{}".format(lqrd) for lqrd in self.link_quality_and_route_data]) 375*cfb92d14SAndroid Build Coastguard Worker return "Route64(id_sequence={}, router_id_mask={}, link_quality_and_route_data=[{}])".format( 376*cfb92d14SAndroid Build Coastguard Worker self.id_sequence, hex(self.router_id_mask), lqrd_str) 377*cfb92d14SAndroid Build Coastguard Worker 378*cfb92d14SAndroid Build Coastguard Worker 379*cfb92d14SAndroid Build Coastguard Workerclass Route64Factory: 380*cfb92d14SAndroid Build Coastguard Worker 381*cfb92d14SAndroid Build Coastguard Worker def __init__(self, link_quality_and_route_data_factory): 382*cfb92d14SAndroid Build Coastguard Worker self._lqrd_factory = link_quality_and_route_data_factory 383*cfb92d14SAndroid Build Coastguard Worker 384*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 385*cfb92d14SAndroid Build Coastguard Worker id_sequence = ord(data.read(1)) 386*cfb92d14SAndroid Build Coastguard Worker router_id_mask = struct.unpack(">Q", data.read(8))[0] 387*cfb92d14SAndroid Build Coastguard Worker 388*cfb92d14SAndroid Build Coastguard Worker link_quality_and_route_data = [] 389*cfb92d14SAndroid Build Coastguard Worker 390*cfb92d14SAndroid Build Coastguard Worker while data.tell() < len(data.getvalue()): 391*cfb92d14SAndroid Build Coastguard Worker link_quality_and_route_data.append(self._lqrd_factory.parse(data, message_info)) 392*cfb92d14SAndroid Build Coastguard Worker 393*cfb92d14SAndroid Build Coastguard Worker return Route64(id_sequence, router_id_mask, link_quality_and_route_data) 394*cfb92d14SAndroid Build Coastguard Worker 395*cfb92d14SAndroid Build Coastguard Worker 396*cfb92d14SAndroid Build Coastguard Workerclass Address16(object): 397*cfb92d14SAndroid Build Coastguard Worker 398*cfb92d14SAndroid Build Coastguard Worker def __init__(self, address): 399*cfb92d14SAndroid Build Coastguard Worker self._address = address 400*cfb92d14SAndroid Build Coastguard Worker 401*cfb92d14SAndroid Build Coastguard Worker @property 402*cfb92d14SAndroid Build Coastguard Worker def address(self): 403*cfb92d14SAndroid Build Coastguard Worker return self._address 404*cfb92d14SAndroid Build Coastguard Worker 405*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 406*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 407*cfb92d14SAndroid Build Coastguard Worker 408*cfb92d14SAndroid Build Coastguard Worker return self.address == other.address 409*cfb92d14SAndroid Build Coastguard Worker 410*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 411*cfb92d14SAndroid Build Coastguard Worker return "Address16(address={})".format(hex(self.address)) 412*cfb92d14SAndroid Build Coastguard Worker 413*cfb92d14SAndroid Build Coastguard Worker 414*cfb92d14SAndroid Build Coastguard Workerclass Address16Factory: 415*cfb92d14SAndroid Build Coastguard Worker 416*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 417*cfb92d14SAndroid Build Coastguard Worker address = struct.unpack(">H", data.read(2))[0] 418*cfb92d14SAndroid Build Coastguard Worker return Address16(address) 419*cfb92d14SAndroid Build Coastguard Worker 420*cfb92d14SAndroid Build Coastguard Worker 421*cfb92d14SAndroid Build Coastguard Workerclass LeaderData(object): 422*cfb92d14SAndroid Build Coastguard Worker 423*cfb92d14SAndroid Build Coastguard Worker def __init__( 424*cfb92d14SAndroid Build Coastguard Worker self, 425*cfb92d14SAndroid Build Coastguard Worker partition_id, 426*cfb92d14SAndroid Build Coastguard Worker weighting, 427*cfb92d14SAndroid Build Coastguard Worker data_version, 428*cfb92d14SAndroid Build Coastguard Worker stable_data_version, 429*cfb92d14SAndroid Build Coastguard Worker leader_router_id, 430*cfb92d14SAndroid Build Coastguard Worker ): 431*cfb92d14SAndroid Build Coastguard Worker self._partition_id = partition_id 432*cfb92d14SAndroid Build Coastguard Worker self._weighting = weighting 433*cfb92d14SAndroid Build Coastguard Worker self._data_version = data_version 434*cfb92d14SAndroid Build Coastguard Worker self._stable_data_version = stable_data_version 435*cfb92d14SAndroid Build Coastguard Worker self._leader_router_id = leader_router_id 436*cfb92d14SAndroid Build Coastguard Worker 437*cfb92d14SAndroid Build Coastguard Worker @property 438*cfb92d14SAndroid Build Coastguard Worker def partition_id(self): 439*cfb92d14SAndroid Build Coastguard Worker return self._partition_id 440*cfb92d14SAndroid Build Coastguard Worker 441*cfb92d14SAndroid Build Coastguard Worker @property 442*cfb92d14SAndroid Build Coastguard Worker def weighting(self): 443*cfb92d14SAndroid Build Coastguard Worker return self._weighting 444*cfb92d14SAndroid Build Coastguard Worker 445*cfb92d14SAndroid Build Coastguard Worker @property 446*cfb92d14SAndroid Build Coastguard Worker def data_version(self): 447*cfb92d14SAndroid Build Coastguard Worker return self._data_version 448*cfb92d14SAndroid Build Coastguard Worker 449*cfb92d14SAndroid Build Coastguard Worker @property 450*cfb92d14SAndroid Build Coastguard Worker def stable_data_version(self): 451*cfb92d14SAndroid Build Coastguard Worker return self._stable_data_version 452*cfb92d14SAndroid Build Coastguard Worker 453*cfb92d14SAndroid Build Coastguard Worker @property 454*cfb92d14SAndroid Build Coastguard Worker def leader_router_id(self): 455*cfb92d14SAndroid Build Coastguard Worker return self._leader_router_id 456*cfb92d14SAndroid Build Coastguard Worker 457*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 458*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 459*cfb92d14SAndroid Build Coastguard Worker 460*cfb92d14SAndroid Build Coastguard Worker return (self.partition_id == other.partition_id and self.weighting == other.weighting and 461*cfb92d14SAndroid Build Coastguard Worker self.data_version == other.data_version and self.stable_data_version == other.stable_data_version and 462*cfb92d14SAndroid Build Coastguard Worker self.leader_router_id == other.leader_router_id) 463*cfb92d14SAndroid Build Coastguard Worker 464*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 465*cfb92d14SAndroid Build Coastguard Worker return 'LeaderData(partition_id={}, weighting={}, data_version={}, stable_data_version={},leader_router_id={}'.format( 466*cfb92d14SAndroid Build Coastguard Worker self.partition_id, 467*cfb92d14SAndroid Build Coastguard Worker self.weighting, 468*cfb92d14SAndroid Build Coastguard Worker self.data_version, 469*cfb92d14SAndroid Build Coastguard Worker self.stable_data_version, 470*cfb92d14SAndroid Build Coastguard Worker self.leader_router_id, 471*cfb92d14SAndroid Build Coastguard Worker ) 472*cfb92d14SAndroid Build Coastguard Worker 473*cfb92d14SAndroid Build Coastguard Worker 474*cfb92d14SAndroid Build Coastguard Workerclass LeaderDataFactory: 475*cfb92d14SAndroid Build Coastguard Worker 476*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 477*cfb92d14SAndroid Build Coastguard Worker partition_id = struct.unpack(">I", data.read(4))[0] 478*cfb92d14SAndroid Build Coastguard Worker weighting = ord(data.read(1)) 479*cfb92d14SAndroid Build Coastguard Worker data_version = ord(data.read(1)) 480*cfb92d14SAndroid Build Coastguard Worker stable_data_version = ord(data.read(1)) 481*cfb92d14SAndroid Build Coastguard Worker leader_router_id = ord(data.read(1)) 482*cfb92d14SAndroid Build Coastguard Worker return LeaderData( 483*cfb92d14SAndroid Build Coastguard Worker partition_id, 484*cfb92d14SAndroid Build Coastguard Worker weighting, 485*cfb92d14SAndroid Build Coastguard Worker data_version, 486*cfb92d14SAndroid Build Coastguard Worker stable_data_version, 487*cfb92d14SAndroid Build Coastguard Worker leader_router_id, 488*cfb92d14SAndroid Build Coastguard Worker ) 489*cfb92d14SAndroid Build Coastguard Worker 490*cfb92d14SAndroid Build Coastguard Worker 491*cfb92d14SAndroid Build Coastguard Workerclass NetworkData(object): 492*cfb92d14SAndroid Build Coastguard Worker 493*cfb92d14SAndroid Build Coastguard Worker def __init__(self, tlvs): 494*cfb92d14SAndroid Build Coastguard Worker self._tlvs = tlvs 495*cfb92d14SAndroid Build Coastguard Worker 496*cfb92d14SAndroid Build Coastguard Worker @property 497*cfb92d14SAndroid Build Coastguard Worker def tlvs(self): 498*cfb92d14SAndroid Build Coastguard Worker return self._tlvs 499*cfb92d14SAndroid Build Coastguard Worker 500*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 501*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 502*cfb92d14SAndroid Build Coastguard Worker 503*cfb92d14SAndroid Build Coastguard Worker return self.tlvs == other.tlvs 504*cfb92d14SAndroid Build Coastguard Worker 505*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 506*cfb92d14SAndroid Build Coastguard Worker tlvs_str = ", ".join(["{}".format(tlv) for tlv in self.tlvs]) 507*cfb92d14SAndroid Build Coastguard Worker return "NetworkData(tlvs=[{}])".format(tlvs_str) 508*cfb92d14SAndroid Build Coastguard Worker 509*cfb92d14SAndroid Build Coastguard Worker 510*cfb92d14SAndroid Build Coastguard Workerclass NetworkDataFactory: 511*cfb92d14SAndroid Build Coastguard Worker 512*cfb92d14SAndroid Build Coastguard Worker def __init__(self, network_data_tlvs_factory): 513*cfb92d14SAndroid Build Coastguard Worker self._tlvs_factory = network_data_tlvs_factory 514*cfb92d14SAndroid Build Coastguard Worker 515*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 516*cfb92d14SAndroid Build Coastguard Worker tlvs = self._tlvs_factory.parse(data, message_info) 517*cfb92d14SAndroid Build Coastguard Worker return NetworkData(tlvs) 518*cfb92d14SAndroid Build Coastguard Worker 519*cfb92d14SAndroid Build Coastguard Worker 520*cfb92d14SAndroid Build Coastguard Workerclass TlvRequest(object): 521*cfb92d14SAndroid Build Coastguard Worker 522*cfb92d14SAndroid Build Coastguard Worker def __init__(self, tlvs): 523*cfb92d14SAndroid Build Coastguard Worker self._tlvs = tlvs 524*cfb92d14SAndroid Build Coastguard Worker 525*cfb92d14SAndroid Build Coastguard Worker @property 526*cfb92d14SAndroid Build Coastguard Worker def tlvs(self): 527*cfb92d14SAndroid Build Coastguard Worker return self._tlvs 528*cfb92d14SAndroid Build Coastguard Worker 529*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 530*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 531*cfb92d14SAndroid Build Coastguard Worker 532*cfb92d14SAndroid Build Coastguard Worker return self.tlvs == other.tlvs 533*cfb92d14SAndroid Build Coastguard Worker 534*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 535*cfb92d14SAndroid Build Coastguard Worker tlvs_str = ", ".join(["{}".format(tlv) for tlv in self.tlvs]) 536*cfb92d14SAndroid Build Coastguard Worker return "TlvRequest(tlvs=[{}])".format(tlvs_str) 537*cfb92d14SAndroid Build Coastguard Worker 538*cfb92d14SAndroid Build Coastguard Worker 539*cfb92d14SAndroid Build Coastguard Workerclass TlvRequestFactory: 540*cfb92d14SAndroid Build Coastguard Worker 541*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 542*cfb92d14SAndroid Build Coastguard Worker tlvs = [b for b in bytearray(data.read())] 543*cfb92d14SAndroid Build Coastguard Worker return TlvRequest(tlvs) 544*cfb92d14SAndroid Build Coastguard Worker 545*cfb92d14SAndroid Build Coastguard Worker 546*cfb92d14SAndroid Build Coastguard Workerclass ScanMask(object): 547*cfb92d14SAndroid Build Coastguard Worker 548*cfb92d14SAndroid Build Coastguard Worker def __init__(self, router, end_device): 549*cfb92d14SAndroid Build Coastguard Worker self._router = router 550*cfb92d14SAndroid Build Coastguard Worker self._end_device = end_device 551*cfb92d14SAndroid Build Coastguard Worker 552*cfb92d14SAndroid Build Coastguard Worker @property 553*cfb92d14SAndroid Build Coastguard Worker def router(self): 554*cfb92d14SAndroid Build Coastguard Worker return self._router 555*cfb92d14SAndroid Build Coastguard Worker 556*cfb92d14SAndroid Build Coastguard Worker @property 557*cfb92d14SAndroid Build Coastguard Worker def end_device(self): 558*cfb92d14SAndroid Build Coastguard Worker return self._end_device 559*cfb92d14SAndroid Build Coastguard Worker 560*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 561*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 562*cfb92d14SAndroid Build Coastguard Worker 563*cfb92d14SAndroid Build Coastguard Worker return (self.router == other.router and self.end_device == other.end_device) 564*cfb92d14SAndroid Build Coastguard Worker 565*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 566*cfb92d14SAndroid Build Coastguard Worker return "ScanMask(router={}, end_device={})".format(self.router, self.end_device) 567*cfb92d14SAndroid Build Coastguard Worker 568*cfb92d14SAndroid Build Coastguard Worker 569*cfb92d14SAndroid Build Coastguard Workerclass ScanMaskFactory: 570*cfb92d14SAndroid Build Coastguard Worker 571*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 572*cfb92d14SAndroid Build Coastguard Worker scan_mask = ord(data.read(1)) 573*cfb92d14SAndroid Build Coastguard Worker router = (scan_mask >> 7) & 0x01 574*cfb92d14SAndroid Build Coastguard Worker end_device = (scan_mask >> 6) & 0x01 575*cfb92d14SAndroid Build Coastguard Worker return ScanMask(router, end_device) 576*cfb92d14SAndroid Build Coastguard Worker 577*cfb92d14SAndroid Build Coastguard Worker 578*cfb92d14SAndroid Build Coastguard Workerclass Connectivity(object): 579*cfb92d14SAndroid Build Coastguard Worker 580*cfb92d14SAndroid Build Coastguard Worker def __init__( 581*cfb92d14SAndroid Build Coastguard Worker self, 582*cfb92d14SAndroid Build Coastguard Worker pp_byte, 583*cfb92d14SAndroid Build Coastguard Worker link_quality_3, 584*cfb92d14SAndroid Build Coastguard Worker link_quality_2, 585*cfb92d14SAndroid Build Coastguard Worker link_quality_1, 586*cfb92d14SAndroid Build Coastguard Worker leader_cost, 587*cfb92d14SAndroid Build Coastguard Worker id_sequence, 588*cfb92d14SAndroid Build Coastguard Worker active_routers, 589*cfb92d14SAndroid Build Coastguard Worker sed_buffer_size=None, 590*cfb92d14SAndroid Build Coastguard Worker sed_datagram_count=None, 591*cfb92d14SAndroid Build Coastguard Worker ): 592*cfb92d14SAndroid Build Coastguard Worker self._pp_byte = pp_byte 593*cfb92d14SAndroid Build Coastguard Worker self._link_quality_3 = link_quality_3 594*cfb92d14SAndroid Build Coastguard Worker self._link_quality_2 = link_quality_2 595*cfb92d14SAndroid Build Coastguard Worker self._link_quality_1 = link_quality_1 596*cfb92d14SAndroid Build Coastguard Worker self._leader_cost = leader_cost 597*cfb92d14SAndroid Build Coastguard Worker self._id_sequence = id_sequence 598*cfb92d14SAndroid Build Coastguard Worker self._active_routers = active_routers 599*cfb92d14SAndroid Build Coastguard Worker self._sed_buffer_size = sed_buffer_size 600*cfb92d14SAndroid Build Coastguard Worker self._sed_datagram_count = sed_datagram_count 601*cfb92d14SAndroid Build Coastguard Worker 602*cfb92d14SAndroid Build Coastguard Worker @property 603*cfb92d14SAndroid Build Coastguard Worker def pp_byte(self): 604*cfb92d14SAndroid Build Coastguard Worker return self._pp_byte 605*cfb92d14SAndroid Build Coastguard Worker 606*cfb92d14SAndroid Build Coastguard Worker @property 607*cfb92d14SAndroid Build Coastguard Worker def pp(self): 608*cfb92d14SAndroid Build Coastguard Worker return common.map_pp(self._pp_byte) 609*cfb92d14SAndroid Build Coastguard Worker 610*cfb92d14SAndroid Build Coastguard Worker @property 611*cfb92d14SAndroid Build Coastguard Worker def link_quality_3(self): 612*cfb92d14SAndroid Build Coastguard Worker return self._link_quality_3 613*cfb92d14SAndroid Build Coastguard Worker 614*cfb92d14SAndroid Build Coastguard Worker @property 615*cfb92d14SAndroid Build Coastguard Worker def link_quality_2(self): 616*cfb92d14SAndroid Build Coastguard Worker return self._link_quality_2 617*cfb92d14SAndroid Build Coastguard Worker 618*cfb92d14SAndroid Build Coastguard Worker @property 619*cfb92d14SAndroid Build Coastguard Worker def link_quality_1(self): 620*cfb92d14SAndroid Build Coastguard Worker return self._link_quality_1 621*cfb92d14SAndroid Build Coastguard Worker 622*cfb92d14SAndroid Build Coastguard Worker @property 623*cfb92d14SAndroid Build Coastguard Worker def leader_cost(self): 624*cfb92d14SAndroid Build Coastguard Worker return self._leader_cost 625*cfb92d14SAndroid Build Coastguard Worker 626*cfb92d14SAndroid Build Coastguard Worker @property 627*cfb92d14SAndroid Build Coastguard Worker def id_sequence(self): 628*cfb92d14SAndroid Build Coastguard Worker return self._id_sequence 629*cfb92d14SAndroid Build Coastguard Worker 630*cfb92d14SAndroid Build Coastguard Worker @property 631*cfb92d14SAndroid Build Coastguard Worker def active_routers(self): 632*cfb92d14SAndroid Build Coastguard Worker return self._active_routers 633*cfb92d14SAndroid Build Coastguard Worker 634*cfb92d14SAndroid Build Coastguard Worker @property 635*cfb92d14SAndroid Build Coastguard Worker def sed_buffer_size(self): 636*cfb92d14SAndroid Build Coastguard Worker return self._sed_buffer_size 637*cfb92d14SAndroid Build Coastguard Worker 638*cfb92d14SAndroid Build Coastguard Worker @property 639*cfb92d14SAndroid Build Coastguard Worker def sed_datagram_count(self): 640*cfb92d14SAndroid Build Coastguard Worker return self._sed_datagram_count 641*cfb92d14SAndroid Build Coastguard Worker 642*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 643*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 644*cfb92d14SAndroid Build Coastguard Worker 645*cfb92d14SAndroid Build Coastguard Worker return (self.pp == other.pp and self.link_quality_3 == other.link_quality_3 and 646*cfb92d14SAndroid Build Coastguard Worker self.link_quality_2 == other.link_quality_2 and self.link_quality_1 == other.link_quality_1 and 647*cfb92d14SAndroid Build Coastguard Worker self.leader_cost == other.leader_cost and self.id_sequence == other.id_sequence and 648*cfb92d14SAndroid Build Coastguard Worker self.active_routers == other.active_routers and self.sed_buffer_size == other.sed_buffer_size and 649*cfb92d14SAndroid Build Coastguard Worker self.sed_datagram_count == other.sed_datagram_count) 650*cfb92d14SAndroid Build Coastguard Worker 651*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 652*cfb92d14SAndroid Build Coastguard Worker return r"Connectivity(pp={}, \ 653*cfb92d14SAndroid Build Coastguard Worker link_quality_3={}, \ 654*cfb92d14SAndroid Build Coastguard Worker link_quality_2={}, \ 655*cfb92d14SAndroid Build Coastguard Worker link_quality_1={}, \ 656*cfb92d14SAndroid Build Coastguard Worker leader_cost={}, \ 657*cfb92d14SAndroid Build Coastguard Worker id_sequence={}, \ 658*cfb92d14SAndroid Build Coastguard Worker active_routers={}, \ 659*cfb92d14SAndroid Build Coastguard Worker sed_buffer_size={}, \ 660*cfb92d14SAndroid Build Coastguard Worker sed_datagram_count={})".format( 661*cfb92d14SAndroid Build Coastguard Worker self.pp, 662*cfb92d14SAndroid Build Coastguard Worker self.link_quality_3, 663*cfb92d14SAndroid Build Coastguard Worker self.link_quality_2, 664*cfb92d14SAndroid Build Coastguard Worker self.link_quality_1, 665*cfb92d14SAndroid Build Coastguard Worker self.leader_cost, 666*cfb92d14SAndroid Build Coastguard Worker self.id_sequence, 667*cfb92d14SAndroid Build Coastguard Worker self.active_routers, 668*cfb92d14SAndroid Build Coastguard Worker self.sed_buffer_size, 669*cfb92d14SAndroid Build Coastguard Worker self.sed_datagram_count, 670*cfb92d14SAndroid Build Coastguard Worker ) 671*cfb92d14SAndroid Build Coastguard Worker 672*cfb92d14SAndroid Build Coastguard Worker 673*cfb92d14SAndroid Build Coastguard Workerclass ConnectivityFactory: 674*cfb92d14SAndroid Build Coastguard Worker 675*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 676*cfb92d14SAndroid Build Coastguard Worker pp_byte = ord(data.read(1)) 677*cfb92d14SAndroid Build Coastguard Worker link_quality_3 = ord(data.read(1)) 678*cfb92d14SAndroid Build Coastguard Worker link_quality_2 = ord(data.read(1)) 679*cfb92d14SAndroid Build Coastguard Worker link_quality_1 = ord(data.read(1)) 680*cfb92d14SAndroid Build Coastguard Worker leader_cost = ord(data.read(1)) 681*cfb92d14SAndroid Build Coastguard Worker id_sequence = ord(data.read(1)) 682*cfb92d14SAndroid Build Coastguard Worker active_routers = ord(data.read(1)) 683*cfb92d14SAndroid Build Coastguard Worker 684*cfb92d14SAndroid Build Coastguard Worker sed_data = io.BytesIO(data.read(3)) 685*cfb92d14SAndroid Build Coastguard Worker 686*cfb92d14SAndroid Build Coastguard Worker if len(sed_data.getvalue()) > 0: 687*cfb92d14SAndroid Build Coastguard Worker sed_buffer_size = struct.unpack(">H", sed_data.read(2))[0] 688*cfb92d14SAndroid Build Coastguard Worker sed_datagram_count = ord(sed_data.read(1)) 689*cfb92d14SAndroid Build Coastguard Worker else: 690*cfb92d14SAndroid Build Coastguard Worker sed_buffer_size = None 691*cfb92d14SAndroid Build Coastguard Worker sed_datagram_count = None 692*cfb92d14SAndroid Build Coastguard Worker 693*cfb92d14SAndroid Build Coastguard Worker return Connectivity( 694*cfb92d14SAndroid Build Coastguard Worker pp_byte, 695*cfb92d14SAndroid Build Coastguard Worker link_quality_3, 696*cfb92d14SAndroid Build Coastguard Worker link_quality_2, 697*cfb92d14SAndroid Build Coastguard Worker link_quality_1, 698*cfb92d14SAndroid Build Coastguard Worker leader_cost, 699*cfb92d14SAndroid Build Coastguard Worker id_sequence, 700*cfb92d14SAndroid Build Coastguard Worker active_routers, 701*cfb92d14SAndroid Build Coastguard Worker sed_buffer_size, 702*cfb92d14SAndroid Build Coastguard Worker sed_datagram_count, 703*cfb92d14SAndroid Build Coastguard Worker ) 704*cfb92d14SAndroid Build Coastguard Worker 705*cfb92d14SAndroid Build Coastguard Worker 706*cfb92d14SAndroid Build Coastguard Workerclass LinkMargin(object): 707*cfb92d14SAndroid Build Coastguard Worker 708*cfb92d14SAndroid Build Coastguard Worker def __init__(self, link_margin): 709*cfb92d14SAndroid Build Coastguard Worker self._link_margin = link_margin 710*cfb92d14SAndroid Build Coastguard Worker 711*cfb92d14SAndroid Build Coastguard Worker @property 712*cfb92d14SAndroid Build Coastguard Worker def link_margin(self): 713*cfb92d14SAndroid Build Coastguard Worker return self._link_margin 714*cfb92d14SAndroid Build Coastguard Worker 715*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 716*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 717*cfb92d14SAndroid Build Coastguard Worker 718*cfb92d14SAndroid Build Coastguard Worker return self.link_margin == other.link_margin 719*cfb92d14SAndroid Build Coastguard Worker 720*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 721*cfb92d14SAndroid Build Coastguard Worker return "LinkMargin(link_margin={})".format(self.link_margin) 722*cfb92d14SAndroid Build Coastguard Worker 723*cfb92d14SAndroid Build Coastguard Worker 724*cfb92d14SAndroid Build Coastguard Workerclass LinkMarginFactory: 725*cfb92d14SAndroid Build Coastguard Worker 726*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 727*cfb92d14SAndroid Build Coastguard Worker link_margin = ord(data.read(1)) 728*cfb92d14SAndroid Build Coastguard Worker return LinkMargin(link_margin) 729*cfb92d14SAndroid Build Coastguard Worker 730*cfb92d14SAndroid Build Coastguard Worker 731*cfb92d14SAndroid Build Coastguard Workerclass Status(object): 732*cfb92d14SAndroid Build Coastguard Worker 733*cfb92d14SAndroid Build Coastguard Worker def __init__(self, status): 734*cfb92d14SAndroid Build Coastguard Worker self._status = status 735*cfb92d14SAndroid Build Coastguard Worker 736*cfb92d14SAndroid Build Coastguard Worker @property 737*cfb92d14SAndroid Build Coastguard Worker def status(self): 738*cfb92d14SAndroid Build Coastguard Worker return self._status 739*cfb92d14SAndroid Build Coastguard Worker 740*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 741*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 742*cfb92d14SAndroid Build Coastguard Worker 743*cfb92d14SAndroid Build Coastguard Worker return self.status == other.status 744*cfb92d14SAndroid Build Coastguard Worker 745*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 746*cfb92d14SAndroid Build Coastguard Worker return "Status(status={})".format(self.status) 747*cfb92d14SAndroid Build Coastguard Worker 748*cfb92d14SAndroid Build Coastguard Worker 749*cfb92d14SAndroid Build Coastguard Workerclass StatusFactory: 750*cfb92d14SAndroid Build Coastguard Worker 751*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 752*cfb92d14SAndroid Build Coastguard Worker status = ord(data.read(1)) 753*cfb92d14SAndroid Build Coastguard Worker return Status(status) 754*cfb92d14SAndroid Build Coastguard Worker 755*cfb92d14SAndroid Build Coastguard Worker 756*cfb92d14SAndroid Build Coastguard Workerclass Version(object): 757*cfb92d14SAndroid Build Coastguard Worker 758*cfb92d14SAndroid Build Coastguard Worker def __init__(self, version): 759*cfb92d14SAndroid Build Coastguard Worker self._version = version 760*cfb92d14SAndroid Build Coastguard Worker 761*cfb92d14SAndroid Build Coastguard Worker @property 762*cfb92d14SAndroid Build Coastguard Worker def version(self): 763*cfb92d14SAndroid Build Coastguard Worker return self._version 764*cfb92d14SAndroid Build Coastguard Worker 765*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 766*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 767*cfb92d14SAndroid Build Coastguard Worker 768*cfb92d14SAndroid Build Coastguard Worker return self.version == other.version 769*cfb92d14SAndroid Build Coastguard Worker 770*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 771*cfb92d14SAndroid Build Coastguard Worker return "Version(version={})".format(self.version) 772*cfb92d14SAndroid Build Coastguard Worker 773*cfb92d14SAndroid Build Coastguard Worker 774*cfb92d14SAndroid Build Coastguard Workerclass VersionFactory: 775*cfb92d14SAndroid Build Coastguard Worker 776*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 777*cfb92d14SAndroid Build Coastguard Worker version = struct.unpack(">H", data.read(2))[0] 778*cfb92d14SAndroid Build Coastguard Worker return Version(version) 779*cfb92d14SAndroid Build Coastguard Worker 780*cfb92d14SAndroid Build Coastguard Worker 781*cfb92d14SAndroid Build Coastguard Workerclass AddressFull(object): 782*cfb92d14SAndroid Build Coastguard Worker 783*cfb92d14SAndroid Build Coastguard Worker def __init__(self, ipv6_address): 784*cfb92d14SAndroid Build Coastguard Worker self._ipv6_address = ipv6_address 785*cfb92d14SAndroid Build Coastguard Worker 786*cfb92d14SAndroid Build Coastguard Worker @property 787*cfb92d14SAndroid Build Coastguard Worker def ipv6_address(self): 788*cfb92d14SAndroid Build Coastguard Worker return self._ipv6_address 789*cfb92d14SAndroid Build Coastguard Worker 790*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 791*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 792*cfb92d14SAndroid Build Coastguard Worker 793*cfb92d14SAndroid Build Coastguard Worker return self.ipv6_address == other.ipv6_address 794*cfb92d14SAndroid Build Coastguard Worker 795*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 796*cfb92d14SAndroid Build Coastguard Worker return "AddressFull(ipv6_address={}')".format(hexlify(self.ipv6_address)) 797*cfb92d14SAndroid Build Coastguard Worker 798*cfb92d14SAndroid Build Coastguard Worker 799*cfb92d14SAndroid Build Coastguard Workerclass AddressFullFactory: 800*cfb92d14SAndroid Build Coastguard Worker 801*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 802*cfb92d14SAndroid Build Coastguard Worker data.read(1) # first byte is ignored 803*cfb92d14SAndroid Build Coastguard Worker ipv6_address = data.read(16) 804*cfb92d14SAndroid Build Coastguard Worker return AddressFull(ipv6_address) 805*cfb92d14SAndroid Build Coastguard Worker 806*cfb92d14SAndroid Build Coastguard Worker 807*cfb92d14SAndroid Build Coastguard Workerclass AddressCompressed(object): 808*cfb92d14SAndroid Build Coastguard Worker 809*cfb92d14SAndroid Build Coastguard Worker def __init__(self, cid, iid): 810*cfb92d14SAndroid Build Coastguard Worker self._cid = cid 811*cfb92d14SAndroid Build Coastguard Worker self._iid = iid 812*cfb92d14SAndroid Build Coastguard Worker 813*cfb92d14SAndroid Build Coastguard Worker @property 814*cfb92d14SAndroid Build Coastguard Worker def cid(self): 815*cfb92d14SAndroid Build Coastguard Worker return self._cid 816*cfb92d14SAndroid Build Coastguard Worker 817*cfb92d14SAndroid Build Coastguard Worker @property 818*cfb92d14SAndroid Build Coastguard Worker def iid(self): 819*cfb92d14SAndroid Build Coastguard Worker return self._iid 820*cfb92d14SAndroid Build Coastguard Worker 821*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 822*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 823*cfb92d14SAndroid Build Coastguard Worker 824*cfb92d14SAndroid Build Coastguard Worker return self.cid == other.cid and self.iid == other.iid 825*cfb92d14SAndroid Build Coastguard Worker 826*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 827*cfb92d14SAndroid Build Coastguard Worker return "AddressCompressed(cid={}, iid={}')".format(self.cid, hexlify(self.iid)) 828*cfb92d14SAndroid Build Coastguard Worker 829*cfb92d14SAndroid Build Coastguard Worker 830*cfb92d14SAndroid Build Coastguard Workerclass AddressCompressedFactory: 831*cfb92d14SAndroid Build Coastguard Worker 832*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 833*cfb92d14SAndroid Build Coastguard Worker cid = ord(data.read(1)) & 0x0F 834*cfb92d14SAndroid Build Coastguard Worker iid = bytearray(data.read(8)) 835*cfb92d14SAndroid Build Coastguard Worker return AddressCompressed(cid, iid) 836*cfb92d14SAndroid Build Coastguard Worker 837*cfb92d14SAndroid Build Coastguard Worker 838*cfb92d14SAndroid Build Coastguard Workerclass AddressRegistration(object): 839*cfb92d14SAndroid Build Coastguard Worker 840*cfb92d14SAndroid Build Coastguard Worker def __init__(self, addresses): 841*cfb92d14SAndroid Build Coastguard Worker self._addresses = addresses 842*cfb92d14SAndroid Build Coastguard Worker 843*cfb92d14SAndroid Build Coastguard Worker @property 844*cfb92d14SAndroid Build Coastguard Worker def addresses(self): 845*cfb92d14SAndroid Build Coastguard Worker return self._addresses 846*cfb92d14SAndroid Build Coastguard Worker 847*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 848*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 849*cfb92d14SAndroid Build Coastguard Worker 850*cfb92d14SAndroid Build Coastguard Worker return self.addresses == other.addresses 851*cfb92d14SAndroid Build Coastguard Worker 852*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 853*cfb92d14SAndroid Build Coastguard Worker addresses_str = ", ".join(["{}".format(address) for address in self.addresses]) 854*cfb92d14SAndroid Build Coastguard Worker return "AddressRegistration(addresses=[{}])".format(addresses_str) 855*cfb92d14SAndroid Build Coastguard Worker 856*cfb92d14SAndroid Build Coastguard Worker 857*cfb92d14SAndroid Build Coastguard Workerclass AddressRegistrationFactory: 858*cfb92d14SAndroid Build Coastguard Worker 859*cfb92d14SAndroid Build Coastguard Worker def __init__(self, addr_compressed_factory, addr_full_factory): 860*cfb92d14SAndroid Build Coastguard Worker self._addr_compressed_factory = addr_compressed_factory 861*cfb92d14SAndroid Build Coastguard Worker self._addr_full_factory = addr_full_factory 862*cfb92d14SAndroid Build Coastguard Worker 863*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 864*cfb92d14SAndroid Build Coastguard Worker addresses = [] 865*cfb92d14SAndroid Build Coastguard Worker 866*cfb92d14SAndroid Build Coastguard Worker while data.tell() < len(data.getvalue()): 867*cfb92d14SAndroid Build Coastguard Worker compressed = (ord(data.read(1)) >> 7) & 0x01 868*cfb92d14SAndroid Build Coastguard Worker data.seek(-1, io.SEEK_CUR) 869*cfb92d14SAndroid Build Coastguard Worker 870*cfb92d14SAndroid Build Coastguard Worker if compressed: 871*cfb92d14SAndroid Build Coastguard Worker addresses.append(self._addr_compressed_factory.parse(data, message_info)) 872*cfb92d14SAndroid Build Coastguard Worker else: 873*cfb92d14SAndroid Build Coastguard Worker addresses.append(self._addr_full_factory.parse(data, message_info)) 874*cfb92d14SAndroid Build Coastguard Worker 875*cfb92d14SAndroid Build Coastguard Worker return AddressRegistration(addresses) 876*cfb92d14SAndroid Build Coastguard Worker 877*cfb92d14SAndroid Build Coastguard Worker 878*cfb92d14SAndroid Build Coastguard Workerclass Channel(object): 879*cfb92d14SAndroid Build Coastguard Worker 880*cfb92d14SAndroid Build Coastguard Worker def __init__(self, channel_page, channel): 881*cfb92d14SAndroid Build Coastguard Worker self._channel_page = channel_page 882*cfb92d14SAndroid Build Coastguard Worker self._channel = channel 883*cfb92d14SAndroid Build Coastguard Worker 884*cfb92d14SAndroid Build Coastguard Worker @property 885*cfb92d14SAndroid Build Coastguard Worker def channel_page(self): 886*cfb92d14SAndroid Build Coastguard Worker return self._channel_page 887*cfb92d14SAndroid Build Coastguard Worker 888*cfb92d14SAndroid Build Coastguard Worker @property 889*cfb92d14SAndroid Build Coastguard Worker def channel(self): 890*cfb92d14SAndroid Build Coastguard Worker return self._channel 891*cfb92d14SAndroid Build Coastguard Worker 892*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 893*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 894*cfb92d14SAndroid Build Coastguard Worker 895*cfb92d14SAndroid Build Coastguard Worker return (self.channel_page == other.channel_page and self.channel == other.channel) 896*cfb92d14SAndroid Build Coastguard Worker 897*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 898*cfb92d14SAndroid Build Coastguard Worker return "Channel(channel_page={}, channel={})".format(self.channel_page, self.channel) 899*cfb92d14SAndroid Build Coastguard Worker 900*cfb92d14SAndroid Build Coastguard Worker 901*cfb92d14SAndroid Build Coastguard Workerclass ChannelFactory: 902*cfb92d14SAndroid Build Coastguard Worker 903*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 904*cfb92d14SAndroid Build Coastguard Worker channel_page = ord(data.read(1)) 905*cfb92d14SAndroid Build Coastguard Worker channel = struct.unpack(">H", data.read(2))[0] 906*cfb92d14SAndroid Build Coastguard Worker return Channel(channel_page, channel) 907*cfb92d14SAndroid Build Coastguard Worker 908*cfb92d14SAndroid Build Coastguard Worker 909*cfb92d14SAndroid Build Coastguard Workerclass PanId: 910*cfb92d14SAndroid Build Coastguard Worker 911*cfb92d14SAndroid Build Coastguard Worker def __init__(self, pan_id): 912*cfb92d14SAndroid Build Coastguard Worker self._pan_id = pan_id 913*cfb92d14SAndroid Build Coastguard Worker 914*cfb92d14SAndroid Build Coastguard Worker @property 915*cfb92d14SAndroid Build Coastguard Worker def pan_id(self): 916*cfb92d14SAndroid Build Coastguard Worker return self._pan_id 917*cfb92d14SAndroid Build Coastguard Worker 918*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 919*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 920*cfb92d14SAndroid Build Coastguard Worker 921*cfb92d14SAndroid Build Coastguard Worker return self.pan_id == other.pan_id 922*cfb92d14SAndroid Build Coastguard Worker 923*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 924*cfb92d14SAndroid Build Coastguard Worker return "PanId(pan_id={})".format(self.pan_id) 925*cfb92d14SAndroid Build Coastguard Worker 926*cfb92d14SAndroid Build Coastguard Worker 927*cfb92d14SAndroid Build Coastguard Workerclass PanIdFactory: 928*cfb92d14SAndroid Build Coastguard Worker 929*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 930*cfb92d14SAndroid Build Coastguard Worker pan_id = struct.unpack(">H", data.read(2))[0] 931*cfb92d14SAndroid Build Coastguard Worker return PanId(pan_id) 932*cfb92d14SAndroid Build Coastguard Worker 933*cfb92d14SAndroid Build Coastguard Worker 934*cfb92d14SAndroid Build Coastguard Workerclass ActiveTimestamp(object): 935*cfb92d14SAndroid Build Coastguard Worker 936*cfb92d14SAndroid Build Coastguard Worker def __init__(self, timestamp_seconds, timestamp_ticks, u): 937*cfb92d14SAndroid Build Coastguard Worker self._timestamp_seconds = timestamp_seconds 938*cfb92d14SAndroid Build Coastguard Worker self._timestamp_ticks = timestamp_ticks 939*cfb92d14SAndroid Build Coastguard Worker self._u = u 940*cfb92d14SAndroid Build Coastguard Worker 941*cfb92d14SAndroid Build Coastguard Worker @property 942*cfb92d14SAndroid Build Coastguard Worker def timestamp_seconds(self): 943*cfb92d14SAndroid Build Coastguard Worker return self._timestamp_seconds 944*cfb92d14SAndroid Build Coastguard Worker 945*cfb92d14SAndroid Build Coastguard Worker @property 946*cfb92d14SAndroid Build Coastguard Worker def timestamp_ticks(self): 947*cfb92d14SAndroid Build Coastguard Worker return self._timestamp_ticks 948*cfb92d14SAndroid Build Coastguard Worker 949*cfb92d14SAndroid Build Coastguard Worker @property 950*cfb92d14SAndroid Build Coastguard Worker def u(self): 951*cfb92d14SAndroid Build Coastguard Worker return self._u 952*cfb92d14SAndroid Build Coastguard Worker 953*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 954*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 955*cfb92d14SAndroid Build Coastguard Worker 956*cfb92d14SAndroid Build Coastguard Worker return (self.timestamp_seconds == other.timestamp_seconds and self.timestamp_ticks == other.timestamp_ticks and 957*cfb92d14SAndroid Build Coastguard Worker self.u == other.u) 958*cfb92d14SAndroid Build Coastguard Worker 959*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 960*cfb92d14SAndroid Build Coastguard Worker return "ActiveTimestamp(timestamp_seconds={}, timestamp_ticks={}, u={})".format( 961*cfb92d14SAndroid Build Coastguard Worker self.timestamp_seconds, self.timestamp_ticks, self.u) 962*cfb92d14SAndroid Build Coastguard Worker 963*cfb92d14SAndroid Build Coastguard Worker 964*cfb92d14SAndroid Build Coastguard Workerclass ActiveTimestampFactory: 965*cfb92d14SAndroid Build Coastguard Worker 966*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 967*cfb92d14SAndroid Build Coastguard Worker seconds = bytearray([0x00, 0x00]) + bytearray(data.read(6)) 968*cfb92d14SAndroid Build Coastguard Worker ticks = struct.unpack(">H", data.read(2))[0] 969*cfb92d14SAndroid Build Coastguard Worker 970*cfb92d14SAndroid Build Coastguard Worker timestamp_seconds = struct.unpack(">Q", bytes(seconds))[0] 971*cfb92d14SAndroid Build Coastguard Worker timestamp_ticks = ticks >> 1 972*cfb92d14SAndroid Build Coastguard Worker u = ticks & 0x01 973*cfb92d14SAndroid Build Coastguard Worker return ActiveTimestamp(timestamp_seconds, timestamp_ticks, u) 974*cfb92d14SAndroid Build Coastguard Worker 975*cfb92d14SAndroid Build Coastguard Worker 976*cfb92d14SAndroid Build Coastguard Workerclass PendingTimestamp(object): 977*cfb92d14SAndroid Build Coastguard Worker 978*cfb92d14SAndroid Build Coastguard Worker def __init__(self, timestamp_seconds, timestamp_ticks, u): 979*cfb92d14SAndroid Build Coastguard Worker self._timestamp_seconds = timestamp_seconds 980*cfb92d14SAndroid Build Coastguard Worker self._timestamp_ticks = timestamp_ticks 981*cfb92d14SAndroid Build Coastguard Worker self._u = u 982*cfb92d14SAndroid Build Coastguard Worker 983*cfb92d14SAndroid Build Coastguard Worker @property 984*cfb92d14SAndroid Build Coastguard Worker def timestamp_seconds(self): 985*cfb92d14SAndroid Build Coastguard Worker return self._timestamp_seconds 986*cfb92d14SAndroid Build Coastguard Worker 987*cfb92d14SAndroid Build Coastguard Worker @property 988*cfb92d14SAndroid Build Coastguard Worker def timestamp_ticks(self): 989*cfb92d14SAndroid Build Coastguard Worker return self._timestamp_ticks 990*cfb92d14SAndroid Build Coastguard Worker 991*cfb92d14SAndroid Build Coastguard Worker @property 992*cfb92d14SAndroid Build Coastguard Worker def u(self): 993*cfb92d14SAndroid Build Coastguard Worker return self._u 994*cfb92d14SAndroid Build Coastguard Worker 995*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 996*cfb92d14SAndroid Build Coastguard Worker common.expect_the_same_class(self, other) 997*cfb92d14SAndroid Build Coastguard Worker 998*cfb92d14SAndroid Build Coastguard Worker return (self.timestamp_seconds == other.timestamp_seconds and self.timestamp_ticks == other.timestamp_ticks and 999*cfb92d14SAndroid Build Coastguard Worker self.u == other.u) 1000*cfb92d14SAndroid Build Coastguard Worker 1001*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 1002*cfb92d14SAndroid Build Coastguard Worker return "PendingTimestamp(timestamp_seconds={}, timestamp_ticks={}, u={})".format( 1003*cfb92d14SAndroid Build Coastguard Worker self.timestamp_seconds, self.timestamp_ticks, self.u) 1004*cfb92d14SAndroid Build Coastguard Worker 1005*cfb92d14SAndroid Build Coastguard Worker 1006*cfb92d14SAndroid Build Coastguard Workerclass PendingTimestampFactory: 1007*cfb92d14SAndroid Build Coastguard Worker 1008*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1009*cfb92d14SAndroid Build Coastguard Worker seconds = bytearray([0x00, 0x00]) + bytearray(data.read(6)) 1010*cfb92d14SAndroid Build Coastguard Worker ticks = struct.unpack(">H", data.read(2))[0] 1011*cfb92d14SAndroid Build Coastguard Worker 1012*cfb92d14SAndroid Build Coastguard Worker timestamp_seconds = struct.unpack(">Q", bytes(seconds))[0] 1013*cfb92d14SAndroid Build Coastguard Worker timestamp_ticks = ticks >> 1 1014*cfb92d14SAndroid Build Coastguard Worker u = ticks & 0x01 1015*cfb92d14SAndroid Build Coastguard Worker return PendingTimestamp(timestamp_seconds, timestamp_ticks, u) 1016*cfb92d14SAndroid Build Coastguard Worker 1017*cfb92d14SAndroid Build Coastguard Worker 1018*cfb92d14SAndroid Build Coastguard Workerclass ActiveOperationalDataset: 1019*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1020*cfb92d14SAndroid Build Coastguard Worker 1021*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1022*cfb92d14SAndroid Build Coastguard Worker print("ActiveOperationalDataset is not implemented yet.") 1023*cfb92d14SAndroid Build Coastguard Worker 1024*cfb92d14SAndroid Build Coastguard Worker 1025*cfb92d14SAndroid Build Coastguard Workerclass ActiveOperationalDatasetFactory: 1026*cfb92d14SAndroid Build Coastguard Worker 1027*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1028*cfb92d14SAndroid Build Coastguard Worker return ActiveOperationalDataset() 1029*cfb92d14SAndroid Build Coastguard Worker 1030*cfb92d14SAndroid Build Coastguard Worker 1031*cfb92d14SAndroid Build Coastguard Workerclass PendingOperationalDataset: 1032*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1033*cfb92d14SAndroid Build Coastguard Worker 1034*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1035*cfb92d14SAndroid Build Coastguard Worker print("PendingOperationalDataset is not implemented yet.") 1036*cfb92d14SAndroid Build Coastguard Worker 1037*cfb92d14SAndroid Build Coastguard Worker 1038*cfb92d14SAndroid Build Coastguard Workerclass PendingOperationalDatasetFactory: 1039*cfb92d14SAndroid Build Coastguard Worker 1040*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1041*cfb92d14SAndroid Build Coastguard Worker return PendingOperationalDataset() 1042*cfb92d14SAndroid Build Coastguard Worker 1043*cfb92d14SAndroid Build Coastguard Worker 1044*cfb92d14SAndroid Build Coastguard Workerclass ThreadDiscovery(object): 1045*cfb92d14SAndroid Build Coastguard Worker 1046*cfb92d14SAndroid Build Coastguard Worker def __init__(self, tlvs): 1047*cfb92d14SAndroid Build Coastguard Worker self._tlvs = tlvs 1048*cfb92d14SAndroid Build Coastguard Worker 1049*cfb92d14SAndroid Build Coastguard Worker @property 1050*cfb92d14SAndroid Build Coastguard Worker def tlvs(self): 1051*cfb92d14SAndroid Build Coastguard Worker return self._tlvs 1052*cfb92d14SAndroid Build Coastguard Worker 1053*cfb92d14SAndroid Build Coastguard Worker def __eq__(self, other): 1054*cfb92d14SAndroid Build Coastguard Worker return self.tlvs == other.tlvs 1055*cfb92d14SAndroid Build Coastguard Worker 1056*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 1057*cfb92d14SAndroid Build Coastguard Worker return "ThreadDiscovery(tlvs={})".format(self.tlvs) 1058*cfb92d14SAndroid Build Coastguard Worker 1059*cfb92d14SAndroid Build Coastguard Worker 1060*cfb92d14SAndroid Build Coastguard Workerclass ThreadDiscoveryFactory: 1061*cfb92d14SAndroid Build Coastguard Worker 1062*cfb92d14SAndroid Build Coastguard Worker def __init__(self, thread_discovery_tlvs_factory): 1063*cfb92d14SAndroid Build Coastguard Worker self._tlvs_factory = thread_discovery_tlvs_factory 1064*cfb92d14SAndroid Build Coastguard Worker 1065*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1066*cfb92d14SAndroid Build Coastguard Worker tlvs = self._tlvs_factory.parse(data, message_info) 1067*cfb92d14SAndroid Build Coastguard Worker return ThreadDiscovery(tlvs) 1068*cfb92d14SAndroid Build Coastguard Worker 1069*cfb92d14SAndroid Build Coastguard Worker 1070*cfb92d14SAndroid Build Coastguard Workerclass CslChannel: 1071*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1072*cfb92d14SAndroid Build Coastguard Worker 1073*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1074*cfb92d14SAndroid Build Coastguard Worker print("CslChannel is not implemented yet.") 1075*cfb92d14SAndroid Build Coastguard Worker 1076*cfb92d14SAndroid Build Coastguard Worker 1077*cfb92d14SAndroid Build Coastguard Workerclass CslChannelFactory: 1078*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1079*cfb92d14SAndroid Build Coastguard Worker 1080*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1081*cfb92d14SAndroid Build Coastguard Worker return CslChannel() 1082*cfb92d14SAndroid Build Coastguard Worker 1083*cfb92d14SAndroid Build Coastguard Worker 1084*cfb92d14SAndroid Build Coastguard Workerclass CslSynchronizedTimeout: 1085*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1086*cfb92d14SAndroid Build Coastguard Worker 1087*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1088*cfb92d14SAndroid Build Coastguard Worker print("CslSynchronizedTimeout is not implemented yet.") 1089*cfb92d14SAndroid Build Coastguard Worker 1090*cfb92d14SAndroid Build Coastguard Worker 1091*cfb92d14SAndroid Build Coastguard Workerclass CslSynchronizedTimeoutFactory: 1092*cfb92d14SAndroid Build Coastguard Worker 1093*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1094*cfb92d14SAndroid Build Coastguard Worker return CslSynchronizedTimeout() 1095*cfb92d14SAndroid Build Coastguard Worker 1096*cfb92d14SAndroid Build Coastguard Worker 1097*cfb92d14SAndroid Build Coastguard Workerclass CslClockAccuracy: 1098*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1099*cfb92d14SAndroid Build Coastguard Worker 1100*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1101*cfb92d14SAndroid Build Coastguard Worker print("CslClockAccuracy is not implemented yet.") 1102*cfb92d14SAndroid Build Coastguard Worker 1103*cfb92d14SAndroid Build Coastguard Worker 1104*cfb92d14SAndroid Build Coastguard Workerclass CslClockAccuracyFactory: 1105*cfb92d14SAndroid Build Coastguard Worker 1106*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1107*cfb92d14SAndroid Build Coastguard Worker return CslClockAccuracy() 1108*cfb92d14SAndroid Build Coastguard Worker 1109*cfb92d14SAndroid Build Coastguard Worker 1110*cfb92d14SAndroid Build Coastguard Workerclass TimeRequest: 1111*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1112*cfb92d14SAndroid Build Coastguard Worker 1113*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1114*cfb92d14SAndroid Build Coastguard Worker print("TimeRequest is not implemented yet.") 1115*cfb92d14SAndroid Build Coastguard Worker 1116*cfb92d14SAndroid Build Coastguard Worker 1117*cfb92d14SAndroid Build Coastguard Workerclass TimeRequestFactory: 1118*cfb92d14SAndroid Build Coastguard Worker 1119*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1120*cfb92d14SAndroid Build Coastguard Worker return TimeRequest() 1121*cfb92d14SAndroid Build Coastguard Worker 1122*cfb92d14SAndroid Build Coastguard Worker 1123*cfb92d14SAndroid Build Coastguard Workerclass TimeParameter: 1124*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1125*cfb92d14SAndroid Build Coastguard Worker 1126*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1127*cfb92d14SAndroid Build Coastguard Worker print("TimeParameter is not implemented yet.") 1128*cfb92d14SAndroid Build Coastguard Worker 1129*cfb92d14SAndroid Build Coastguard Worker 1130*cfb92d14SAndroid Build Coastguard Workerclass TimeParameterFactory: 1131*cfb92d14SAndroid Build Coastguard Worker 1132*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1133*cfb92d14SAndroid Build Coastguard Worker return TimeParameter() 1134*cfb92d14SAndroid Build Coastguard Worker 1135*cfb92d14SAndroid Build Coastguard Worker 1136*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsQuery: 1137*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1138*cfb92d14SAndroid Build Coastguard Worker 1139*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1140*cfb92d14SAndroid Build Coastguard Worker print("LinkMetricsQuery is not implemented yet.") 1141*cfb92d14SAndroid Build Coastguard Worker 1142*cfb92d14SAndroid Build Coastguard Worker 1143*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsQueryFactory: 1144*cfb92d14SAndroid Build Coastguard Worker 1145*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1146*cfb92d14SAndroid Build Coastguard Worker return LinkMetricsQuery() 1147*cfb92d14SAndroid Build Coastguard Worker 1148*cfb92d14SAndroid Build Coastguard Worker 1149*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsManagement: 1150*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1151*cfb92d14SAndroid Build Coastguard Worker 1152*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1153*cfb92d14SAndroid Build Coastguard Worker print("LinkMetricsManagement is not implemented yet.") 1154*cfb92d14SAndroid Build Coastguard Worker 1155*cfb92d14SAndroid Build Coastguard Worker 1156*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsManagementFactory: 1157*cfb92d14SAndroid Build Coastguard Worker 1158*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1159*cfb92d14SAndroid Build Coastguard Worker return LinkMetricsManagement() 1160*cfb92d14SAndroid Build Coastguard Worker 1161*cfb92d14SAndroid Build Coastguard Worker 1162*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsReport: 1163*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1164*cfb92d14SAndroid Build Coastguard Worker 1165*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1166*cfb92d14SAndroid Build Coastguard Worker print("LinkMetricsReport is not implemented yet.") 1167*cfb92d14SAndroid Build Coastguard Worker 1168*cfb92d14SAndroid Build Coastguard Worker 1169*cfb92d14SAndroid Build Coastguard Workerclass LinkMetricsReportFactory: 1170*cfb92d14SAndroid Build Coastguard Worker 1171*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1172*cfb92d14SAndroid Build Coastguard Worker return LinkMetricsReport() 1173*cfb92d14SAndroid Build Coastguard Worker 1174*cfb92d14SAndroid Build Coastguard Worker 1175*cfb92d14SAndroid Build Coastguard Workerclass LinkProbe: 1176*cfb92d14SAndroid Build Coastguard Worker # TODO: Not implemented yet 1177*cfb92d14SAndroid Build Coastguard Worker 1178*cfb92d14SAndroid Build Coastguard Worker def __init__(self): 1179*cfb92d14SAndroid Build Coastguard Worker print("LinkProbe is not implemented yet.") 1180*cfb92d14SAndroid Build Coastguard Worker 1181*cfb92d14SAndroid Build Coastguard Worker 1182*cfb92d14SAndroid Build Coastguard Workerclass LinkProbeFactory: 1183*cfb92d14SAndroid Build Coastguard Worker 1184*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1185*cfb92d14SAndroid Build Coastguard Worker return LinkProbe() 1186*cfb92d14SAndroid Build Coastguard Worker 1187*cfb92d14SAndroid Build Coastguard Worker 1188*cfb92d14SAndroid Build Coastguard Workerclass MleCommand(object): 1189*cfb92d14SAndroid Build Coastguard Worker 1190*cfb92d14SAndroid Build Coastguard Worker def __init__(self, _type, tlvs): 1191*cfb92d14SAndroid Build Coastguard Worker self._type = _type 1192*cfb92d14SAndroid Build Coastguard Worker self._tlvs = tlvs 1193*cfb92d14SAndroid Build Coastguard Worker 1194*cfb92d14SAndroid Build Coastguard Worker @property 1195*cfb92d14SAndroid Build Coastguard Worker def type(self): 1196*cfb92d14SAndroid Build Coastguard Worker return self._type 1197*cfb92d14SAndroid Build Coastguard Worker 1198*cfb92d14SAndroid Build Coastguard Worker @property 1199*cfb92d14SAndroid Build Coastguard Worker def tlvs(self): 1200*cfb92d14SAndroid Build Coastguard Worker return self._tlvs 1201*cfb92d14SAndroid Build Coastguard Worker 1202*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 1203*cfb92d14SAndroid Build Coastguard Worker tlvs_str = ", ".join(["{}".format(tlv) for tlv in self.tlvs]) 1204*cfb92d14SAndroid Build Coastguard Worker return "MleCommand(type={}, tlvs=[{}])".format(self.type.name, tlvs_str) 1205*cfb92d14SAndroid Build Coastguard Worker 1206*cfb92d14SAndroid Build Coastguard Worker 1207*cfb92d14SAndroid Build Coastguard Workerclass MleCommandFactory: 1208*cfb92d14SAndroid Build Coastguard Worker 1209*cfb92d14SAndroid Build Coastguard Worker _MARKER_EXTENDED_LENGTH = 0xff 1210*cfb92d14SAndroid Build Coastguard Worker 1211*cfb92d14SAndroid Build Coastguard Worker def __init__(self, tlvs_factories): 1212*cfb92d14SAndroid Build Coastguard Worker self._tlvs_factories = tlvs_factories 1213*cfb92d14SAndroid Build Coastguard Worker 1214*cfb92d14SAndroid Build Coastguard Worker def _get_length(self, data): 1215*cfb92d14SAndroid Build Coastguard Worker length = ord(data.read(1)) 1216*cfb92d14SAndroid Build Coastguard Worker 1217*cfb92d14SAndroid Build Coastguard Worker if length == self._MARKER_EXTENDED_LENGTH: 1218*cfb92d14SAndroid Build Coastguard Worker length = struct.unpack(">H", data.read(2))[0] 1219*cfb92d14SAndroid Build Coastguard Worker 1220*cfb92d14SAndroid Build Coastguard Worker return length 1221*cfb92d14SAndroid Build Coastguard Worker 1222*cfb92d14SAndroid Build Coastguard Worker def _get_tlv_factory(self, _type): 1223*cfb92d14SAndroid Build Coastguard Worker try: 1224*cfb92d14SAndroid Build Coastguard Worker return self._tlvs_factories[_type] 1225*cfb92d14SAndroid Build Coastguard Worker except KeyError: 1226*cfb92d14SAndroid Build Coastguard Worker logging.error('Could not find TLV factory. Unsupported TLV type: {}'.format(_type)) 1227*cfb92d14SAndroid Build Coastguard Worker return UnknownTlvFactory(_type) 1228*cfb92d14SAndroid Build Coastguard Worker 1229*cfb92d14SAndroid Build Coastguard Worker def _parse_tlv(self, data, message_info): 1230*cfb92d14SAndroid Build Coastguard Worker _type = TlvType(ord(data.read(1))) 1231*cfb92d14SAndroid Build Coastguard Worker length = self._get_length(data) 1232*cfb92d14SAndroid Build Coastguard Worker value = data.read(length) 1233*cfb92d14SAndroid Build Coastguard Worker 1234*cfb92d14SAndroid Build Coastguard Worker factory = self._get_tlv_factory(_type) 1235*cfb92d14SAndroid Build Coastguard Worker 1236*cfb92d14SAndroid Build Coastguard Worker return factory.parse(io.BytesIO(value), message_info) 1237*cfb92d14SAndroid Build Coastguard Worker 1238*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1239*cfb92d14SAndroid Build Coastguard Worker cmd_type = CommandType(ord(data.read(1))) 1240*cfb92d14SAndroid Build Coastguard Worker tlvs = [] 1241*cfb92d14SAndroid Build Coastguard Worker 1242*cfb92d14SAndroid Build Coastguard Worker while data.tell() < len(data.getvalue()): 1243*cfb92d14SAndroid Build Coastguard Worker tlv = self._parse_tlv(data, message_info) 1244*cfb92d14SAndroid Build Coastguard Worker tlvs.append(tlv) 1245*cfb92d14SAndroid Build Coastguard Worker 1246*cfb92d14SAndroid Build Coastguard Worker return MleCommand(cmd_type, tlvs) 1247*cfb92d14SAndroid Build Coastguard Worker 1248*cfb92d14SAndroid Build Coastguard Worker 1249*cfb92d14SAndroid Build Coastguard Workerclass MleMessage(object): 1250*cfb92d14SAndroid Build Coastguard Worker 1251*cfb92d14SAndroid Build Coastguard Worker def __init__(self, command): 1252*cfb92d14SAndroid Build Coastguard Worker self._command = command 1253*cfb92d14SAndroid Build Coastguard Worker 1254*cfb92d14SAndroid Build Coastguard Worker @property 1255*cfb92d14SAndroid Build Coastguard Worker def command(self): 1256*cfb92d14SAndroid Build Coastguard Worker return self._command 1257*cfb92d14SAndroid Build Coastguard Worker 1258*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 1259*cfb92d14SAndroid Build Coastguard Worker return "MleMessage(command={})".format(self.command) 1260*cfb92d14SAndroid Build Coastguard Worker 1261*cfb92d14SAndroid Build Coastguard Worker 1262*cfb92d14SAndroid Build Coastguard Workerclass MleMessageSecured(MleMessage): 1263*cfb92d14SAndroid Build Coastguard Worker 1264*cfb92d14SAndroid Build Coastguard Worker def __init__(self, aux_sec_hdr, command, mic): 1265*cfb92d14SAndroid Build Coastguard Worker super(MleMessageSecured, self).__init__(command) 1266*cfb92d14SAndroid Build Coastguard Worker self._aux_sec_hdr = aux_sec_hdr 1267*cfb92d14SAndroid Build Coastguard Worker self._mic = mic 1268*cfb92d14SAndroid Build Coastguard Worker 1269*cfb92d14SAndroid Build Coastguard Worker @property 1270*cfb92d14SAndroid Build Coastguard Worker def aux_sec_hdr(self): 1271*cfb92d14SAndroid Build Coastguard Worker return self._aux_sec_hdr 1272*cfb92d14SAndroid Build Coastguard Worker 1273*cfb92d14SAndroid Build Coastguard Worker @property 1274*cfb92d14SAndroid Build Coastguard Worker def mic(self): 1275*cfb92d14SAndroid Build Coastguard Worker return self._mic 1276*cfb92d14SAndroid Build Coastguard Worker 1277*cfb92d14SAndroid Build Coastguard Worker def __repr__(self): 1278*cfb92d14SAndroid Build Coastguard Worker return "MleMessageSecured(aux_sec_hdr={}, command={}, mic=\"{}\")".format(self.aux_sec_hdr, self.command, 1279*cfb92d14SAndroid Build Coastguard Worker hexlify(self.mic)) 1280*cfb92d14SAndroid Build Coastguard Worker 1281*cfb92d14SAndroid Build Coastguard Worker 1282*cfb92d14SAndroid Build Coastguard Workerclass MleMessageFactory: 1283*cfb92d14SAndroid Build Coastguard Worker 1284*cfb92d14SAndroid Build Coastguard Worker def __init__(self, aux_sec_hdr_factory, mle_command_factory, crypto_engine): 1285*cfb92d14SAndroid Build Coastguard Worker self._aux_sec_hdr_factory = aux_sec_hdr_factory 1286*cfb92d14SAndroid Build Coastguard Worker self._mle_command_factory = mle_command_factory 1287*cfb92d14SAndroid Build Coastguard Worker self._crypto_engine = crypto_engine 1288*cfb92d14SAndroid Build Coastguard Worker 1289*cfb92d14SAndroid Build Coastguard Worker def _create_mle_secured_message(self, data, message_info): 1290*cfb92d14SAndroid Build Coastguard Worker aux_sec_hdr = self._aux_sec_hdr_factory.parse(data, message_info) 1291*cfb92d14SAndroid Build Coastguard Worker 1292*cfb92d14SAndroid Build Coastguard Worker enc_data_length = len(data.getvalue()) 1293*cfb92d14SAndroid Build Coastguard Worker 1294*cfb92d14SAndroid Build Coastguard Worker enc_data = bytearray(data.read(enc_data_length - data.tell() - self._crypto_engine.mic_length)) 1295*cfb92d14SAndroid Build Coastguard Worker mic = bytearray(data.read()) 1296*cfb92d14SAndroid Build Coastguard Worker 1297*cfb92d14SAndroid Build Coastguard Worker dec_data = self._crypto_engine.decrypt(enc_data, mic, message_info) 1298*cfb92d14SAndroid Build Coastguard Worker 1299*cfb92d14SAndroid Build Coastguard Worker command = self._mle_command_factory.parse(io.BytesIO(dec_data), message_info) 1300*cfb92d14SAndroid Build Coastguard Worker 1301*cfb92d14SAndroid Build Coastguard Worker return MleMessageSecured(aux_sec_hdr, command, mic) 1302*cfb92d14SAndroid Build Coastguard Worker 1303*cfb92d14SAndroid Build Coastguard Worker def _create_mle_message(self, data, message_info): 1304*cfb92d14SAndroid Build Coastguard Worker command = self._mle_command_factory.parse(data, message_info) 1305*cfb92d14SAndroid Build Coastguard Worker 1306*cfb92d14SAndroid Build Coastguard Worker return MleMessage(command) 1307*cfb92d14SAndroid Build Coastguard Worker 1308*cfb92d14SAndroid Build Coastguard Worker def parse(self, data, message_info): 1309*cfb92d14SAndroid Build Coastguard Worker security_indicator = ord(data.read(1)) 1310*cfb92d14SAndroid Build Coastguard Worker 1311*cfb92d14SAndroid Build Coastguard Worker if security_indicator == 0: 1312*cfb92d14SAndroid Build Coastguard Worker return self._create_mle_secured_message(data, message_info) 1313*cfb92d14SAndroid Build Coastguard Worker 1314*cfb92d14SAndroid Build Coastguard Worker elif security_indicator == 255: 1315*cfb92d14SAndroid Build Coastguard Worker return self._create_mle_message(data, message_info) 1316*cfb92d14SAndroid Build Coastguard Worker 1317*cfb92d14SAndroid Build Coastguard Worker else: 1318*cfb92d14SAndroid Build Coastguard Worker raise RuntimeError( 1319*cfb92d14SAndroid Build Coastguard Worker "Could not create MLE message. Unknown security indicator value: {}".format(security_indicator)) 1320