/
pvvx
/
TLB2Z
Обзор
Документация
Войти
/
pvvx
/
TLB2Z
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/make/zigbee_ota.py
96 строк
3 KB
Victor
beta1 v0.1.0.6
19 фев 2026, 00:30
19 фев 2026, 00:30
6e5e039
Код
Авторство
О чём код?
#!/usr/bin/env python3 import argparse import binascii import os import struct OTA_MAGIC = b'\x5d\x02' def main(args): assert args.input_file != args.output hs = str.encode(args.header_string) if len(hs) > 31: print("Error: header_string size is too long!"); exit(2); with (open(args.input_file, 'rb')) as bin_file: bin_file.seek(0, 0) firmware = bytearray(bin_file.read(-1)) if firmware[6:8] != OTA_MAGIC: # Ensure FW size is multiple of 16 padding = 16 - len(firmware) % 16 if padding < 16: firmware += b'\xFF' * padding # Fix FW length firmware[0x18:0x1c] = (len(firmware) + 4).to_bytes(4, byteorder='little') # Add magic constant firmware[6:8] = OTA_MAGIC # Add CRC crc = binascii.crc32(firmware) ^ 0xffffffff firmware += crc.to_bytes(4, byteorder='little') ota_hdr_s = struct.Struct('<I5HIH32sI') header_size = 56 firmware_len = len(firmware) total_image_size = firmware_len + header_size + 6 manufacturer_code = args.manufacturer_id or int.from_bytes(firmware[18:20], byteorder='little') image_type = args.image_type or int.from_bytes(firmware[20:22], byteorder='little') file_version = args.file_version or int.from_bytes(firmware[2:6], byteorder='little') if len(hs) == 0: hs = str.encode('ZigbeeTLc B2Zdevice OTA') ota_hdr = ota_hdr_s.pack( 0xbeef11e, 0x100, # header version is 0x0100 header_size, 0, # ota_ext_hdr_value if ota_ext_hdr else 0, manufacturer_code, # args.manufacturer, image_type, # args.image_type, file_version, # options.File_Version 2, # options.stack_version, hs + b'\x00' * (32-len(hs)), #b'\x00' * 32, # OTA_Header_String.encode(), total_image_size, ) # add chunk header: 0 - firmware type ota_hdr += struct.pack('<HI', 0, firmware_len) out_filename = args.output if not out_filename: head, tail = os.path.split(args.input_file) if args.path: head = args.path if args.name: tail = args.name if args.output_title: name = args.output_title else: name, _ = os.path.splitext(tail) out_filename = os.path.join(head, '{:04x}-{:04x}-{:08x}-{}.zigbee'.format( manufacturer_code, image_type, file_version, name, )) with open(out_filename, 'wb') as output: bin_file.seek(0, 0) output.write(ota_hdr) output.write(firmware) print("%s was created with ZCL OTA Header." % out_filename) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument("input_file", help="input file") parser.add_argument("-t", '--output-title', help="replace original file name with the string") parser.add_argument("-o", '--output', help="output file") parser.add_argument("-p", '--path', help="path to output file") parser.add_argument("-n", '--name', help="short name output file") # parser.add_argument("-m", "--manufacturer_id", metavar="MANUFACTURER_ID", type=lambda x: int(x, 0), help="Manufacturer ID") parser.add_argument("-i", "--image_type", metavar="IMAGE_ID", type=lambda x: int(x, 0), help="Image ID") parser.add_argument("-v", "--file_version", metavar="VERSION", type=lambda x: int(x, 0), help="File version") parser.add_argument("-s", "--header_string", metavar="HEADER_STRING", type=str, default="", help="Header String") _args = parser.parse_args() main(_args)