1 | #!/usr/bin/env python3 |
||
2 | # -*- coding: utf-8 -*- |
||
3 | |||
4 | # pylint: disable=C0111,C0326,C0103 |
||
5 | |||
6 | """Checks for the latest FULL or OTA updates for specified PRD number.""" |
||
7 | |||
8 | import os |
||
9 | import sys |
||
10 | |||
11 | from tcllib import argparser |
||
12 | from tcllib.devices import Device |
||
13 | from tcllib.dumpmgr import write_info_if_dumps_found |
||
14 | from tcllib.requests import (CheckRequest, ChecksumRequest, DownloadRequest, |
||
15 | EncryptHeaderRequest, RequestRunner, |
||
16 | ServerSelector) |
||
17 | |||
18 | |||
19 | dpdesc = """ |
||
20 | Checks for the latest FULL updates for the specified PRD number or for an OTA from the |
||
21 | version specified as fvver. |
||
22 | """ |
||
23 | dp = argparser.DefaultParser(__file__, dpdesc) |
||
24 | dp.add_argument("prd", nargs=1, help="CU Reference #, e.g. PRD-63117-011") |
||
25 | dp.add_argument("fvver", nargs="?", help="Firmware version to check for OTA updates, e.g. AAM481 (omit to run FULL check)", default="AAA000") |
||
26 | dp.add_argument("-i", "--imei", help="use specified IMEI instead of default", type=str) |
||
27 | dp.add_argument("-m", "--mode", help="force type of update to check for", default="auto", type=str, choices=["full", "ota"]) |
||
28 | dp.add_argument("-t", "--type", help="force type of check to run", default="auto", type=str, choices=["desktop", "mobile"]) |
||
29 | dp.add_argument("--rawmode", help="override --mode with raw value (2=OTA, 4=FULL)", metavar="MODE") |
||
30 | dp.add_argument("--rawcltp", help="override --type with raw value (10=MOBILE, 2010=DESKTOP)", metavar="CLTP") |
||
31 | args = dp.parse_args(sys.argv[1:]) |
||
32 | |||
33 | dev = Device(args.prd[0], args.fvver) |
||
34 | dev.imei = "3531510" |
||
35 | |||
36 | |||
37 | def sel_mode(txtmode, autoval, rawval): |
||
38 | """Handle custom mode.""" |
||
39 | if rawval: |
||
40 | return rawval |
||
41 | if txtmode == "auto": |
||
42 | return autoval |
||
43 | elif txtmode == "ota": |
||
44 | return dev.MODE_STATES["OTA"] |
||
45 | return dev.MODE_STATES["FULL"] |
||
46 | |||
47 | |||
48 | def sel_cltp(txtmode, autoval, rawval): |
||
49 | """Handle custom CLTP.""" |
||
50 | if rawval: |
||
51 | return rawval |
||
52 | if txtmode == "auto": |
||
53 | return autoval |
||
54 | elif txtmode == "desktop": |
||
55 | return dev.CLTP_STATES["DESKTOP"] |
||
56 | return dev.CLTP_STATES["MOBILE"] |
||
57 | |||
58 | |||
59 | if args.imei: |
||
60 | print("Use specified IMEI: {}".format(args.imei)) |
||
61 | dev.imei = args.imei |
||
62 | |||
63 | if args.fvver == "AAA000": |
||
64 | dev.mode = sel_mode(args.mode, dev.MODE_STATES["FULL"], args.rawmode) |
||
65 | dev.cltp = sel_cltp(args.type, dev.CLTP_STATES["DESKTOP"], args.rawcltp) |
||
66 | else: |
||
67 | dev.mode = sel_mode(args.mode, dev.MODE_STATES["OTA"], args.rawmode) |
||
68 | dev.cltp = sel_cltp(args.type, dev.CLTP_STATES["MOBILE"], args.rawcltp) |
||
69 | |||
70 | print("Mode: {}".format(dev.mode)) |
||
71 | print("CLTP: {}".format(dev.cltp)) |
||
72 | |||
73 | runner = RequestRunner(ServerSelector()) |
||
74 | |||
75 | # Check for update |
||
76 | chk = CheckRequest(dev) |
||
77 | runner.run(chk) |
||
78 | if not chk.success: |
||
79 | print("{}".format(chk.error)) |
||
80 | sys.exit(2) |
||
81 | chkres = chk.get_result() |
||
82 | print(chkres.pretty_xml()) |
||
83 | |||
84 | # Request download |
||
85 | dlr = DownloadRequest(dev, chkres.tvver, chkres.fw_id) |
||
86 | runner.run(dlr) |
||
87 | if not dlr.success: |
||
88 | print("{}".format(dlr.error)) |
||
89 | sys.exit(3) |
||
90 | dlrres = dlr.get_result() |
||
91 | print(dlrres.pretty_xml()) |
||
92 | |||
93 | if dlrres.encslaves: |
||
94 | encrunner = RequestRunner(ServerSelector(dlrres.encslaves), https=False) |
||
95 | cks = ChecksumRequest(dlrres.fileurl, dlrres.fileurl) |
||
96 | encrunner.run(cks) |
||
97 | if not cks.success: |
||
98 | print("{}".format(cks.error)) |
||
99 | sys.exit(4) |
||
100 | cksres = cks.get_result() |
||
101 | print(cksres.pretty_xml()) |
||
102 | |||
103 | for s in dlrres.slaves: |
||
104 | print("http://{}{}".format(s, dlrres.fileurl)) |
||
105 | |||
106 | for s in dlrres.s3_slaves: |
||
107 | print("http://{}{}".format(s, dlrres.s3_fileurl)) |
||
108 | |||
109 | if dev.mode == dev.MODE_STATES["FULL"]: |
||
110 | hdr = EncryptHeaderRequest(dlrres.fileurl) |
||
111 | encrunner.run(hdr) |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
112 | if not hdr.success: |
||
113 | print("{}".format(hdr.error)) |
||
114 | sys.exit(5) |
||
115 | hdrres = hdr.get_result() |
||
116 | headname = "header_{}.bin".format(chkres.tvver) |
||
117 | headdir = "headers" |
||
118 | if not os.path.exists(headdir): |
||
119 | os.makedirs(headdir) |
||
120 | if len(hdrres.rawdata) == 4194320: |
||
121 | # TODO: Check sha1sum |
||
122 | print("Header length check passed. Writing to {}.".format(headname)) |
||
123 | with open(os.path.join(headdir, headname), "wb") as f: |
||
124 | f.write(hdrres.rawdata) |
||
125 | else: |
||
126 | print("Header length invalid ({}).".format(len(hdrres.rawdata))) |
||
127 | |||
128 | write_info_if_dumps_found() |
||
129 |