Shearwater: detect the hardware type

Stop pretending that all the devices since the Petrel are the same. They
actually aren't. So let's detect them and correctly identify them.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2017-07-07 16:33:13 -07:00
parent 04073759a8
commit 6f4776d6c4
3 changed files with 59 additions and 6 deletions

View File

@ -270,11 +270,12 @@ static const dc_descriptor_t g_descriptors[] = {
#endif #endif
/* Shearwater Predator */ /* Shearwater Predator */
{"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2}, {"Shearwater", "Predator", DC_FAMILY_SHEARWATER_PREDATOR, 2},
/* Shearwater Petrel */ /* Shearwater Petrel family */
{"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3}, {"Shearwater", "Petrel", DC_FAMILY_SHEARWATER_PETREL, 3},
{"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 3}, {"Shearwater", "Petrel 2", DC_FAMILY_SHEARWATER_PETREL, 4},
{"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 3}, {"Shearwater", "Nerd", DC_FAMILY_SHEARWATER_PETREL, 5},
{"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 3}, {"Shearwater", "Perdix", DC_FAMILY_SHEARWATER_PETREL, 6},
{"Shearwater", "Perdix AI", DC_FAMILY_SHEARWATER_PETREL, 7},
/* Dive Rite NiTek Q */ /* Dive Rite NiTek Q */
{"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0}, {"Dive Rite", "NiTek Q", DC_FAMILY_DIVERITE_NITEKQ, 0},
/* Citizen Hyper Aqualand */ /* Citizen Hyper Aqualand */

View File

@ -31,6 +31,14 @@ extern "C" {
#define ID_SERIAL 0x8010 #define ID_SERIAL 0x8010
#define ID_FIRMWARE 0x8011 #define ID_FIRMWARE 0x8011
#define ID_HARDWARE_TYPE 0x8050
#define PREDATOR 2
#define PETREL 3
#define PETREL2 4
#define NERD 5
#define PERDIX 6
#define PERDIXAI 7
typedef struct shearwater_common_device_t { typedef struct shearwater_common_device_t {
dc_device_t base; dc_device_t base;

View File

@ -199,9 +199,53 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
// Convert to a number. // Convert to a number.
unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1); unsigned int firmware = str2num (dc_buffer_get_data (buffer), dc_buffer_get_size (buffer), 1);
// get the product information
rc = shearwater_common_identifier (&device->base, buffer, ID_HARDWARE_TYPE);
if (rc != DC_STATUS_SUCCESS) {
ERROR (abstract->context, "Failed to read the hardware type.");
dc_buffer_free (buffer);
dc_buffer_free (manifests);
return rc;
}
// Emit a device info event. // Emit a device info event.
dc_event_devinfo_t devinfo; dc_event_devinfo_t devinfo;
devinfo.model = 3; if (dc_buffer_get_size (buffer) == 2) {
unsigned short model_code = array_uint16_be(dc_buffer_get_data (buffer));
switch (model_code) {
case 0x0101:
case 0x0202:
devinfo.model = PREDATOR;
break;
case 0x0606:
case 0x0A0A:
devinfo.model = NERD;
break;
case 0x0404:
case 0x0909:
case 0x0B0B:
devinfo.model = PETREL;
break;
case 0x0505:
case 0x0808:
devinfo.model = PETREL2;
break;
case 0x0707: // documentation list 0C0D for both Perdix and Perdix AI :-(
devinfo.model = PERDIX;
break;
case 0x0C0C:
case 0x0C0D:
case 0x0D0D:
devinfo.model = PERDIXAI;
break;
default:
devinfo.model = PETREL;
ERROR (abstract->context, "Unknown model code - assuming Petrel.");
}
} else {
devinfo.model = PERDIX;
ERROR (abstract->context, "Failed to read hardware type - assuming Petrel.");
}
devinfo.firmware = firmware; devinfo.firmware = firmware;
devinfo.serial = array_uint32_be (serial); devinfo.serial = array_uint32_be (serial);
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo); device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);