mirror of
https://codeberg.org/vanous/huafetcher.git
synced 2025-01-10 15:12:01 +01:00
add UIHH aGPS packing
This commit is contained in:
parent
59a1df5dc1
commit
a40b8c9bbe
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,6 +8,7 @@ cep_alm_pak.zip
|
|||||||
cep_7days.zip
|
cep_7days.zip
|
||||||
credentials.*
|
credentials.*
|
||||||
README.html
|
README.html
|
||||||
|
tmp
|
||||||
# C extensions
|
# C extensions
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ package.domain = cz.linux
|
|||||||
source.dir = .
|
source.dir = .
|
||||||
|
|
||||||
# (list) Source files to include (let empty to include all the files)
|
# (list) Source files to include (let empty to include all the files)
|
||||||
source.include_exts = py,png,jpg,kv,atlas
|
source.include_exts = py,png,jpg,kv,atlas,json
|
||||||
|
|
||||||
# (list) List of inclusions using pattern matching
|
# (list) List of inclusions using pattern matching
|
||||||
#source.include_patterns = assets/*,images/*.png
|
#source.include_patterns = assets/*,images/*.png
|
||||||
@ -28,7 +28,7 @@ source.exclude_dirs = tests, bin, screenshots
|
|||||||
#source.exclude_patterns = license,images/*/*.jpg
|
#source.exclude_patterns = license,images/*/*.jpg
|
||||||
|
|
||||||
# (str) Application versioning (method 1)
|
# (str) Application versioning (method 1)
|
||||||
version = 0.17
|
version = 0.18
|
||||||
|
|
||||||
# (str) Application versioning (method 2)
|
# (str) Application versioning (method 2)
|
||||||
# version.regex = __version__ = ['"](.*)['"]
|
# version.regex = __version__ = ['"](.*)['"]
|
||||||
|
@ -159,24 +159,25 @@ class HuamiAmazfit:
|
|||||||
|
|
||||||
return devices_dict
|
return devices_dict
|
||||||
|
|
||||||
def get_gps_data(self):
|
def get_gps_data(self) -> None:
|
||||||
agps_packs = ["AGPS_ALM", "AGPSZIP"]
|
"""Download GPS packs: almanac and AGPS"""
|
||||||
agps_file_names = ["cep_alm_pak.zip", "cep_7days.zip"]
|
agps_packs = ["AGPS_ALM", "AGPSZIP", "LLE", "AGPS"]
|
||||||
|
agps_file_names = ["cep_1week.zip", "cep_7days.zip", "lle_1week.zip", "cep_pak.bin"]
|
||||||
agps_link = urls.URLS['agps']
|
agps_link = urls.URLS['agps']
|
||||||
|
|
||||||
headers = urls.PAYLOADS['agps']
|
headers = urls.PAYLOADS['agps']
|
||||||
headers['apptoken'] = self.app_token
|
headers['apptoken'] = self.app_token
|
||||||
|
|
||||||
for idx, agps_pack_name in enumerate(agps_packs):
|
for pack_idx, agps_pack_name in enumerate(agps_packs):
|
||||||
print("Downloading {}...".format(agps_pack_name))
|
print(f"Downloading {agps_pack_name}...")
|
||||||
response = requests.get(agps_link.format(pack_name=agps_pack_name), headers=headers)
|
response = requests.get(agps_link.format(pack_name=agps_pack_name), headers=headers)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
agps_result = response.json()[0]
|
agps_result = response.json()[0]
|
||||||
if 'fileUrl' not in agps_result:
|
if 'fileUrl' not in agps_result:
|
||||||
raise ValueError("No 'fileUrl' parameter in files request.")
|
raise ValueError("No 'fileUrl' parameter in files request.")
|
||||||
with requests.get(agps_result['fileUrl'], stream=True) as r:
|
with requests.get(agps_result['fileUrl'], stream=True) as request:
|
||||||
with open(agps_file_names[idx], 'wb') as f:
|
with open(agps_file_names[pack_idx], 'wb') as gps_file:
|
||||||
shutil.copyfileobj(r.raw, f)
|
shutil.copyfileobj(request.raw, gps_file)
|
||||||
|
|
||||||
def logout(self):
|
def logout(self):
|
||||||
logout_url = urls.URLS['logout']
|
logout_url = urls.URLS['logout']
|
||||||
|
62
main.py
62
main.py
@ -124,15 +124,15 @@ class Main(App):
|
|||||||
self.fetch_agps_button.bind(on_press=self.on_press_button_agps)
|
self.fetch_agps_button.bind(on_press=self.on_press_button_agps)
|
||||||
self.fetch_agps_button.disabled=True
|
self.fetch_agps_button.disabled=True
|
||||||
|
|
||||||
share_agps_button = MyButton(text='Share aGPS')
|
create_uihh_file_button = MyButton(text='Create UIHH')
|
||||||
share_agps_button.bind(on_press=self.on_press_button_share_agps)
|
create_uihh_file_button.bind(on_press=self.create_uihh_agps_file)
|
||||||
|
|
||||||
buttons_layout.add_widget(self.get_token_button)
|
buttons_layout.add_widget(self.get_token_button)
|
||||||
#buttons_layout.add_widget(login_button)
|
#buttons_layout.add_widget(login_button)
|
||||||
buttons_layout.add_widget(self.fetch_key_button)
|
buttons_layout.add_widget(self.fetch_key_button)
|
||||||
buttons_layout.add_widget(self.fetch_agps_button)
|
buttons_layout.add_widget(self.fetch_agps_button)
|
||||||
#sharing doesn't work
|
#sharing doesn't work
|
||||||
#buttons_layout.add_widget(share_agps_button)
|
buttons_layout.add_widget(create_uihh_file_button)
|
||||||
|
|
||||||
self.paste_token_input_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
|
self.paste_token_input_layout = BoxLayout(orientation="horizontal", spacing=SPACING)
|
||||||
paste_token_input_label=MyLabel(text='URL result')
|
paste_token_input_label=MyLabel(text='URL result')
|
||||||
@ -428,6 +428,8 @@ class Main(App):
|
|||||||
|
|
||||||
def get_agps_files(self, *xargs):
|
def get_agps_files(self, *xargs):
|
||||||
import zipfile
|
import zipfile
|
||||||
|
import shutil
|
||||||
|
import os
|
||||||
try:
|
try:
|
||||||
res=self.huamidevice.login()
|
res=self.huamidevice.login()
|
||||||
if res:
|
if res:
|
||||||
@ -439,9 +441,9 @@ class Main(App):
|
|||||||
|
|
||||||
self.huamidevice.get_gps_data()
|
self.huamidevice.get_gps_data()
|
||||||
agps_file_names = ["cep_alm_pak.zip"]
|
agps_file_names = ["cep_alm_pak.zip"]
|
||||||
|
agps_file_names = ["cep_1week.zip", "cep_7days.zip", "lle_1week.zip", "cep_pak.bin"]
|
||||||
|
data_dir="./tmp"
|
||||||
if ( platform == 'android' ):
|
if ( platform == 'android' ):
|
||||||
import shutil
|
|
||||||
import os
|
|
||||||
from jnius import autoclass
|
from jnius import autoclass
|
||||||
from jnius import cast
|
from jnius import cast
|
||||||
Environment = autoclass('android.os.Environment')
|
Environment = autoclass('android.os.Environment')
|
||||||
@ -451,6 +453,9 @@ class Main(App):
|
|||||||
for filename in agps_file_names:
|
for filename in agps_file_names:
|
||||||
sdpathfile = os.path.join(data_dir, filename)
|
sdpathfile = os.path.join(data_dir, filename)
|
||||||
shutil.copyfile(filename, sdpathfile)
|
shutil.copyfile(filename, sdpathfile)
|
||||||
|
print(f"process {filename}")
|
||||||
|
if "zip" not in filename:
|
||||||
|
continue
|
||||||
with zipfile.ZipFile(filename, "r") as zip_f:
|
with zipfile.ZipFile(filename, "r") as zip_f:
|
||||||
#zip_f.extractall()
|
#zip_f.extractall()
|
||||||
zip_f.extractall(data_dir)
|
zip_f.extractall(data_dir)
|
||||||
@ -458,6 +463,53 @@ class Main(App):
|
|||||||
self.instructions_label.text="Files downloaded and extracted"
|
self.instructions_label.text="Files downloaded and extracted"
|
||||||
#Clock.schedule_once(partial(self.doit), 1)
|
#Clock.schedule_once(partial(self.doit), 1)
|
||||||
|
|
||||||
|
def create_uihh_agps_file(self, *xargs):
|
||||||
|
import typemap as tm
|
||||||
|
import pathlib
|
||||||
|
from binascii import crc32
|
||||||
|
data_dir="./tmp"
|
||||||
|
|
||||||
|
if ( platform == 'android' ):
|
||||||
|
from jnius import autoclass
|
||||||
|
from jnius import cast
|
||||||
|
Environment = autoclass('android.os.Environment')
|
||||||
|
File = autoclass('java.io.File')
|
||||||
|
data_dir = Environment.getExternalStorageDirectory().getPath()
|
||||||
|
|
||||||
|
content = b""
|
||||||
|
|
||||||
|
for typeID, inputfilename in tm.typemap.items():
|
||||||
|
fullPathName = pathlib.Path(data_dir).joinpath(inputfilename)
|
||||||
|
if not fullPathName.is_file():
|
||||||
|
self.instructions_label.text=f"[E] File not found: {fullPathName}"
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(fullPathName, "rb") as f:
|
||||||
|
filecontent = f.read()
|
||||||
|
|
||||||
|
print(f"[I] Packing {inputfilename}")
|
||||||
|
fileheader = chr(1).encode() +typeID.to_bytes(1,"big") + len(filecontent).to_bytes(4,"little") + crc32(filecontent).to_bytes(4,"little")
|
||||||
|
content += fileheader + filecontent
|
||||||
|
|
||||||
|
print("[I] Adding header")
|
||||||
|
header = ["UIHH" , chr(0x04) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x01) , crc32(content).to_bytes(4,"little") , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , len(content).to_bytes(4,"little") , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00) , chr(0x00)]
|
||||||
|
|
||||||
|
merged_header=b""
|
||||||
|
for i in header:
|
||||||
|
if isinstance(i, str):
|
||||||
|
i=i.encode()
|
||||||
|
merged_header+=i
|
||||||
|
|
||||||
|
content = merged_header+content
|
||||||
|
|
||||||
|
|
||||||
|
outputfile = pathlib.Path(data_dir).joinpath("aGPS_UIHH.bin")
|
||||||
|
print(f"[I] Writing {outputfile}")
|
||||||
|
with open(outputfile, "wb") as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
self.instructions_label.text="aGPS UIHH created"
|
||||||
|
#Clock.schedule_once(partial(self.doit), 1)
|
||||||
def on_press_button_share_agps(self, instance):
|
def on_press_button_share_agps(self, instance):
|
||||||
#not working because android broke it
|
#not working because android broke it
|
||||||
if ( platform == 'android' ):
|
if ( platform == 'android' ):
|
||||||
|
7
typemap.json
Normal file
7
typemap.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{ "0x05" : "gps_alm.bin",
|
||||||
|
"0x0f" : "gln_alm.bin",
|
||||||
|
"0x86" : "lle_bds.lle",
|
||||||
|
"0x87" : "lle_gps.lle",
|
||||||
|
"0x88" : "lle_glo.lle",
|
||||||
|
"0x89" : "lle_gal.lle",
|
||||||
|
"0x8a" : "lle_qzss.lle"}
|
24
typemap.py
Normal file
24
typemap.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#Copyright (C) 2021 Andreas Shimokawa
|
||||||
|
#
|
||||||
|
#This file is part of Gadgetbridge-tools.
|
||||||
|
#
|
||||||
|
#Gadgetbridge is free software: you can redistribute it and/or modify
|
||||||
|
#it under the terms of the GNU Affero General Public License as published
|
||||||
|
#by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
#(at your option) any later version.
|
||||||
|
#
|
||||||
|
#Gadgetbridge is distributed in the hope that it will be useful,
|
||||||
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
#GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
#You should have received a copy of the GNU Affero General Public License
|
||||||
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
with open("typemap.json") as f:
|
||||||
|
jsonmap = json.load(f)
|
||||||
|
|
||||||
|
typemap={int(k,16):v for k,v in jsonmap.items()}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user