diff --git a/tpl-lorawan-prov.py b/tpl-lorawan-prov.py new file mode 100644 index 0000000..1ae8022 --- /dev/null +++ b/tpl-lorawan-prov.py @@ -0,0 +1,161 @@ + +import time +import serial +import binascii + +class TPLBirdySlim: + port = None + def __init__(self, serialPortName): + self.port = serial.Serial( + port=serialPortName, + baudrate=57600, + bytesize=serial.EIGHTBITS, + parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + timeout=30, + xonxoff=False, + rtscts=False, + dsrdtr=False + ) + print(self.port.name) + if self.port.is_open: + self.port.close() + self.port.open() + self.port.reset_input_buffer() + self.port.reset_output_buffer() + def _changeBaudrate(self, newRate): + if self.port.is_open: + self.port.close() + self.port.baudrate = newRate + self.port.open() + self.port.reset_input_buffer() + self.port.reset_output_buffer() + + def checksum(self, data): + cs = 0x00 + for x in data: + cs = (cs + x % 256) & 0xFF + return cs & 0xFF + def sendCMD(self, data): + cmd = [] + cmd.append(0x02) + cmd.append(len(data)) + cmd.extend(data) + cmd.append(0x03) + cmd.append(self.checksum(cmd.copy())) + cmd.append(0x04) + + print(">", binascii.hexlify(bytes(cmd))) + self.port.write(cmd) + self.port.flush() + def readSingleByte(self): + return int.from_bytes(self.port.read(1), 'little') + def wait4Response(self): + #first Byte is always 0x02 + if self.readSingleByte() != 0x02: + return None + dataLength = self.readSingleByte() + reply = [] + for x in range(dataLength): + reply.append(self.readSingleByte()) + + if self.readSingleByte() != 0x03: + return None + + pCRC = self.readSingleByte() + pCRCData = [0x02, dataLength] + pCRCData.extend(reply) + pCRCData.extend([0x03]) + rCRC = self.checksum(pCRCData) + if self.readSingleByte() != 0x04: + return None + if pCRC != rCRC: + return None # crc mismatch + return reply + + def askHighspeed(self): + self.sendCMD([0x25,0x01]) + return self.wait4Response() + def switchToHighspeed(self): + resp = self.askHighspeed() + if len(resp) == 1 and resp[0] == 0x06: + self._changeBaudrate(115200) + return True + else: + return False + def readE2P(self, addr, size=0x80): + _addr = addr.to_bytes(2, byteorder='big') + _cmd = [0x29, 0x00, 0x00, _addr[0], _addr[1], size] + self.sendCMD(_cmd) + resp = self.wait4Response() + print(">", binascii.hexlify(bytes(resp))) + if resp[0:5] != _cmd[0:5]: + print(resp[0:5], _cmd[0:5]) + return None # mismatch + return resp[5:] + def writeE2P(self, addr, data): + _addr = addr.to_bytes(2, byteorder='big') + _cmd = [0x2A, 0x00, 0x00, _addr[0], _addr[1]] + _cmd.extend(data) + self.sendCMD(_cmd) + resp = self.wait4Response() + if resp[0:4] != _cmd[0:4]: + print("resp mismatch", resp, _cmd) + return False # mismatch + if resp[5] != len(data): + print("length mismatch") + return False # mismatch + if resp[6:] != _cmd[5:]: + print("resp mismatch", resp, _cmd) + return False # mismatch + return True + #def boskrypt_mode(self): + # self.sendCMD([0xF3,0xF3]) + def getDeviceInfo(self): + self.sendCMD([0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff]) + return self.wait4Response() + def writeSerialNumber(self, newSerial): + _cmd = [0x13] + _cmd.extend(newSerial) + self.sendCMD(_cmd) + resp = self.wait4Response() + if _cmd[2:] != resp[2:]: + return False + return True + def checkE2PData(self, data): + return len(data) / 0x80 == 0xCD + + + +test = TPLBirdySlim('/dev/ttyUSB0') +#test.sendCMD([0x10,0x08]) + +test.sendCMD([0x01,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,]) +print(bytes(test.wait4Response())) + +test.sendCMD([0x12,]) # get Serial +print(bytes(test.wait4Response())) + +test.sendCMD([0xEF,]) # get CEIC? +print(bytes(test.wait4Response())) + +loraProvCMD = [0x2B, 0x00, 0x44,0x00 ] + +#abp try +AppEUI = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] +DevEUI = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] +AppKey = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ] + +AppSKey = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] +NwkSKey = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ] +DevAddr = [ 0x00, 0x00, 0x00, 0x00 ] + +loraProvCMD.extend(AppSKey) +loraProvCMD.extend(AppEUI) +loraProvCMD.extend(DevEUI) +loraProvCMD.extend(AppSKey) +loraProvCMD.extend(NwkSKey) +loraProvCMD.extend(DevAddr) + +test.sendCMD(loraProvCMD) +print(bytes(test.wait4Response())) \ No newline at end of file