Started support for querying update servers.

This commit is contained in:
Markus Birth 2019-09-10 05:00:35 +02:00
parent 912dc50ff4
commit b5b6038849
Signed by: mbirth
GPG Key ID: A9928D7A098C3A9A
5 changed files with 523 additions and 0 deletions

31
get_updates.py Normal file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Queries the updateserver for given device's updates.
"""
from grmn import updateserver, devices
import sys
if len(sys.argv) < 2:
print("Syntax: {} DEVICESKU".format(sys.argv[0]))
print("Examples:")
print(" {} 3196 - Query update info for 006-B3196-00".format(sys.argv[0]))
print(" {} 006-B3196-00 - Query update info for given SKU".format(sys.argv[0]))
sys.exit(1)
DEVICE = sys.argv[1]
us = updateserver.UpdateServer()
device_sku = DEVICE
if len(device_sku) <= 4:
device_sku = "006-B{:>04}-00".format(device_sku)
hwid = int(device_sku[5:9])
device_name = devices.DEVICES.get(hwid, "Unknown device")
print("Device: {}".format(device_name))
us.query_updates([device_sku])

View File

@ -0,0 +1,39 @@
syntax = "proto3";
message GetAllUnitSoftwareUpdates {
message ClientData {
string client = 1; // "express"
string language = 2; // "en_US"
string client_platform = 3; // "Windows"
string client_platform_version = 4; // "601 Service Pack 1"
};
ClientData client_data = 1;
string device_xml = 2;
}
message GetAllUnitSoftwareUpdatesReply {
message UpdateInfo {
message FileInfo {
int64 UNKNOWN_NUM1 = 1;
string url = 2;
string md5 = 3;
int64 file_size = 4;
}
repeated string changelog = 1;
string device_name = 2;
string license_url = 3;
string update_file = 4;
int64 UNKNOWN_NUM5 = 5;
repeated FileInfo files_list = 6;
string product_sku = 8;
string fw_version = 9;
int64 UNKNOWN_FLAG10 = 10;
string language = 11;
int64 UNKNOWN_FLAG12 = 12;
string file_type = 14;
string UNKNOWN_STR15 = 15;
}
repeated UpdateInfo update_info = 1;
}

View File

@ -0,0 +1,361 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: GetAllUnitSoftwareUpdates.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='GetAllUnitSoftwareUpdates.proto',
package='',
syntax='proto3',
serialized_options=None,
serialized_pb=_b('\n\x1fGetAllUnitSoftwareUpdates.proto\"\xd5\x01\n\x19GetAllUnitSoftwareUpdates\x12:\n\x0b\x63lient_data\x18\x01 \x01(\x0b\x32%.GetAllUnitSoftwareUpdates.ClientData\x12\x12\n\ndevice_xml\x18\x02 \x01(\t\x1ah\n\nClientData\x12\x0e\n\x06\x63lient\x18\x01 \x01(\t\x12\x10\n\x08language\x18\x02 \x01(\t\x12\x17\n\x0f\x63lient_platform\x18\x03 \x01(\t\x12\x1f\n\x17\x63lient_platform_version\x18\x04 \x01(\t\"\x85\x04\n\x1eGetAllUnitSoftwareUpdatesReply\x12?\n\x0bupdate_info\x18\x01 \x03(\x0b\x32*.GetAllUnitSoftwareUpdatesReply.UpdateInfo\x1a\xa1\x03\n\nUpdateInfo\x12\x11\n\tchangelog\x18\x01 \x03(\t\x12\x13\n\x0b\x64\x65vice_name\x18\x02 \x01(\t\x12\x13\n\x0blicense_url\x18\x03 \x01(\t\x12\x13\n\x0bupdate_file\x18\x04 \x01(\t\x12\x14\n\x0cUNKNOWN_NUM5\x18\x05 \x01(\x03\x12G\n\nfiles_list\x18\x06 \x03(\x0b\x32\x33.GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo\x12\x13\n\x0bproduct_sku\x18\x08 \x01(\t\x12\x12\n\nfw_version\x18\t \x01(\t\x12\x16\n\x0eUNKNOWN_FLAG10\x18\n \x01(\x03\x12\x10\n\x08language\x18\x0b \x01(\t\x12\x16\n\x0eUNKNOWN_FLAG12\x18\x0c \x01(\x03\x12\x11\n\tfile_type\x18\x0e \x01(\t\x12\x15\n\rUNKNOWN_STR15\x18\x0f \x01(\t\x1aM\n\x08\x46ileInfo\x12\x14\n\x0cUNKNOWN_NUM1\x18\x01 \x01(\x03\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x0b\n\x03md5\x18\x03 \x01(\t\x12\x11\n\tfile_size\x18\x04 \x01(\x03\x62\x06proto3')
)
_GETALLUNITSOFTWAREUPDATES_CLIENTDATA = _descriptor.Descriptor(
name='ClientData',
full_name='GetAllUnitSoftwareUpdates.ClientData',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='client', full_name='GetAllUnitSoftwareUpdates.ClientData.client', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='language', full_name='GetAllUnitSoftwareUpdates.ClientData.language', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='client_platform', full_name='GetAllUnitSoftwareUpdates.ClientData.client_platform', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='client_platform_version', full_name='GetAllUnitSoftwareUpdates.ClientData.client_platform_version', index=3,
number=4, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=145,
serialized_end=249,
)
_GETALLUNITSOFTWAREUPDATES = _descriptor.Descriptor(
name='GetAllUnitSoftwareUpdates',
full_name='GetAllUnitSoftwareUpdates',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='client_data', full_name='GetAllUnitSoftwareUpdates.client_data', index=0,
number=1, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='device_xml', full_name='GetAllUnitSoftwareUpdates.device_xml', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_GETALLUNITSOFTWAREUPDATES_CLIENTDATA, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=36,
serialized_end=249,
)
_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO_FILEINFO = _descriptor.Descriptor(
name='FileInfo',
full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='UNKNOWN_NUM1', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo.UNKNOWN_NUM1', index=0,
number=1, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='url', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo.url', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='md5', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo.md5', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='file_size', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo.file_size', index=3,
number=4, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=692,
serialized_end=769,
)
_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO = _descriptor.Descriptor(
name='UpdateInfo',
full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='changelog', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.changelog', index=0,
number=1, type=9, cpp_type=9, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='device_name', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.device_name', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='license_url', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.license_url', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='update_file', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.update_file', index=3,
number=4, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='UNKNOWN_NUM5', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.UNKNOWN_NUM5', index=4,
number=5, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='files_list', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.files_list', index=5,
number=6, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='product_sku', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.product_sku', index=6,
number=8, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='fw_version', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.fw_version', index=7,
number=9, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='UNKNOWN_FLAG10', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.UNKNOWN_FLAG10', index=8,
number=10, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='language', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.language', index=9,
number=11, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='UNKNOWN_FLAG12', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.UNKNOWN_FLAG12', index=10,
number=12, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='file_type', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.file_type', index=11,
number=14, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='UNKNOWN_STR15', full_name='GetAllUnitSoftwareUpdatesReply.UpdateInfo.UNKNOWN_STR15', index=12,
number=15, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO_FILEINFO, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=352,
serialized_end=769,
)
_GETALLUNITSOFTWAREUPDATESREPLY = _descriptor.Descriptor(
name='GetAllUnitSoftwareUpdatesReply',
full_name='GetAllUnitSoftwareUpdatesReply',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='update_info', full_name='GetAllUnitSoftwareUpdatesReply.update_info', index=0,
number=1, type=11, cpp_type=10, label=3,
has_default_value=False, default_value=[],
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO, ],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=252,
serialized_end=769,
)
_GETALLUNITSOFTWAREUPDATES_CLIENTDATA.containing_type = _GETALLUNITSOFTWAREUPDATES
_GETALLUNITSOFTWAREUPDATES.fields_by_name['client_data'].message_type = _GETALLUNITSOFTWAREUPDATES_CLIENTDATA
_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO_FILEINFO.containing_type = _GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO
_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO.fields_by_name['files_list'].message_type = _GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO_FILEINFO
_GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO.containing_type = _GETALLUNITSOFTWAREUPDATESREPLY
_GETALLUNITSOFTWAREUPDATESREPLY.fields_by_name['update_info'].message_type = _GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO
DESCRIPTOR.message_types_by_name['GetAllUnitSoftwareUpdates'] = _GETALLUNITSOFTWAREUPDATES
DESCRIPTOR.message_types_by_name['GetAllUnitSoftwareUpdatesReply'] = _GETALLUNITSOFTWAREUPDATESREPLY
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
GetAllUnitSoftwareUpdates = _reflection.GeneratedProtocolMessageType('GetAllUnitSoftwareUpdates', (_message.Message,), dict(
ClientData = _reflection.GeneratedProtocolMessageType('ClientData', (_message.Message,), dict(
DESCRIPTOR = _GETALLUNITSOFTWAREUPDATES_CLIENTDATA,
__module__ = 'GetAllUnitSoftwareUpdates_pb2'
# @@protoc_insertion_point(class_scope:GetAllUnitSoftwareUpdates.ClientData)
))
,
DESCRIPTOR = _GETALLUNITSOFTWAREUPDATES,
__module__ = 'GetAllUnitSoftwareUpdates_pb2'
# @@protoc_insertion_point(class_scope:GetAllUnitSoftwareUpdates)
))
_sym_db.RegisterMessage(GetAllUnitSoftwareUpdates)
_sym_db.RegisterMessage(GetAllUnitSoftwareUpdates.ClientData)
GetAllUnitSoftwareUpdatesReply = _reflection.GeneratedProtocolMessageType('GetAllUnitSoftwareUpdatesReply', (_message.Message,), dict(
UpdateInfo = _reflection.GeneratedProtocolMessageType('UpdateInfo', (_message.Message,), dict(
FileInfo = _reflection.GeneratedProtocolMessageType('FileInfo', (_message.Message,), dict(
DESCRIPTOR = _GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO_FILEINFO,
__module__ = 'GetAllUnitSoftwareUpdates_pb2'
# @@protoc_insertion_point(class_scope:GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo)
))
,
DESCRIPTOR = _GETALLUNITSOFTWAREUPDATESREPLY_UPDATEINFO,
__module__ = 'GetAllUnitSoftwareUpdates_pb2'
# @@protoc_insertion_point(class_scope:GetAllUnitSoftwareUpdatesReply.UpdateInfo)
))
,
DESCRIPTOR = _GETALLUNITSOFTWAREUPDATESREPLY,
__module__ = 'GetAllUnitSoftwareUpdates_pb2'
# @@protoc_insertion_point(class_scope:GetAllUnitSoftwareUpdatesReply)
))
_sym_db.RegisterMessage(GetAllUnitSoftwareUpdatesReply)
_sym_db.RegisterMessage(GetAllUnitSoftwareUpdatesReply.UpdateInfo)
_sym_db.RegisterMessage(GetAllUnitSoftwareUpdatesReply.UpdateInfo.FileInfo)
# @@protoc_insertion_point(module_scope)

91
grmn/updateserver.py Normal file
View File

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
from . import devices
from .proto import GetAllUnitSoftwareUpdates_pb2
from xml.dom.minidom import getDOMImplementation
import requests
PROTO_API_GETALLUNITSOFTWAREUPDATES_URL = "http://omt.garmin.com/Rce/ProtobufApi/SoftwareUpdateService/GetAllUnitSoftwareUpdates"
GRMN_CLIENT_VERSION = "5.7.0.2"
class UpdateServer:
def query_updates(self, sku_numbers):
device_xml = self.get_device_xml(sku_numbers)
reply = self.get_unit_updates(device_xml)
print(reply)
def dom_add_text(self, doc, parent, elem_name, text):
e = doc.createElement(elem_name)
t = doc.createTextNode(text)
e.appendChild(t)
parent.appendChild(e)
def get_device_xml(self, sku_numbers):
dom = getDOMImplementation()
doc = dom.createDocument(None, "Device", None)
root = doc.documentElement
root.setAttribute("xmlns", "http://www.garmin.com/xmlschemas/GarminDevice/v2")
root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
root.setAttribute("xsi:schemaLocation", "http://www.garmin.com/xmlschemas/GarminDevice/v2 http://www.garmin.com/xmlschemas/GarminDevicev2.xsd")
model = doc.createElement("Model")
self.dom_add_text(doc, model, "PartNumber", sku_numbers[0])
self.dom_add_text(doc, model, "SoftwareVersion", "1")
self.dom_add_text(doc, model, "Description", "-")
root.appendChild(model)
self.dom_add_text(doc, root, "Id", "2345678910")
msm = doc.createElement("MassStorageMode")
for sku in sku_numbers:
uf = doc.createElement("UpdateFile")
self.dom_add_text(doc, uf, "PartNumber", sku)
v = doc.createElement("Version")
self.dom_add_text(doc, v, "Major", "0")
self.dom_add_text(doc, v, "Minor", "1")
self.dom_add_text(doc, uf, "Path", "GARMIN")
self.dom_add_text(doc, uf, "FileName", "GUPDATE.GCD")
msm.appendChild(uf)
root.appendChild(msm)
xml = doc.toxml()
return xml
def get_unit_updates(self, device_xml):
query = GetAllUnitSoftwareUpdates_pb2.GetAllUnitSoftwareUpdates()
query.client_data.client = "express"
query.client_data.language ="en_US"
query.client_data.client_platform = "Windows"
query.client_data.client_platform_version = "601 Service Pack 1"
query.device_xml = device_xml
proto_msg = query.SerializeToString()
headers = {
"User-Agent": "Garmin Core Service Win - {}".format(GRMN_CLIENT_VERSION),
"Garmin-Client-Name": "CoreService",
"Garmin-Client-Version": GRMN_CLIENT_VERSION,
"X-garmin-client-id": "EXPRESS",
"Garmin-Client-Platform": "windows",
"Garmin-Client-Platform-Version": "601",
"Garmin-Client-Platform-Version-Revision": "1",
"Content-Type": "application/octet-stream",
}
r = requests.post(PROTO_API_GETALLUNITSOFTWAREUPDATES_URL, headers=headers, data=proto_msg)
if r.status_code != 200:
r.raise_for_status()
return None
#print(r.content)
with open("protoreply.bin", "wb") as f:
f.write(r.content)
f.close()
reply = GetAllUnitSoftwareUpdates_pb2.GetAllUnitSoftwareUpdatesReply()
reply.ParseFromString(r.content)
return reply

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
protobuf