1
0
mirror of https://github.com/mbirth/tcl_ota_check.git synced 2024-09-19 22:33:25 +01:00

Use new Device classes in ALL the features!

This commit is contained in:
Markus Birth 2018-02-07 01:49:44 +01:00
parent b687c4185f
commit 0b7ae53861
Signed by: mbirth
GPG Key ID: A9928D7A098C3A9A
10 changed files with 78 additions and 139 deletions

View File

@ -11,12 +11,11 @@ import sys
import tcllib
import tcllib.argparser
from tcllib.devices import Device
from tcllib.xmltools import pretty_xml
fc = tcllib.FotaCheck()
fc.serid = "3531510"
#fc.osvs = "7.1.1"
dpdesc = """
Checks for the latest FULL updates for the specified PRD number or for an OTA from the
@ -32,48 +31,45 @@ dp.add_argument("--rawmode", help="override --mode with raw value (2=OTA, 4=FULL
dp.add_argument("--rawcltp", help="override --type with raw value (10=MOBILE, 2010=DESKTOP)", metavar="CLTP")
args = dp.parse_args(sys.argv[1:])
dev = Device(args.prd[0], args.fvver)
dev.imei = "3531510"
def sel_mode(txtmode, autoval, rawval):
"""Handle custom mode."""
if rawval:
enum = tcllib.default_enum("MODE", {"RAW": rawval})
return enum.RAW
return rawval
if txtmode == "auto":
return autoval
elif txtmode == "ota":
return fc.MODE.OTA
return fc.MODE.FULL
return dev.MODE_STATES["OTA"]
return dev.MODE_STATES["FULL"]
def sel_cltp(txtmode, autoval, rawval):
"""Handle custom CLTP."""
if rawval:
enum = tcllib.default_enum("CLTP", {"RAW": rawval})
return enum.RAW
return rawval
if txtmode == "auto":
return autoval
elif txtmode == "desktop":
return fc.CLTP.DESKTOP
return fc.CLTP.MOBILE
return dev.CLTP_STATES["DESKTOP"]
return dev.CLTP_STATES["MOBILE"]
if args.imei:
print("Use specified IMEI: {}".format(args.imei))
fc.serid = args.imei
dev.imei = args.imei
fc.curef = args.prd[0]
fc.fv = args.fvver
if args.fvver == "AAA000":
fc.mode = sel_mode(args.mode, fc.MODE.FULL, args.rawmode)
fc.cltp = sel_cltp(args.type, fc.CLTP.DESKTOP, args.rawcltp)
dev.mode = sel_mode(args.mode, dev.MODE_STATES["FULL"], args.rawmode)
dev.cltp = sel_cltp(args.type, dev.CLTP_STATES["DESKTOP"], args.rawcltp)
else:
fc.mode = sel_mode(args.mode, fc.MODE.OTA, args.rawmode)
fc.cltp = sel_cltp(args.type, fc.CLTP.MOBILE, args.rawcltp)
dev.mode = sel_mode(args.mode, dev.MODE_STATES["OTA"], args.rawmode)
dev.cltp = sel_cltp(args.type, dev.CLTP_STATES["MOBILE"], args.rawcltp)
print("Mode: {}".format(fc.mode.value))
print("CLTP: {}".format(fc.cltp.value))
print("Mode: {}".format(dev.mode))
print("CLTP: {}".format(dev.cltp))
check_xml = fc.do_check()
fc.reset_session(dev)
check_xml = fc.do_check(dev)
print(pretty_xml(check_xml))
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
@ -92,7 +88,7 @@ for s in slaves:
for s in s3_slaves:
print("http://{}{}".format(s, s3_fileurl))
if fc.mode == fc.MODE.FULL:
if dev.mode == dev.MODE_STATES["FULL"]:
header = fc.do_encrypt_header(random.choice(encslaves), fileurl)
headname = "header_{}.bin".format(tv)
headdir = "headers"

View File

@ -16,9 +16,7 @@ from tcllib.devices import DesktopDevice
dev = DesktopDevice()
fc = tcllib.FotaCheck()
fc.mode = fc.MODE.FULL # still needed to set User-Agent
dpdesc = """
Checks for the latest FULL updates for all PRD numbers or only for
@ -40,8 +38,8 @@ for prd, variant in prds.items():
lastver = variant["last_full"]
if prdcheck in prd:
try:
fc.reset_session()
dev.curef = prd
fc.reset_session(dev)
check_xml = fc.do_check(dev, max_tries=20)
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
txt_tv = tv

View File

@ -16,9 +16,7 @@ from tcllib.devices import MobileDevice
dev = MobileDevice()
fc = tcllib.FotaCheck()
fc.mode = fc.MODE.OTA # still needed to set User-Agent
dpdesc = """
Checks for the latest OTA updates for all PRD numbers or only for the PRD specified
@ -49,9 +47,9 @@ for prd, variant in prds.items():
lastver = args.forcever
if prdcheck in prd:
try:
fc.reset_session()
dev.curef = prd
dev.fwver = lastver
fc.reset_session(dev)
check_xml = fc.do_check(dev, max_tries=20)
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
versioninfo = ansi.YELLOW_DARK + fv + ansi.RESET + "" + ansi.YELLOW + tv + ansi.RESET + " (FULL: {})".format(variant["last_full"])

View File

@ -13,16 +13,11 @@ from requests.exceptions import RequestException, Timeout
import tcllib
import tcllib.argparser
from tcllib import ansi, devlist
from tcllib.devices import DesktopDevice, MobileDevice
dev = DesktopDevice()
fc = tcllib.FotaCheck()
fc.serid = "3531510"
fc.fv = "AAA000"
fc.mode = fc.MODE.FULL
# CLTP = 10 (only show actual updates or HTTP 206) / 2010 (always show latest version for MODE.FULL)
#fc.cltp = fc.CLTP.MOBILE
fc.cltp = fc.CLTP.DESKTOP
dpdesc = """
Finds new PRD numbers for all known variants, or specified variants with tocheck. Scan range
@ -74,9 +69,9 @@ for center in sorted(prddict.keys()):
print("Checking {} ({}/{})".format(curef, done_count, total_count))
print(ansi.UP_DEL, end="")
try:
fc.reset_session()
fc.curef = curef
check_xml = fc.do_check(https=False, max_tries=20)
dev.curef = curef
fc.reset_session(dev)
check_xml = fc.do_check(dev, https=False, max_tries=20)
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
txt_tv = tv
print("{}: {} {}".format(curef, txt_tv, fhash))

View File

@ -12,19 +12,14 @@ from requests.exceptions import RequestException, Timeout
import tcllib
import tcllib.argparser
from tcllib import ansi, devlist
from tcllib.devices import DesktopDevice, MobileDevice
# Variants to scan for
SCAN_VARIANTS = ["001", "003", "009", "010", "700"]
dev = DesktopDevice()
fc = tcllib.FotaCheck()
fc.serid = "3531510"
fc.fv = "AAA000"
fc.mode = fc.MODE.FULL
# CLTP = 10 (only show actual updates or HTTP 206) / 2010 (always show latest version for MODE.FULL)
#fc.cltp = fc.CLTP.MOBILE
fc.cltp = fc.CLTP.DESKTOP
dpdesc = """
Finds new PRD numbers for a range of variants. Scan range can be set by
@ -61,9 +56,9 @@ for center in to_scan:
print("Checking {} ({}/{})".format(curef, done_count, total_count))
print(ansi.UP_DEL, end="")
try:
fc.reset_session()
fc.curef = curef
check_xml = fc.do_check(https=False, max_tries=20)
dev.curef = curef
fc.reset_session(dev)
check_xml = fc.do_check(dev, https=False, max_tries=20)
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
txt_tv = tv
print("{}: {} {}".format(curef, txt_tv, fhash))

View File

@ -12,11 +12,11 @@ from requests.exceptions import RequestException, Timeout
import tcllib
import tcllib.argparser
from tcllib import ansi
from tcllib.devices import DesktopDevice, MobileDevice
dev = MobileDevice()
fc = tcllib.FotaCheck()
fc.serid = "3531510"
fc.mode = fc.MODE.OTA
dpdesc = """
Finds all valid OTA updates for a given PRD. Scan range can be set by
@ -60,9 +60,9 @@ for fv in allvers:
print("Checking {} ({}/{})".format(fv, done_count, total_count))
print(ansi.UP_DEL, end="")
try:
fc.reset_session()
fc.fv = fv
check_xml = fc.do_check(https=False, max_tries=20)
dev.fwver = fv
fc.reset_session(dev)
check_xml = fc.do_check(dev, https=False, max_tries=20)
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
txt_tv = tv
print("{}: {}{} {}".format(curef, fv, txt_tv, fhash))

View File

@ -11,17 +11,15 @@ import requests
from requests.exceptions import RequestException
import tcllib
from tcllib.devices import DesktopDevice, MobileDevice
# 1. Fetch list of missing OTAs (e.g. from ancient versions to current)
# 2. Query updates from FOTA servers (and store XML)
# (3. Upload will be done manually with upload_logs.py)
dev = MobileDevice()
fc = tcllib.FotaCheck()
fc.serid = "3531510"
#fc.osvs = "7.1.1"
fc.mode = fc.MODE.OTA
fc.cltp = fc.CLTP.MOBILE
print("Loading list of missing OTAs.")
versions_json = requests.get("https://tclota.birth-online.de/json_otaversions.php").text
@ -38,10 +36,10 @@ for prd, data in versions.items():
for ver in data["missing_froms"]:
print(" {}".format(ver), end="", flush=True)
try:
fc.reset_session()
fc.curef = prd
fc.fv = ver
check_xml = fc.do_check(max_tries=20)
dev.curef = prd
dev.fwver = ver
fc.reset_session(dev)
check_xml = fc.do_check(dev, max_tries=20)
curef, fv, tv, fw_id, fileid, fn, fsize, fhash = fc.parse_check(check_xml)
print("", end="", flush=True)
except RequestException as e:

View File

@ -11,12 +11,12 @@ import sys
import tcllib
import tcllib.argparser
from tcllib.devices import DesktopDevice
from tcllib.xmltools import pretty_xml
fc = tcllib.FotaCheck()
fc.serid = "3531510"
#fc.osvs = "7.1.1"
dev = DesktopDevice()
dpdesc = """
Downloads the given firmware file.
@ -36,41 +36,39 @@ args = dp.parse_args(sys.argv[1:])
def sel_mode(defaultmode, rawval):
"""Handle custom mode."""
if rawval:
enum = tcllib.default_enum("MODE", {"RAW": rawval})
return enum.RAW
return rawval
return defaultmode
def sel_cltp(txtmode, rawval):
"""Handle custom CLTP."""
if rawval:
enum = tcllib.default_enum("CLTP", {"RAW": rawval})
return enum.RAW
return rawval
if txtmode == "mobile":
return fc.CLTP.MOBILE
return fc.CLTP.DESKTOP
return dev.CLTP_STATES["MOBILE"]
return dev.CLTP_STATES["DESKTOP"]
if args.imei:
print("Use specified IMEI: {}".format(args.imei))
fc.serid = args.imei
dev.imei = args.imei
fc.curef = args.prd[0]
dev.curef = args.prd[0]
if args.ota:
fc.fv = args.ota[0]
fc.mode = sel_mode(fc.MODE.OTA, args.rawmode)
dev.fwver = args.ota[0]
dev.mode = sel_mode(dev.MODE_STATES["OTA"], args.rawmode)
else:
fc.fv = args.targetversion[0]
fc.mode = sel_mode(fc.MODE.FULL, args.rawmode)
fc.cltp = sel_cltp(args.type, args.rawcltp)
dev.fwver = args.targetversion[0]
dev.mode = sel_mode(dev.MODE_STATES["FULL"], args.rawmode)
dev.cltp = sel_cltp(args.type, args.rawcltp)
print("Mode: {}".format(fc.mode.value))
print("CLTP: {}".format(fc.cltp.value))
print("Mode: {}".format(dev.mode))
print("CLTP: {}".format(dev.cltp))
fv = fc.fv
fv = dev.fwver
tv = args.targetversion[0]
fw_id = args.fwid[0]
req_xml = fc.do_request(fc.curef, fv, tv, fw_id)
req_xml = fc.do_request(dev.curef, fv, tv, fw_id)
print(pretty_xml(req_xml))
fileid, fileurl, slaves, encslaves, s3_fileurl, s3_slaves = fc.parse_request(req_xml)
@ -80,7 +78,7 @@ for s in slaves:
for s in s3_slaves:
print("http://{}{}".format(s, s3_fileurl))
if fc.mode == fc.MODE.FULL:
if dev.mode == dev.MODE_STATES["FULL"]:
header = fc.do_encrypt_header(random.choice(encslaves), fileurl)
headname = "header_{}.bin".format(tv)
headdir = "headers"

View File

@ -5,19 +5,12 @@
"""Library for TCL API work and related functions."""
import enum
import requests
from . import (dumpmgr, servervote, tclcheck, tclchecksum, tclencheader,
tclrequest)
def default_enum(enumname, vardict, qualroot="tcllib.FotaCheck"):
"""Enum with defaults set."""
return enum.IntEnum(enumname, vardict, module=__name__, qualname="{}.{}".format(qualroot, enumname))
class FotaCheck(
tclcheck.TclCheckMixin,
tclrequest.TclRequestMixin,
@ -28,35 +21,15 @@ class FotaCheck(
):
"""Main API handler class."""
CKTP = default_enum("CKTP", ["AUTO", "MANUAL"])
MODE = default_enum("MODE", {"OTA": 2, "FULL": 4})
RTD = default_enum("RTD", ["UNROOTED", "ROOTED"])
CHNL = default_enum("CHNL", ["3G", "WIFI"])
CLTP = default_enum("CLTP", {"MOBILE": 10, "DESKTOP": 2010})
CKOT = default_enum("CKOT", ["ALL", "AOTA_ONLY", "FOTA_ONLY"])
def __init__(self):
"""Handle mixins and populate variables."""
super().__init__()
self.serid = "543212345000000"
self.curef = "PRD-63117-011"
self.fv = "AAM481"
self.osvs = "7.1.1"
self.mode = self.MODE.FULL
self.ftype = "Firmware"
self.cltp = self.CLTP.MOBILE
self.cktp = self.CKTP.MANUAL
self.ckot = self.CKOT.ALL
self.rtd = self.RTD.UNROOTED
self.chnl = self.CHNL.WIFI
self.reset_session()
def reset_session(self):
def reset_session(self, device=None):
"""Reset everything to default."""
self.g2master = self.get_master_server()
self.sess = requests.Session()
if self.mode == self.MODE.FULL:
self.sess.headers.update({"User-Agent": "com.tcl.fota/5.1.0.2.0029.0, Android"})
else:
self.sess.headers.update({"User-Agent": "tcl"})
if device:
self.sess.headers.update({"User-Agent": device.ua})
return self.sess

View File

@ -11,6 +11,8 @@ from collections import OrderedDict, defaultdict
import requests
from defusedxml import ElementTree
from .devices import Device
class TclCheckMixin:
"""A mixin component for TCL's update request API."""
@ -21,38 +23,24 @@ class TclCheckMixin:
url = protocol + self.g2master + "/check.php"
return url
def prep_check(self, device=None, https=True):
def prep_check(self, device: Device, https=True):
"""Prepare URL and parameters for update request."""
url = self.prep_check_url(https)
params = OrderedDict()
if device:
# Need to support both ways for now
params["id"] = device.imei
params["curef"] = device.curef
params["fv"] = device.fwver
params["mode"] = device.mode
params["type"] = device.type
params["cltp"] = device.cltp
params["cktp"] = device.cktp
params["rtd"] = device.rtd
params["chnl"] = device.chnl
#params["osvs"] = device.osvs
#params["ckot"] = device.ckot
else:
params["id"] = self.serid
params["curef"] = self.curef
params["fv"] = self.fv
params["mode"] = self.mode.value
params["type"] = self.ftype
params["cltp"] = self.cltp.value
params["cktp"] = self.cktp.value
params["rtd"] = self.rtd.value
params["chnl"] = self.chnl.value
#params["osvs"] = self.osvs
#params["ckot"] = self.ckot.value
params["id"] = device.imei
params["curef"] = device.curef
params["fv"] = device.fwver
params["mode"] = device.mode
params["type"] = device.type
params["cltp"] = device.cltp
params["cktp"] = device.cktp
params["rtd"] = device.rtd
params["chnl"] = device.chnl
#params["osvs"] = device.osvs
#params["ckot"] = device.ckot
return url, params
def do_check(self, device=None, https=True, timeout=10, max_tries=5):
def do_check(self, device: Device, https=True, timeout=10, max_tries=5):
"""Perform update request with given parameters."""
url, params = self.prep_check(device, https)
last_response = None