From b5b60388491f3fb31ef5d69331130b5567f553d5 Mon Sep 17 00:00:00 2001 From: Markus Birth Date: Tue, 10 Sep 2019 05:00:35 +0200 Subject: [PATCH] Started support for querying update servers. --- get_updates.py | 31 ++ grmn/proto/GetAllUnitSoftwareUpdates.proto | 39 +++ grmn/proto/GetAllUnitSoftwareUpdates_pb2.py | 361 ++++++++++++++++++++ grmn/updateserver.py | 91 +++++ requirements.txt | 1 + 5 files changed, 523 insertions(+) create mode 100644 get_updates.py create mode 100644 grmn/proto/GetAllUnitSoftwareUpdates.proto create mode 100644 grmn/proto/GetAllUnitSoftwareUpdates_pb2.py create mode 100644 grmn/updateserver.py create mode 100644 requirements.txt diff --git a/get_updates.py b/get_updates.py new file mode 100644 index 0000000..bcb6b71 --- /dev/null +++ b/get_updates.py @@ -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]) diff --git a/grmn/proto/GetAllUnitSoftwareUpdates.proto b/grmn/proto/GetAllUnitSoftwareUpdates.proto new file mode 100644 index 0000000..c3e2b8f --- /dev/null +++ b/grmn/proto/GetAllUnitSoftwareUpdates.proto @@ -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; +} diff --git a/grmn/proto/GetAllUnitSoftwareUpdates_pb2.py b/grmn/proto/GetAllUnitSoftwareUpdates_pb2.py new file mode 100644 index 0000000..aaf0938 --- /dev/null +++ b/grmn/proto/GetAllUnitSoftwareUpdates_pb2.py @@ -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) diff --git a/grmn/updateserver.py b/grmn/updateserver.py new file mode 100644 index 0000000..3479227 --- /dev/null +++ b/grmn/updateserver.py @@ -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 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b0c79cc --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +protobuf