Skip to content

Commit 6a2fbe4

Browse files
committed
Garmin: Add MTP Support for More Models.
Add MTP support for more of the newer Garmin Descent models. Signed-off-by: Michael Keller <[email protected]>
1 parent 2e6aab2 commit 6a2fbe4

File tree

3 files changed

+47
-28
lines changed

3 files changed

+47
-28
lines changed

src/garmin.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
#include "libmtp.h"
4040

4141
#define GARMIN_VENDOR 0x091E
42-
#define DESCENT_MK2 0x4CBA
43-
#define DESCENT_MK2_APAC 0x4E76
42+
43+
#define DESCENT_MK2 3258
4444

4545
// deal with ancient libmpt found on older Linux distros
4646
#ifndef LIBMTP_FILES_AND_FOLDERS_ROOT
@@ -59,6 +59,24 @@ typedef struct garmin_device_t {
5959
#endif
6060
} garmin_device_t;
6161

62+
// Ids can be found at https://developer.garmin.com/connect-iq/reference-guides/devices-reference/
63+
// (look for 'Part Number')
64+
65+
const garmin_model_t garmin_models[] = {
66+
{ "Descent™ G1 / G1 Solar", 4005, true },
67+
{ "Descent™ G2", 4588, true },
68+
{ "Descent™ Mk1", 2859, false },
69+
{ "Descent™ Mk1 APAC", 2991, false },
70+
{ "Descent™ Mk2(i)", 3258, true },
71+
{ "Descent™ Mk2(i) APAC", 3702, true },
72+
{ "Descent™ Mk2 S", 3542, true },
73+
{ "Descent™ Mk2 S APAC", 3930, true },
74+
{ "Descent™ Mk3(i) 43mm", 4222, true },
75+
{ "Descent™ Mk3(i) 51mm", 4223, true },
76+
{ "Descent™ X50i", 4518, true },
77+
{ NULL, 0, false }
78+
};
79+
6280
static dc_status_t garmin_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size);
6381
static dc_status_t garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata);
6482
static dc_status_t garmin_device_close (dc_device_t *abstract);
@@ -99,7 +117,7 @@ garmin_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *ios
99117
// for a Descent Mk2/Mk2i, we have to use MTP to access its storage;
100118
// for Garmin devices, the model number corresponds to the lower three nibbles of the USB product ID
101119
// in order to have only one entry for the Mk2, we don't use the Mk2/APAC model number in our code
102-
device->use_mtp = (model == (0x0FFF & DESCENT_MK2));
120+
device->use_mtp = model == DESCENT_MK2;
103121
device->mtp_device = NULL;
104122
#endif
105123

@@ -335,7 +353,17 @@ mtp_get_file_list(dc_device_t *abstract, struct file_list *files)
335353
rawdevices[i].device_entry.vendor_id, rawdevices[i].device_entry.product_id);
336354
continue;
337355
}
338-
if (rawdevices[i].device_entry.product_id != DESCENT_MK2 && rawdevices[i].device_entry.product_id != DESCENT_MK2_APAC) {
356+
357+
bool mtp_capable = false;
358+
for (unsigned j = 0; garmin_models[j].name; j++) {
359+
if ((garmin_models[j].id | 0x4000) == rawdevices[i].device_entry.product_id) {
360+
mtp_capable = garmin_models[j].mtp_capable;
361+
362+
break;
363+
}
364+
}
365+
366+
if (!mtp_capable) {
339367
DEBUG(abstract->context, "Garmin/mtp: skipping Garmin raw device %04x/%04x, as it is not a dive computer / does not support MTP",
340368
rawdevices[i].device_entry.vendor_id, rawdevices[i].device_entry.product_id);
341369
continue;

src/garmin.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#ifndef GARMIN_H
2323
#define GARMIN_H
2424

25+
#include <stdbool.h>
26+
2527
#include <libdivecomputer/context.h>
2628
#include <libdivecomputer/iostream.h>
2729
#include <libdivecomputer/device.h>
@@ -31,6 +33,14 @@
3133
extern "C" {
3234
#endif /* __cplusplus */
3335

36+
typedef struct {
37+
const char *name;
38+
int id;
39+
bool mtp_capable;
40+
} garmin_model_t;
41+
42+
extern const garmin_model_t garmin_models[];
43+
3444
dc_status_t
3545
garmin_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model);
3646

src/garmin_parser.c

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,25 +1648,6 @@ static void add_sensor_string(garmin_parser_t *garmin, const char *desc, const s
16481648
static dc_status_t
16491649
garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsigned int size)
16501650
{
1651-
// Ids can be found at https://developer.garmin.com/connect-iq/reference-guides/devices-reference/
1652-
// (look for 'Part Number')
1653-
static const struct {
1654-
const char *name;
1655-
int id;
1656-
} models[] = {
1657-
{ "Descent™ G1 / G1 Solar", 4005 },
1658-
{ "Descent™ G2", 4588 },
1659-
{ "Descent™ Mk1", 2859 },
1660-
{ "Descent™ Mk1 APAC", 2991 },
1661-
{ "Descent™ Mk2(i)", 3258 },
1662-
{ "Descent™ Mk2(i) APAC", 3702 },
1663-
{ "Descent™ Mk2 S", 3542 },
1664-
{ "Descent™ Mk2 S APAC", 3930 },
1665-
{ "Descent™ Mk3(i) 43mm", 4222 },
1666-
{ "Descent™ Mk3(i) 51mm", 4223 },
1667-
{ "Descent™ X50i", 4518 },
1668-
};
1669-
16701651
/* Walk the data once without a callback to set up the core fields */
16711652
garmin->callback = NULL;
16721653
garmin->userdata = NULL;
@@ -1683,13 +1664,13 @@ garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsi
16831664
dc_field_add_string_fmt(&garmin->cache, "Firmware", "%u.%02u",
16841665
garmin->dive.firmware / 100, garmin->dive.firmware % 100);
16851666
if (garmin->dive.product) {
1686-
int i = 0;
1687-
for (i = 0; i < C_ARRAY_SIZE(models); i++)
1688-
if (models[i].id == garmin->dive.product)
1667+
unsigned i;
1668+
for (i = 0; garmin_models[i].name; i++)
1669+
if (garmin_models[i].id == garmin->dive.product)
16891670
break;
16901671

1691-
if (i < C_ARRAY_SIZE(models))
1692-
dc_field_add_string_fmt(&garmin->cache, "Model", "%s", models[i].name);
1672+
if (garmin_models[i].name)
1673+
dc_field_add_string_fmt(&garmin->cache, "Model", "%s", garmin_models[i].name);
16931674
else
16941675
dc_field_add_string_fmt(&garmin->cache, "Model", "Unknown model ID: %u", garmin->dive.product);
16951676
}

0 commit comments

Comments
 (0)