Garmin: Add Support for Descent Mk3(i).

Add support for the Garmin Descent Mk3(i) models.
This pretty much just updates the entry in the device list to cover Mk2
and Mk3 models.
It does nothing to add support for MTP when reading from an Mk3 model -
I have not been able to get MTP support on linux going reliably, and I
do not have an Mk2 / Mk3 to test with anyway.
I suspect that MTP support is incomplete anyway, as the
product IDs for models like the Mk2S and Mk2G are not detected.
This change also adds an extra info field for the Model (based on a
heuristic and incomplete list).
It also fixes the data type for the sensor_type field.

Signed-off-by: Michael Keller <mikeller@042.ch>
This commit is contained in:
Michael Keller 2024-04-19 15:29:28 +12:00 committed by Michael Keller
parent 62a29eea15
commit 792090566e
3 changed files with 37 additions and 8 deletions

View File

@ -471,10 +471,11 @@ static const dc_descriptor_t g_descriptors[] = {
// Not merged upstream yet
/* Garmin -- model numbers as defined in FIT format; USB product id is (0x4000 | model) */
/* for the Mk1 we are using the model of the global model - the APAC model is 2991 */
/* for the Mk2 we are using the model of the global model - the APAC model is 3702 */
/* for the Mk1 we are using the model of the global model */
/* for the Mk2/Mk3 we are using the model of the Mk2 global model */
/* see garmin_parser.c for a more comprehensive list of models */
{"Garmin", "Descent Mk1", DC_FAMILY_GARMIN, 2859, DC_TRANSPORT_USBSTORAGE, dc_filter_garmin},
{"Garmin", "Descent Mk2/Mk2i", DC_FAMILY_GARMIN, 3258, DC_TRANSPORT_USBSTORAGE, dc_filter_garmin},
{"Garmin", "Descent Mk2(i)/Mk3(i)", DC_FAMILY_GARMIN, 3258, DC_TRANSPORT_USBSTORAGE, dc_filter_garmin},
{"FIT", "File import", DC_FAMILY_GARMIN, 0, DC_TRANSPORT_USBSTORAGE, NULL },
};

View File

@ -101,7 +101,6 @@ garmin_device_open (dc_device_t **out, dc_context_t *context, dc_iostream_t *ios
// in order to have only one entry for the Mk2, we don't use the Mk2/APAC model number in our code
device->use_mtp = (model == (0x0FFF & DESCENT_MK2));
device->mtp_device = NULL;
DEBUG(context, "Found Garmin with model 0x%x which is a %s\n", model, (device->use_mtp ? "Mk2/Mk2i" : "Mk1"));
#endif
*out = (dc_device_t *) device;
@ -331,12 +330,16 @@ mtp_get_file_list(dc_device_t *abstract, struct file_list *files)
for (i = 0; i < numrawdevices; i++) {
LIBMTP_devicestorage_t *storage;
// we only want to read from a Garmin Descent Mk2 device at this point
if (rawdevices[i].device_entry.vendor_id != GARMIN_VENDOR ||
(rawdevices[i].device_entry.product_id != DESCENT_MK2 && rawdevices[i].device_entry.product_id != DESCENT_MK2_APAC)) {
if (rawdevices[i].device_entry.vendor_id != GARMIN_VENDOR) {
DEBUG(abstract->context, "Garmin/mtp: skipping raw device %04x/%04x",
rawdevices[i].device_entry.vendor_id, rawdevices[i].device_entry.product_id);
continue;
}
if (rawdevices[i].device_entry.product_id != DESCENT_MK2 && rawdevices[i].device_entry.product_id != DESCENT_MK2_APAC) {
DEBUG(abstract->context, "Garmin/mtp: skipping Garmin raw device %04x/%04x, as it is not a dive computer / does not support MTP",
rawdevices[i].device_entry.vendor_id, rawdevices[i].device_entry.product_id);
continue;
}
device->mtp_device = LIBMTP_Open_Raw_Device_Uncached(&rawdevices[i]);
if (device->mtp_device == NULL) {
DEBUG(abstract->context, "Garmin/mtp: unable to open raw device %d", i);

View File

@ -797,7 +797,7 @@ DECLARE_FIELD(SENSOR_PROFILE, enabled, ENUM)
{
current_sensor(garmin)->sensor_enabled = data;
}
DECLARE_FIELD(SENSOR_PROFILE, sensor_type, UINT8)
DECLARE_FIELD(SENSOR_PROFILE, sensor_type, ENUM)
{
// 28 is tank pod
// start filling in next sensor after this record
@ -1090,7 +1090,7 @@ DECLARE_MESG(SENSOR_PROFILE) = {
SET_FIELD(SENSOR_PROFILE, 0, ant_channel_id, UINT32Z), // derived from the number engraved on the side
SET_FIELD(SENSOR_PROFILE, 2, name, STRING),
SET_FIELD(SENSOR_PROFILE, 3, enabled, ENUM),
SET_FIELD(SENSOR_PROFILE, 52, sensor_type, UINT8), // 28 is tank pod
SET_FIELD(SENSOR_PROFILE, 52, sensor_type, ENUM), // 28 is tank pod
SET_FIELD(SENSOR_PROFILE, 74, pressure_units, ENUM), // 0 is PSI, 1 is KPA (unused), 2 is Bar
SET_FIELD(SENSOR_PROFILE, 75, rated_pressure, UINT16),
SET_FIELD(SENSOR_PROFILE, 76, reserve_pressure, UINT16),
@ -1615,6 +1615,20 @@ static void add_sensor_string(garmin_parser_t *garmin, const char *desc, const s
static dc_status_t
garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsigned int size)
{
// This list is empirical and somewhat speculative
// will have to be confirmed with Garmin
static const struct {
int id;
const char *name;
} models[] = {
{ 2859, "Descent Mk1" },
{ 2991, "Descent Mk1 APAC" },
{ 3258, "Descent Mk2(i)" },
{ 3542, "Descent Mk2s" },
{ 3702, "Descent Mk2 APAC" },
{ 4223, "Descent Mk3" },
};
/* Walk the data once without a callback to set up the core fields */
garmin->callback = NULL;
garmin->userdata = NULL;
@ -1630,6 +1644,17 @@ garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsi
if (garmin->dive.firmware)
dc_field_add_string_fmt(&garmin->cache, "Firmware", "%u.%02u",
garmin->dive.firmware / 100, garmin->dive.firmware % 100);
if (garmin->dive.product) {
int i = 0;
for (i = 0; i < C_ARRAY_SIZE(models); i++)
if (models[i].id == garmin->dive.product)
break;
if (i < C_ARRAY_SIZE(models))
dc_field_add_string_fmt(&garmin->cache, "Model", "%s", models[i].name);
else
dc_field_add_string_fmt(&garmin->cache, "Model", "Unknown model ID: %u", garmin->dive.product);
}
// These seem to be the "real" GPS dive coordinates
add_gps_string(garmin, "GPS1", &garmin->gps.SESSION.entry);