rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | #!/usr/bin/env python
|
| 2 | # -*- coding: utf-8 -*
|
| 3 | try:
|
| 4 | import pyserial as serial
|
| 5 | import pyserial.tools.list_ports as ser_tools
|
| 6 | except ImportError:
|
| 7 | import serial
|
| 8 | import serial.tools.list_ports as ser_tools
|
| 9 | import sys, time, struct, logging
|
| 10 | from optparse import OptionParser
|
| 11 | try:
|
| 12 | # python2
|
| 13 | import ConfigParser as configparser
|
| 14 | except ImportError:
|
| 15 | # python3
|
| 16 | import configparser
|
| 17 |
|
| 18 | class Fbtool:
|
| 19 | def __init__(self, config_file, meid=False):
|
| 20 | self.TGT_CFG_SBC_EN = 0x00000001
|
| 21 | self.TGT_CFG_SLA_EN = 0x00000002
|
| 22 | self.TGT_CFG_DAA_EN = 0x00000004
|
| 23 | self.E_ERROR = 0x1000
|
| 24 | self.__ser = None
|
| 25 | self.__connect_type = 'UNKNOWN'
|
| 26 | self.__meid = meid
|
| 27 | cfg = configparser.ConfigParser()
|
| 28 | cfg.read(config_file)
|
| 29 | self.__da1_path = cfg.get('DA1', 'da1_path')
|
| 30 | self.__da1_addr = int(cfg.get('DA1', 'da1_addr'), 16)
|
| 31 | self.__da1_jump_64 = int(cfg.get('DA1', 'da1_jump_64'), 16)
|
| 32 | self.__da2_path = cfg.get('DA2', 'da2_path')
|
| 33 | self.__da2_addr = int(cfg.get('DA2', 'da2_addr'), 16)
|
| 34 | self.__auth_path = cfg.get('Auth', 'auth_path')
|
| 35 | self.__cert_path = cfg.get('Cert', 'cert_path')
|
| 36 | self.__fall_thru_to_fb = int(cfg.get('FALL_THRU_TO_FB', 'fall_thru_to_fb'))
|
| 37 | logging.debug('da1_path: %s' %(self.__da1_path))
|
| 38 | logging.debug('da1_addr: 0x%x' %(self.__da1_addr))
|
| 39 | logging.debug('da1_jump_64: 0x%x' %(self.__da1_jump_64))
|
| 40 | logging.debug('da2_path: %s' %(self.__da2_path))
|
| 41 | logging.debug('ad2_addr: 0x%x' %(self.__da2_addr))
|
| 42 | logging.debug('auth_path: %s' %(self.__auth_path))
|
| 43 | logging.debug('cert_path: %s' %(self.__cert_path))
|
| 44 |
|
| 45 | def __del__(self):
|
| 46 | # compatible with pySerial 2.6.
|
| 47 | # isOpen() is deprecated since version 3.0, 3.0 uses is_open
|
| 48 | if self.__ser and self.__ser.isOpen():
|
| 49 | self.__ser.close()
|
| 50 |
|
| 51 | def __match_usb_br(self, vid, pid):
|
| 52 | if vid == 0x0e8d and pid == 0x0003:
|
| 53 | self.__connect_type = 'BROM'
|
| 54 | return True
|
| 55 | return False
|
| 56 |
|
| 57 | def __match_usb_pl(self, vid, pid):
|
| 58 | if ((vid == 0x0e8d and pid == 0x2000) or (vid == 0x0e8d and pid == 0x3000)):
|
| 59 | self.__connect_type = 'PRELOADER'
|
| 60 | return True
|
| 61 | return False
|
| 62 |
|
| 63 | def __match_usb_auto(self, vid, pid):
|
| 64 | if self.__match_usb_br(vid, pid):
|
| 65 | return True
|
| 66 | if self.__match_usb_pl(vid, pid):
|
| 67 | return True
|
| 68 | return False
|
| 69 |
|
| 70 | def __open_usb_device(self, match_usb_func, comport, vid, pid):
|
| 71 | if match_usb_func(vid, pid):
|
| 72 | time.sleep(0.1)
|
| 73 | try:
|
| 74 | self.__ser = serial.Serial(comport, 115200)
|
| 75 | except serial.SerialException as e:
|
| 76 | logging.debug('%s, retry...' %(str(e)))
|
| 77 | else:
|
| 78 | logging.info('Got %s' %(comport))
|
| 79 | return True
|
| 80 | return False
|
| 81 |
|
| 82 | def __find_usb_device(self, match_usb_func):
|
| 83 | while True:
|
| 84 | ports = ser_tools.comports()
|
| 85 | if serial.VERSION < '3':
|
| 86 | ports_list = list(ports)
|
| 87 | for port in ports_list:
|
| 88 | if 'USB' in port[2]:
|
| 89 | if sys.platform.startswith('win'):
|
| 90 | idx = port[2].index('VID_')+4
|
| 91 | vid = int(port[2][idx : idx + 4], 16)
|
| 92 | idx = port[2].index('PID_')+4
|
| 93 | pid = int(port[2][idx : idx + 4], 16)
|
| 94 | elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
|
| 95 | idx = port[2].index('VID:PID=') + 8
|
| 96 | vid = int(port[2][idx : idx + 4], 16)
|
| 97 | pid = int(port[2][idx + 5 : idx + 13], 16)
|
| 98 | elif sys.platform.startswith('darwin'):
|
| 99 | raise EnvironmentError('Unsupport macOS')
|
| 100 | else:
|
| 101 | raise EnvironmentError('Unsupported platform')
|
| 102 | if self.__open_usb_device(match_usb_func, port[0], vid, pid):
|
| 103 | return
|
| 104 | else:
|
| 105 | for port in ports:
|
| 106 | if self.__open_usb_device(match_usb_func, port.device, port.vid, port.pid):
|
| 107 | return
|
| 108 |
|
| 109 | def __read8(self):
|
| 110 | return struct.unpack('!B', self.__ser.read())[0]
|
| 111 |
|
| 112 | def __read16(self):
|
| 113 | return struct.unpack('!H', self.__ser.read(2))[0]
|
| 114 |
|
| 115 | def __read32(self):
|
| 116 | return struct.unpack('!I', self.__ser.read(4))[0]
|
| 117 |
|
| 118 | def __write8(self, data, echo):
|
| 119 | self.__ser.write(struct.pack('!B', data))
|
| 120 | if echo:
|
| 121 | return struct.unpack('!B', self.__ser.read())[0] == data
|
| 122 | return True
|
| 123 |
|
| 124 | def __write16(self, data, echo):
|
| 125 | self.__ser.write(struct.pack('!H', data))
|
| 126 | if echo:
|
| 127 | return struct.unpack('!H', self.__ser.read(2))[0] == data
|
| 128 | return True
|
| 129 |
|
| 130 | def __write32(self, data, echo):
|
| 131 | self.__ser.write(struct.pack('!I', data))
|
| 132 | if echo:
|
| 133 | return struct.unpack('!I', self.__ser.read(4))[0] == data
|
| 134 | return True
|
| 135 |
|
| 136 | def __start_cmd(self):
|
| 137 | cmd = (0xa0, 0x0a, 0x50, 0x05)
|
| 138 | echo_cmd = (0x5f, 0xf5, 0xaf, 0xfa)
|
| 139 |
|
| 140 | i = 0
|
| 141 | while (i < len(cmd)):
|
| 142 | self.__write8(cmd[i], False)
|
| 143 | if self.__read8() != echo_cmd[i]:
|
| 144 | i = 0
|
| 145 | self.__ser.flushInput()
|
| 146 | else:
|
| 147 | i = i + 1
|
| 148 | time.sleep(0.1)
|
| 149 | # self.__ser.flush()
|
| 150 | self.__ser.flushInput()
|
| 151 | self.__ser.flushOutput()
|
| 152 | if self.__connect_type == 'BROM':
|
| 153 | logging.info('Connect brom')
|
| 154 | elif self.__connect_type == 'PRELOADER':
|
| 155 | logging.info('Connect preloader')
|
| 156 |
|
| 157 | def __load_binary(self, path):
|
| 158 | logging.info("Loading file: %s" %path)
|
| 159 | with open(path, 'rb') as f:
|
| 160 | return f.read()
|
| 161 |
|
| 162 | def __checksum(self, data, length):
|
| 163 | checksum = 0
|
| 164 | for i in range(0, length, 2):
|
| 165 | checksum ^= struct.unpack('<H', data[i:i+2])[0]
|
| 166 | checksum &= 0xFFFF
|
| 167 | return checksum
|
| 168 |
|
| 169 | def __get_target_config(self):
|
| 170 | if not self.__write8(0xd8, True):
|
| 171 | return -1, None
|
| 172 | cfg = self.__read32()
|
| 173 | status = self.__read16()
|
| 174 |
|
| 175 | if status >= self.E_ERROR:
|
| 176 | return status, None
|
| 177 | return 0, cfg
|
| 178 |
|
| 179 | def __send_auth(self, cfg):
|
| 180 | if self.TGT_CFG_DAA_EN & cfg == 0:
|
| 181 | return 0
|
| 182 | else:
|
| 183 | if self.TGT_CFG_SBC_EN & cfg == 0:
|
| 184 | logging.error('daa=1, sbc=0')
|
| 185 | return -2
|
| 186 | if self.__auth_path == '':
|
| 187 | logging.error('no auth file')
|
| 188 | return -3
|
| 189 | auth = self.__load_binary(self.__auth_path)
|
| 190 | auth_len = len(auth)
|
| 191 | logging.debug("auth file size: 0x%x" %(auth_len))
|
| 192 |
|
| 193 | if not self.__write8(0xe2, True):
|
| 194 | return -4
|
| 195 | if not self.__write32(len(auth), True):
|
| 196 | return -5
|
| 197 |
|
| 198 | status = self.__read16()
|
| 199 | if status >= self.E_ERROR:
|
| 200 | return status
|
| 201 | self.__ser.write(auth)
|
| 202 |
|
| 203 | # compare checksum
|
| 204 | if self.__read16() != self.__checksum(auth, auth_len):
|
| 205 | return -6
|
| 206 |
|
| 207 | status = self.__read16()
|
| 208 | if status >= self.E_ERROR:
|
| 209 | return status
|
| 210 | return 0
|
| 211 |
|
| 212 | def __strip_pl_hdr(self, pl, pl_len):
|
| 213 | # EMMC_HEADER_V1
|
| 214 | identifier, ver, dev_rw_unit = struct.unpack('12s2I', pl[:20])
|
| 215 | # GFH_FILE_INFO_V1
|
| 216 | gfh = pl[:56]
|
| 217 | gfh_offset = 0
|
| 218 |
|
| 219 | if identifier.strip(b'\0') == b'EMMC_BOOT' and ver == 1:
|
| 220 | logging.debug('emmc_hdr: identifier:%s, ver:0x%08x, dev_rw_unit:0x%08x' %(identifier, ver, dev_rw_unit))
|
| 221 | # BR_Layout_v1 size: 40
|
| 222 | if dev_rw_unit + 40 > pl_len:
|
| 223 | logging.error('EMMC HDR error. dev_rw_unit=0x%x, brlyt_size=0x%x, pl_len=0x%x'
|
| 224 | %(dev_rw_unit, brlyt_size, pl_len))
|
| 225 | return False, None, None
|
| 226 |
|
| 227 | brlyt_identifier, brlyt_ver = struct.unpack('8sI', pl[dev_rw_unit:dev_rw_unit + 12])
|
| 228 | logging.debug('brlyt_identifier: %s, brlyt_ver=0x%x' %(brlyt_identifier, brlyt_ver))
|
| 229 | if brlyt_identifier.strip(b'\0') != b'BRLYT' or brlyt_ver != 1:
|
| 230 | logging.error('BRLYT error. ver=0x%x, identifier=%s' %(brlyt_ver, brlyt_identifier))
|
| 231 | return False, None, None
|
| 232 | # BL_Descriptor
|
| 233 | bl_begin_dev_addr = struct.unpack('I', pl[dev_rw_unit + 28 : dev_rw_unit + 32])[0]
|
| 234 | if bl_begin_dev_addr + 56 > pl_len:
|
| 235 | logging.error('BRLYT error. bl_begin_dev_addr=0x%x' %bl_begin_dev_addr)
|
| 236 | return False, None, None
|
| 237 | # GFH_FILE_INFO_v1
|
| 238 | gfh = pl[bl_begin_dev_addr:bl_begin_dev_addr + 56]
|
| 239 | gfh_offset = bl_begin_dev_addr
|
| 240 |
|
| 241 | gfh_struct =struct.unpack('I2H12sIH2B7I', gfh)
|
| 242 |
|
| 243 | gfh_magic_ver = gfh_struct[0]
|
| 244 | gfh_type = gfh_struct[2]
|
| 245 | gfh_identifier = gfh_struct[3]
|
| 246 | gfh_file_len = gfh_struct[9]
|
| 247 | gfh_jump_offset = gfh_struct[13]
|
| 248 | gfh_sig_len = gfh_struct[12]
|
| 249 | if (gfh_magic_ver & 0x00FFFFFF) == 0x004D4D4D and gfh_type == 0 and gfh_identifier.strip(b'\0') == b'FILE_INFO':
|
| 250 | if gfh_file_len < gfh_jump_offset + gfh_sig_len:
|
| 251 | logging.error('GFH error. pl_len=0x%x, file_len=0x%x, jump_offset=0x%x, sig_len=0x%x'
|
| 252 | %(pl_len, gfh_file_len, gfh_jump_offset, gfh_sig_len))
|
| 253 | return False, None, None
|
| 254 | logging.debug('gfh: magic_ver: 0x%08x' %gfh_struct[0])
|
| 255 | logging.debug('gfh: size: 0x%04x' %gfh_struct[1])
|
| 256 | logging.debug('gfh: type: 0x%04x' %gfh_struct[2])
|
| 257 | logging.debug('gfh: identifier: %s' %gfh_struct[3])
|
| 258 | logging.debug('gfh: file_ver: 0x%08x' %gfh_struct[4])
|
| 259 | logging.debug('gfh: file_type: 0x%04x' %gfh_struct[5])
|
| 260 | logging.debug('gfh: flash_dev: 0x%02x' %gfh_struct[6])
|
| 261 | logging.debug('gfh: sig_type: 0x%02x' %gfh_struct[7])
|
| 262 | logging.debug('gfh: load_addr: 0x%08x' %gfh_struct[8])
|
| 263 | logging.debug('gfh: file_len: 0x%08x' %gfh_struct[9])
|
| 264 | logging.debug('gfh: max_size: 0x%08x' %gfh_struct[10])
|
| 265 | logging.debug('gfh: content_offset: 0x%08x' %gfh_struct[11])
|
| 266 | logging.debug('gfh: sig_len: 0x%08x' %gfh_struct[12])
|
| 267 | logging.debug('gfh: jump_offset: 0x%08x' %gfh_struct[13])
|
| 268 | logging.debug('gfh: attr: 0x%08x' %gfh_struct[14])
|
| 269 | strip_pl_len = gfh_file_len - gfh_jump_offset - gfh_sig_len
|
| 270 | start = gfh_offset + gfh_jump_offset
|
| 271 | strip_pl = pl[start:start + strip_pl_len]
|
| 272 | return (True, strip_pl, strip_pl_len)
|
| 273 | else:
|
| 274 | return (True, pl, pl_len)
|
| 275 |
|
| 276 | def __send_da(self, addr, da, da_len, sig, sig_len):
|
| 277 | if not self.__write8(0xd7, True):
|
| 278 | return -1
|
| 279 | if not self.__write32(addr, True):
|
| 280 | return -2
|
| 281 | logging.debug('len: 0x%x' %(da_len + sig_len))
|
| 282 | if not self.__write32(da_len + sig_len, True):
|
| 283 | return -3
|
| 284 | if not self.__write32(sig_len, True):
|
| 285 | return -4
|
| 286 | status = self.__read16()
|
| 287 | if status >= self.E_ERROR:
|
| 288 | return status
|
| 289 |
|
| 290 | if da_len > 0:
|
| 291 | self.__ser.write(da)
|
| 292 | if sig_len > 0:
|
| 293 | self.__ser.write(sig)
|
| 294 |
|
| 295 | checksum = self.__checksum(da, da_len) ^ self.__checksum(sig, sig_len)
|
| 296 | data = self.__read16()
|
| 297 | logging.debug('checksum: 0x%x - 0x%x' %(checksum, data))
|
| 298 | if data != checksum:
|
| 299 | return -5
|
| 300 | status = self.__read16()
|
| 301 | if status >= self.E_ERROR:
|
| 302 | return status
|
| 303 |
|
| 304 | return 0
|
| 305 |
|
| 306 | def __jump_da(self, addr):
|
| 307 | if not self.__write8(0xd5, True):
|
| 308 | return -1
|
| 309 | if not self.__write32(addr, True):
|
| 310 | return -2
|
| 311 | status = self.__read16()
|
| 312 | if status >= self.E_ERROR:
|
| 313 | return status
|
| 314 | return 0
|
| 315 |
|
| 316 | def __jump_da_ex(self, addr):
|
| 317 | if not self.__write8(0xde, True):
|
| 318 | return -1
|
| 319 | if not self.__write32(addr, True):
|
| 320 | return -2
|
| 321 | if not self.__write8(0x1, True):
|
| 322 | return -3
|
| 323 | status = self.__read16()
|
| 324 | if status >= self.E_ERROR:
|
| 325 | return status
|
| 326 | if not self.__write8(0x64, True):
|
| 327 | return -4
|
| 328 | status = self.__read16()
|
| 329 | if status >= self.E_ERROR:
|
| 330 | return status
|
| 331 | return 0
|
| 332 |
|
| 333 | def __get_meid(self):
|
| 334 | if not self.__write8(0xe1, True):
|
| 335 | return -1
|
| 336 | len = self.__read32()
|
| 337 | logging.debug('meid len: 0x%x' %len)
|
| 338 | data = struct.unpack('!'+str(len)+'B', self.__ser.read(len))
|
| 339 | meid_str = lambda s: ''.join(map(lambda c: '%02x' %c, s))
|
| 340 | status = self.__read16()
|
| 341 | if status >= self.E_ERROR:
|
| 342 | return status
|
| 343 | logging.info(meid_str(data));
|
| 344 | return 0
|
| 345 |
|
| 346 | def __send_cert(self, data, len):
|
| 347 | if not self.__write8(0xe0, True):
|
| 348 | return -1
|
| 349 | if not self.__write32(len, True):
|
| 350 | return -2
|
| 351 | status = self.__read16()
|
| 352 | if status >= self.E_ERROR:
|
| 353 | return status
|
| 354 | self.__ser.write(data)
|
| 355 | checksum = self.__checksum(data, len)
|
| 356 | data = self.__read16()
|
| 357 | if checksum != data:
|
| 358 | logging.error("checksum: 0x%x - 0x%x" %(checksum, data))
|
| 359 | return -3
|
| 360 | status = self.__read16()
|
| 361 | if status >= self.E_ERROR:
|
| 362 | return status
|
| 363 | return 0
|
| 364 |
|
| 365 | def __reboot_platform(self):
|
| 366 | if not self.__write8(0xd4, True):
|
| 367 | return -1
|
| 368 | if not self.__write32(0x10007000, True):
|
| 369 | return -2
|
| 370 | if not self.__write32(0x1, True):
|
| 371 | return -3
|
| 372 | status = self.__read16()
|
| 373 | if status >= self.E_ERROR:
|
| 374 | return status
|
| 375 | if not self.__write32(0x22000004, True):
|
| 376 | return -4
|
| 377 | status = self.__read16()
|
| 378 | if status >= self.E_ERROR:
|
| 379 | return status
|
| 380 | if not self.__write8(0xd4, True):
|
| 381 | return -5
|
| 382 | if not self.__write32(0x10007014, True):
|
| 383 | return -6
|
| 384 | if not self.__write32(0x1, True):
|
| 385 | return -7
|
| 386 | status = self.__read16()
|
| 387 | if status >= self.E_ERROR:
|
| 388 | return status
|
| 389 | if not self.__write32(0x1209, True):
|
| 390 | return -8
|
| 391 | return 0
|
| 392 |
|
| 393 | def __fall_through_to_fastboot(self):
|
| 394 | if not self.__write8(0xd9, True):
|
| 395 | return -1
|
| 396 | status = self.__read16()
|
| 397 | if status >= self.E_ERROR:
|
| 398 | return status
|
| 399 | return 0
|
| 400 |
|
| 401 | def start(self):
|
| 402 | self.__find_usb_device(self.__match_usb_auto)
|
| 403 | self.__start_cmd()
|
| 404 |
|
| 405 | # get meid
|
| 406 | if self.__meid:
|
| 407 | status = self.__get_meid()
|
| 408 | if status != 0:
|
| 409 | logging.error('get meid (%d)' %status)
|
| 410 | return -1
|
| 411 | return 0
|
| 412 |
|
| 413 | # send cert
|
| 414 | if self.__cert_path != '':
|
| 415 | cert = self.__load_binary(self.__cert_path)
|
| 416 | cert_len = len(cert)
|
| 417 | logging.debug('cert_len: 0x%x' %cert_len)
|
| 418 | status = self.__send_cert(cert, cert_len)
|
| 419 | if status != 0:
|
| 420 | logging.error('send cert (%d)' %status)
|
| 421 | return -1
|
| 422 | logging.info('Reboot...')
|
| 423 | status = self.__reboot_platform()
|
| 424 | if status != 0:
|
| 425 | logging.error('reboot platform (%d)' %status)
|
| 426 | return -1
|
| 427 | return 0
|
| 428 |
|
| 429 | if self.__connect_type == 'BROM':
|
| 430 | status, cfg = self.__get_target_config()
|
| 431 | if status != 0:
|
| 432 | logging.error('get target config (%s)' %status)
|
| 433 | return -1
|
| 434 | logging.debug('cfg=0x%x' %cfg)
|
| 435 |
|
| 436 | status = self.__send_auth(cfg)
|
| 437 | if status != 0:
|
| 438 | logging.error('send auth (%d)' %status)
|
| 439 | return -1
|
| 440 |
|
| 441 | da1 = self.__load_binary(self.__da1_path)
|
| 442 | da1_len = len(da1)
|
| 443 | logging.debug('da1 length: 0x%x' %da1_len)
|
| 444 | status, strip_pl, strip_pl_len = self.__strip_pl_hdr(da1, da1_len)
|
| 445 | if not status:
|
| 446 | logging.error('strip pl hdr')
|
| 447 | return -1
|
| 448 |
|
| 449 | sig_da1 = None
|
| 450 | sig_da1_len = 0
|
| 451 | if self.TGT_CFG_DAA_EN & cfg:
|
| 452 | sig_da1 = self.__load_binary(self.__da1_path + '.sign')
|
| 453 | sig_da1_len = len(sig_da1)
|
| 454 |
|
| 455 | logging.debug('strip_pl_len: 0x%x' %strip_pl_len)
|
| 456 | logging.info('Send %s' %self.__da1_path)
|
| 457 | status = self.__send_da(self.__da1_addr, strip_pl, strip_pl_len, sig_da1, sig_da1_len)
|
| 458 | if status != 0:
|
| 459 | logging.error('send da1 (%d)' %status)
|
| 460 | return -1
|
| 461 | logging.info('Jump da')
|
| 462 | if self.__da1_jump_64 == 0:
|
| 463 | status = self.__jump_da(self.__da1_addr)
|
| 464 | else:
|
| 465 | status = self.__jump_da_ex(self.__da1_addr)
|
| 466 | if status != 0:
|
| 467 | logging.error('jump da1 (%d)' %status)
|
| 468 | return -1
|
| 469 |
|
| 470 | self.__ser.close()
|
| 471 | if self.__da2_path == '':
|
| 472 | return 0
|
| 473 |
|
| 474 | # handshake to preloader
|
| 475 | self.__find_usb_device(self.__match_usb_pl)
|
| 476 | self.__start_cmd()
|
| 477 |
|
| 478 | if self.__fall_thru_to_fb == 1:
|
| 479 | logging.info("fall through to fastboot")
|
| 480 | status = self.__fall_through_to_fastboot()
|
| 481 | self.__ser.close()
|
| 482 | if status != 0:
|
| 483 | logging.error("fall through to fastboot failed(%d)" %(status))
|
| 484 | return -1
|
| 485 | else:
|
| 486 | return 0
|
| 487 |
|
| 488 | # load da2 (lk)
|
| 489 | da2 = self.__load_binary(self.__da2_path)
|
| 490 | da2_len = len(da2)
|
| 491 | sig_da2 = self.__load_binary(self.__da2_path + '.sign')
|
| 492 | sig_da2_len = len(sig_da2)
|
| 493 | logging.info('Send %s' %self.__da2_path)
|
| 494 | status = self.__send_da(self.__da2_addr, da2, da2_len, sig_da2, sig_da2_len)
|
| 495 | if status != 0:
|
| 496 | logging.error('send da2 (%d)' %status)
|
| 497 | return -1
|
| 498 | logging.info('Jump da2')
|
| 499 | status = self.__jump_da(self.__da2_addr)
|
| 500 | if status != 0:
|
| 501 | logging.error('jump da2 (%d)' %status)
|
| 502 | return -1
|
| 503 |
|
| 504 | self.__ser.close()
|
| 505 | return 0
|
| 506 |
|
| 507 |
|
| 508 | if __name__ == '__main__':
|
| 509 | parser = OptionParser()
|
| 510 | parser.add_option('-f', '--file', dest='configfile', help='read config file',
|
| 511 | metavar='FILE', default='dl_addr.ini')
|
| 512 | parser.add_option('-d', '--debug', action='store_true', dest='debuglog',
|
| 513 | default=False, help='enable debug log')
|
| 514 | parser.add_option('-m', '--meid', action='store_true', dest='meid',
|
| 515 | default=False, help='get meid')
|
| 516 | options, args = parser.parse_args()
|
| 517 | config_file = options.configfile
|
| 518 | meid = options.meid
|
| 519 | debug = options.debuglog
|
| 520 | if debug:
|
| 521 | logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s')
|
| 522 | else:
|
| 523 | logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
|
| 524 |
|
| 525 | logging.info('pySerial version: (%s)' %serial.VERSION)
|
| 526 | if serial.VERSION < '2.6':
|
| 527 | logging.error('pySerial version(%s) is lower than 2.6, please upgrade!' %serial.VERSION)
|
| 528 | logging.info('Use config file: %s' %(config_file))
|
| 529 | logging.info('Waiting to connect platform...')
|
| 530 | fbtool = Fbtool(config_file, meid)
|
| 531 | fbtool.start()
|