From 0e5c493ceabe9b5ce26f3258f634967b990fafda Mon Sep 17 00:00:00 2001 From: Thomas Kuehne Date: Sat, 20 Sep 2025 00:00:00 +0200 Subject: [PATCH] Garmin: add debug support to fetch the DEVICE_XML `Debug / Fetch device Debug Logs` now fetches the FILETYPE.DEVICE_XML instead of triggering a normal fetch. On some devices this file is readily available via USB on others this is the only way to retrieve it. Note: The features listed in DEVICE_XML and device.fit sometimes differ substantially and don't necessarily reflect the supported features. So far there is no known way to retrieve device.fit via Bluetooth. --- .../devices/garmin/FileTransferHandler.java | 26 ++++++++++++++++++- .../service/devices/garmin/GarminSupport.java | 6 +++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/FileTransferHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/FileTransferHandler.java index adfcab6196..fe0be21589 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/FileTransferHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/FileTransferHandler.java @@ -1,3 +1,19 @@ +/* Copyright (C) 2024-2025 Daniele Gobbetti, José Rebelo, Thomas Kuehne + + This file is part of Gadgetbridge. + + 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 . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin; import android.content.Intent; @@ -91,6 +107,13 @@ public class FileTransferHandler implements MessageHandler { download.setCurrentlyDownloading(new FileFragment(new DirectoryEntry(0, FileType.FILETYPE.DIRECTORY, 0, 0, 0, 0, null))); return new DownloadRequestMessage(0, 0, DownloadRequestMessage.REQUEST_TYPE.NEW, 0, 0); } + + public DownloadRequestMessage initiateDebugDownload() { + DirectoryEntry deviceXml = new DirectoryEntry(0xFFFD, FileType.FILETYPE.DEVICE_XML, 0xFFFD, 0, 0, 0, new Date()); + download.setCurrentlyDownloading(new FileFragment(deviceXml)); + return new DownloadRequestMessage(deviceXml.getFileIndex(), 0, DownloadRequestMessage.REQUEST_TYPE.NEW, 0, 0); + } + // public DownloadRequestMessage downloadSettings() { // download.setCurrentlyDownloading(new FileFragment(new DirectoryEntry(0, FileType.FILETYPE.SETTINGS, 0, 0, 0, 0, null))); // return new DownloadRequestMessage(0, 0, DownloadRequestMessage.REQUEST_TYPE.NEW, 0, 0); @@ -199,10 +222,11 @@ public CreateFileMessage initiateUpload(byte[] fileAsByteArray, FileType.FILETYP final DirectoryEntry directoryEntry = new DirectoryEntry(fileIndex, filetype, fileNumber, specificFlags, fileFlags, fileSize, fileDate); if (directoryEntry.filetype == null) { // discard unsupported files - LOG.warn("Unsupported directory entry of type {}/{}", fileDataType, fileSubType); + LOG.warn("Unsupported directory entry of type {}/{}: {}", fileDataType, fileSubType, directoryEntry); continue; } if (!FILE_TYPES_TO_PROCESS.contains(directoryEntry.filetype) && !fetchUnknownFiles) { + LOG.debug("Skipping directory entry: {}", directoryEntry); continue; } if (fileIndex == 0 && fileDataType == 0 && fileSubType == 0 && fileNumber == 0 && specificFlags == 0 && fileFlags == 0 && fileSize == 0) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java index ad0c7a7914..cd030b237f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/GarminSupport.java @@ -64,6 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; +import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes; import nodomain.freeyourgadget.gadgetbridge.model.weather.Weather; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.proto.garmin.GdiCore; @@ -447,6 +448,11 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC return; } + if (dataTypes == RecordedDataTypes.TYPE_DEBUGLOGS){ + sendOutgoingMessage("fetch debug data", fileTransferHandler.initiateDebugDownload()); + return; + } + // FIXME respect dataTypes? // We initiate download here even in the new sync protocol so that the watch "flushes" the data