def decode(cls, mhdr, data): """Create a MACMessage object from binary representation. Args: mhdr (MACHeader): MAC header object. data (str): UDP packet data. Returns: A MACDataUplinkMessage object. """ # Message (PHYPayload) must be at least 6 bytes if len(data) < 6: raise DecodeError() # Decode message payload payload = MACPayload.decode(data[1:len(data)-4]) # Decode fopts MAC Commands commands = [] p = 0 while p < payload.fhdr.foptslen: c = MACCommand.decode(payload.fhdr.fopts[p:]) # We have no option except to break here if we fail to decode # a MAC command, as we have no way of advancing the pointer if c is None: break commands.append(c) p += c.length # Slice the MIC mic = struct.unpack('<L', data[len(data)-4:])[0] m = MACDataUplinkMessage(mhdr, payload, commands, mic) return m
def decode(cls, data): """Create a MACPayload object from binary representation. Args: data (str): MACPayload packet data. Returns: MACPayload object on success, None otherwise. """ # Payload must be at a minimum 1 byte, + 7 byte fhdr dlen = len(data) # TODO: check region specific length if dlen < 8: raise DecodeError() # Decode the frame header fhdr = FrameHeader.decode(data) # Check and decode fport fport = None frmpayload = None if dlen > fhdr.length: fport = struct.unpack('B', data[fhdr.length])[0] # Decode frmpayload if dlen > fhdr.length + 1: frmpayload = data[fhdr.length+1:] p = MACPayload(fhdr, fport, frmpayload) return p
def decode(cls, data): """Create a FrameHeader object from binary representation. Args: data (str): MACPayload packet data Returns: FrameHeader object on success, None otherwise. """ # FrameHeader must be at least 7 bytes if len(data) < 7: raise DecodeError() (devaddr, fctrl, fcnt) = struct.unpack('<LBH', data[:7]) # Decode fctrl field # ADR is bit 7 adr = (fctrl & 128) >> 7 # ADRackreq is bit 6 adrackreq = (fctrl & 64) >> 6 # ACK is bit 5 ack = (fctrl & 32) >> 5 # Foptslen = bits [3:0] foptslen = fctrl & 15 fopts = data[7:7+foptslen] fheader = FrameHeader(devaddr, adr, adrackreq, ack, foptslen, fcnt, fopts) return fheader
def decode(cls, mhdr, data): """Create a MACJoinRequestMessage object from binary representation. Args: mhdr (MACHeader): MAC header object. data (str): UDP packet data. Returns: JoinRequestMessage object on success, None otherwise. """ # Message (PHYPayload) must be 23 bytes if len(data) != 23: raise DecodeError() (appeui, deveui, devnonce, mic) = struct.unpack('<QQHL', data[1:]) m = JoinRequestMessage(mhdr, appeui, deveui, devnonce, mic) return m
def decode(cls, data): """Decode the message type. Args: data (str): UDP packet data. Returns: MACJoinMessage or MACDataMessage on success, None otherwise. """ # Message (PHYPayload) must be at least 1 byte if len(data) < 1: raise DecodeError() # Decode the MAC Header mhdr = MACHeader.decode(data[0]) # Decode the Message if mhdr.mtype == JOIN_REQUEST: return JoinRequestMessage.decode(mhdr, data) elif mhdr.mtype == UN_DATA_UP or mhdr.mtype == CO_DATA_UP: return MACDataUplinkMessage.decode(mhdr, data)