Skip to content

Update libdivecomputer to Latest from Upstream. - #120

Open
mikeller wants to merge 20 commits into
subsurface:Subsurface-DS9from
mikeller:update_libdivecomputer_202608
Open

Update libdivecomputer to Latest from Upstream.#120
mikeller wants to merge 20 commits into
subsurface:Subsurface-DS9from
mikeller:update_libdivecomputer_202608

Conversation

@mikeller

Copy link
Copy Markdown
Member
  • Ignore all invalid end-of-profile pointer values
  • Add support for the Mares Sirius L
  • Use the GNSS status to ignore invalid locations
  • Read the shearwater model number directly
  • Fix the clock synchronization for DC_TIMEZONE_NONE
  • Add a new location sample to report multiple GPS locations
  • Rename a local variable
  • Fix some small typos
  • Use memcmp to compare the service key
  • Integrate the frog code into the ostc3 backend
  • Use a symbolic constants for the commands
  • Handle variable sized packets
  • Add Shearwater Perdix 3 support
  • Update the minimum and maximum BLE packet size
  • Fix the Seac Tablet memory size
  • Remove deprecated AC_PROG_CC_C99 autoconf macro
  • Fix the closing tags of the location elements
  • Fix build errors from libdivecomputer master merge

jefdriesen and others added 19 commits May 11, 2026 09:06
The end-of-profile pointer can be stored in two different locations
(possibly as a simple wear leveling mechanism). Each location is
expected to contain either a valid value or 0xffffffff to indicate the
alternative location should be used.

In a bugreport, a Nemo Wide 2 device appears to have some kind of data
corruption issue, where 0x7f bytes are present in the invalid value
instead of the expected 0xff bytes. As a workaround, ignore all out of
range values.
The Sirius L uses the Genius/Sirius variant of the protocol, with a new
model number (0x33) and bluetooth device name. The model number was
confirmed against a factory-new unit on firmware 01.00.01: the version
packet reports the product name "Sirius L" at offset 0x46, and the
OBJ_DEVICE_MODEL response returns 0x33.
The GNSS status field indicates whether the longitude and latitude
fields contain valid location data. This is more reliable than checking
for the magic values zero and 0xFFFFFFFF, which are technically valid
locations (although also very unlikely dive locations).
The Shearwater dive computers support reading the model number directly
with the RDBI command 0x8060. This previously unknown feature eliminates
the need to first read the hardware type and then map it onto the
corresponding model number. Since new hardware types are introduced
relative frequently, the mapping was always a bit out of date.
Because the special DC_TIMEZONE_NONE value is out of range for a valid
UTC offset, setting the clock fails with DC_STATUS_INVALIDARGS. Assume
an UTC offset of zero instead.
Some of the dive computers with an integrated GPS receiver use a data
format that is capable of reporting multiple GPS coordinates throughout
the dive. Add a new location sample to support this feature and update
all dive computer backends to use it.

The existing location field remains available for dive computers which
can only support a single location that is not linked to a sample.
Currently there are no such computers left anymore.

In practice, only the Halycon Symbios appears to report multiple GPS
locations. The Shearwater Swift records the entry and exit location and
those locations are now both reported, respectively on the first and
last sample.
Using a variable named "status" for the display message is confusing
because that name is typically used for the return value of a function.
The service key is already hardcoded in the command and doesn't need to
be repeated a second time.
The communication protocol used by the frog is almost identical to the
ostc3 protocol, with a few small differences:

 - No profile length stored in the dive header. The length must be
   calculated from the profile begin/end pointers instead.
 - Smaller display message (15 vs 16 characters)
 - Smaller custom text (13 vs 60 characters)
 - Smaller firmware size (116K vs 120K)
 - Different service key
 - Different firmware encryption key

These differences can easily be handled in the ostc3 backend. The main
improvement is less code duplication.

For features not supported by the frog, the corresponding commands will
fail at runtime with DC_STATUS_UNSUPPORTED, just like with the ostc3.
The exceptions are the INIT and HEADER commands, but those two commands
are supported by the frog.

The following functions are removed from the public api and can be
replaced with the corresponding ostc3 variant:

 - hw_frog_device_version
 - hw_frog_device_display
 - hw_frog_device_customtext
The response to the upload init command contains the maximum length of
the data packets which will be received in the next stage of the
communication. This length field has a variable length and the number of
bytes is indicated in the upper nibble of the second byte.

Update the code to handle response packets with a multibyte length.
The Shearwater Perdix 3 uses a new variant of the communication
protocol, with the following changes:

 - New BLE GATT service and characteristics:

	 Service: 1aa44039-1667-4b29-87cc-dfecaaf31d97
     Rx characteristic: e8460acd-e525-477d-bc50-c743e08d23f4 (write-without-response)
     Tx characteristic: cd5683d6-eb69-4012-9e5b-9083e419cef2 (notify)

 - The 2 byte BLE packet header containing the total number of frames
   and the current frame number is no longer present.

 - The header of each frame changed to support larger frames:

   - The length field changed from an 8 bit value to 16 bit value,
	 increasing the total length of the header to 5 bytes.
   - The existing 0x00 byte moved to a different location. It's now
	 before the length field instead of after the length field.

 - The block request command has an extra 0x00 byte.

The new protocol variant is selected based on the model number of the
Perdix 3.

Co-authored-by: Steve Houle <steve@shoule.ca>
Co-authored-by: Jef Driesen <jef@libdivecomputer.org>
For maximum compatibility, use the minimum ATT MTU size (23 bytes) for
sending and the maximum ATT MTU size (517 bytes) for receiving. The
corresponding payload size is always 3 bytes smaller (20 and 514 bytes).
The Seac Tablet has twice the amount of flash memory compared to the
older models.
Since autoconf 2.70, the AC_PROG_CC_C99 macro is deprecated and can be
replaced with the AC_PROG_CC macro, which will automatically check for
C99 or later.

For backwards compatibility, the use of the macro is preserved for older
autoconf versions.
The latitude and altitude elements are written with a second opening tag
instead of a closing tag, in both the dive location and the sample
location output. The resulting document is not well-formed XML.
Copilot AI lite review requested due to automatic review settings August 21, 2026 07:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR syncs libdivecomputer with upstream by adding support for new devices/features (notably GNSS/location improvements and Mares Sirius L), integrating Frog support into the OSTC3 backend, and applying a set of build/API updates.

Changes:

  • Add per-sample GPS location reporting via new DC_SAMPLE_LOCATION and update multiple parsers/output to emit it.
  • Integrate Frog protocol support into the hw_ostc3 backend and remove the standalone hw_frog backend/files.
  • Device support and robustness fixes (Mares Sirius L, Seac Tablet memory size, GNSS-status filtering, various protocol/build fixes).

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/shearwater_predator_parser.c Adds GNSS status handling and emits location samples (also introduces GNSS macro duplication).
src/shearwater_petrel.c Improves model read error wording and adds debug hexdump for the model number.
src/shearwater_common.h Adds/renames Shearwater WDBI/time/model identifiers.
src/seac_screen.c Updates Seac Tablet ringbuffer/profile memory end address.
src/parser.c Removes hw_frog include as Frog is integrated into OSTC3 backend.
src/mares_iconhd.c Adds Mares Sirius L model handling and tightens end-of-profile pointer validation.
src/mares_iconhd_parser.c Adds Mares Sirius L model constant support in the parser.
src/Makefile.am Removes hw_frog.* from build sources.
src/libdivecomputer.symbols Removes exported hw_frog_device_* symbols.
src/hw_ostc3.h Changes hw_ostc3_device_open signature to include a frog parameter.
src/hw_ostc3.c Integrates Frog protocol/layout/key handling into OSTC3 backend; updates packet sizes and firmware handling.
src/hw_frog.h Removes the internal Frog backend header.
src/hw_frog.c Removes the standalone Frog backend implementation.
src/halcyon_symbios_parser.c Switches from single cached location field to emitting DC_SAMPLE_LOCATION events.
src/divesystem_idive.c Fixes timezone handling for DC_TIMEZONE_NONE during timesync.
src/divesystem_idive_parser.c Switches to emitting DC_SAMPLE_LOCATION events and adjusts GPS parsing flow.
src/divesoft_freedom_parser.c Switches from cached location field to emitting DC_SAMPLE_LOCATION events.
src/device.c Routes Frog opens through hw_ostc3_device_open(..., frog=1) and OSTC3 opens through frog=0.
src/descriptor.c Adds Mares “Sirius L” descriptor and filter string.
include/libdivecomputer/parser.h Adds DC_SAMPLE_LOCATION and a dc_location_t member to dc_sample_value_t.
include/libdivecomputer/Makefile.am Removes public hw_frog.h from installed headers.
include/libdivecomputer/hw_ostc3.h Adds Frog display/customtext size constants.
include/libdivecomputer/hw_frog.h Removes public Frog header/API surface.
examples/output_xml.c Emits <location> for DC_SAMPLE_LOCATION and fixes XML closing tags for field location.
contrib/msvc/libdivecomputer.vcxproj Removes Frog source/header entries from MSVC project.
contrib/android/Android.mk Removes Frog source from Android build.
configure.ac Makes AC_PROG_CC_C99 conditional for older autoconf versions.
Suppressed comments (2)

src/shearwater_predator_parser.c:130

  • GNSS_FIX_2D/GNSS_FIX_3D are defined twice (once in the new GNSS_* block and again a few lines later), which will trigger macro redefinition warnings/errors on some compilers.
#define GNSS_FIX_2D 2
#define GNSS_FIX_3D 3

src/libdivecomputer.symbols:147

  • Removing the exported hw_frog_device_* symbols is an ABI/API breaking change for downstream consumers that directly call these helpers. If this library versioning expects ABI stability, consider keeping deprecated wrapper symbols that forward to hw_ostc3_device_* (or bump the SONAME/major version accordingly).
hw_ostc_device_reset
hw_ostc_device_screenshot
hw_ostc_device_fwupdate
hw_ostc3_device_version
hw_ostc3_device_hardware
hw_ostc3_device_display
hw_ostc3_device_customtext

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/device.c
Comment on lines 187 to 192
case DC_FAMILY_HW_FROG:
rc = hw_frog_device_open (&device, context, iostream);
rc = hw_ostc3_device_open (&device, context, iostream, 1);
break;
case DC_FAMILY_HW_OSTC3:
rc = hw_ostc3_device_open (&device, context, iostream);
rc = hw_ostc3_device_open (&device, context, iostream, 0);
break;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct upstream behaviour — the Frog integration into the OSTC3 backend is an upstream design decision. In the upstream libdivecomputer, DC_FAMILY_HW_FROG devices are intentionally routed through the OSTC3 backend, which means dc_device_get_type() will return DC_FAMILY_HW_OSTC3 for them. Subsurface does not branch on dc_device_get_type() for the Frog; it uses the descriptor family from the device descriptor, so this does not affect Subsurface. Out of scope for this sync PR.

Comment on lines 383 to 386
break;
case DC_FIELD_LOCATION:
if (!parser->have_location)
return DC_STATUS_UNSUPPORTED;
location->latitude = parser->latitude / 10000000.0;
location->longitude = parser->longitude / 10000000.0;
location->altitude = parser->altitude / 1000.0;
break;
default:
return DC_STATUS_UNSUPPORTED;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a regression introduced by this merge — this is upstream's deliberate design. The upstream divesystem_idive_parser_get_field() at commit 1a6e1650 never had a DC_FIELD_LOCATION case either; iDive is a new per-sample-location parser that only emits DC_SAMPLE_LOCATION. Subsurface's core/libdivecomputer.cpp handles this correctly by consuming DC_SAMPLE_LOCATION from the sample callback and falling back to DC_FIELD_LOCATION for older parsers.

Comment on lines 288 to 292
decomodel->params.gf.high = parser->gf_hi;
break;
case DC_FIELD_LOCATION:
if (!parser->have_location)
return DC_STATUS_UNSUPPORTED;
location->latitude = parser->latitude / 1000000.0;
location->longitude = parser->longitude / 1000000.0;
location->altitude = 0.0;
break;
default:
return DC_STATUS_UNSUPPORTED;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for iDive: this is upstream's deliberate design, not a regression. The upstream halcyon_symbios_parser_get_field() at 1a6e1650 never had a DC_FIELD_LOCATION case. Halcyon Symbios is a new per-sample-location parser; DC_SAMPLE_LOCATION is the intended mechanism. Subsurface handles this correctly via the sample callback path.

Comment on lines 832 to 845
case DC_FIELD_DECOMODEL:
if (parser->vpm) {
decomodel->type = DC_DECOMODEL_VPM;
decomodel->conservatism = 0;
} else {
decomodel->type = DC_DECOMODEL_BUHLMANN;
decomodel->conservatism = 0;
decomodel->params.gf.low = parser->gf_lo;
decomodel->params.gf.high = parser->gf_hi;
}
break;
case DC_FIELD_LOCATION:
if (!parser->have_location)
return DC_STATUS_UNSUPPORTED;
location->latitude = parser->latitude / 1000000.0;
location->longitude = parser->longitude / 1000000.0;
location->altitude = 0.0;
break;
default:
return DC_STATUS_UNSUPPORTED;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for iDive and Halcyon: upstream's deliberate design. divesoft_freedom_parser_get_field() never had DC_FIELD_LOCATION in upstream at 1a6e1650. Divesoft Freedom is a new per-sample-location parser using DC_SAMPLE_LOCATION. Handled correctly by Subsurface's sample callback.

@mikeller

Copy link
Copy Markdown
Member Author

Addressed the Copilot review:

Fixed: The GNSS_FIX_2D/GNSS_FIX_3D duplicate macro definitions in shearwater_predator_parser.c (lines 129–130) were a genuine merge artefact — the fork's old bare defines were left in when the fuller upstream GNSS_* block came in. Removed the duplicates; the canonical aligned definitions at lines 122–123 remain. Will need a force-push to update the PR branch.

Not actioned (upstream design, not regressions):

  • The three DC_FIELD_LOCATION "regression" findings for iDive, Halcyon Symbios, and Divesoft Freedom — verified against upstream 1a6e1650: none of these parsers ever had a DC_FIELD_LOCATION case. They are new per-sample-location parsers; DC_SAMPLE_LOCATION is the intended mechanism. Subsurface handles this via the sample callback path with a DC_FIELD_LOCATION fallback for older parsers.
  • The Frog/OSTC3 family-type concern — upstream design; Subsurface does not branch on dc_device_get_type() for Frog devices.
  • The hw_frog_device_* ABI removal — consequence of upstream's integration; this fork is vendored into Subsurface and is not ABI-versioned for external consumers.

Copilot AI review requested due to automatic review settings August 21, 2026 08:14
@mikeller
mikeller force-pushed the update_libdivecomputer_202608 branch from cb34af2 to affdbf8 Compare August 21, 2026 08:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/hw_ostc3.c:1031

  • The compact ? ... : ... expression is mixed with || without parentheses, which changes the meaning due to C operator precedence (?: has lower precedence than ||). As written, this can fail to detect a mismatched version/header when compact is false (or incorrectly gate the check on compact). Wrap the ternary in parentheses (and, for the compact branch, wrap the two memcmp checks) so the condition matches the intended logic.
		if (memcmp (profile + layout->version, header + offset + logbook->version, 1) != 0 ||
			compact ?
			memcmp (profile + layout->fingerprint, header + offset + logbook->fingerprint, 10) != 0 ||
			memcmp (profile + layout->number, header + offset + logbook->number, 2) != 0 :
			memcmp (profile + layout->fingerprint, header + offset + layout->fingerprint, RB_LOGBOOK_SIZE_FULL - layout->fingerprint) != 0) {

@mikeller

Copy link
Copy Markdown
Member Author

Re: the second Copilot review (hw_ostc3.c:1031, operator precedence in the header-verification condition):\n\nThis condition is verbatim from upstream libdivecomputer at commit 1a6e1650 — it was not introduced or changed by this PR. Copilot is correct that A || B ? C : D parses as A || (B ? C : D) rather than (A || B) ? C : D due to C operator precedence, which differs from the apparent intent. However, since this is pre-existing upstream code that this sync PR did not touch, fixing it is out of scope here. If worth addressing, that fix belongs as a separate upstream contribution to libdivecomputer/libdivecomputer.

@mikeller

Copy link
Copy Markdown
Member Author

Update: the operator-precedence bug in hw_ostc3.c has been fixed in the amended commit (now 0a503734). The ternary expression is now wrapped in parentheses so the condition correctly reads as version_mismatch || (compact ? (fp_mismatch || num_mismatch) : full_fp_mismatch) rather than the previous (version_mismatch || compact) ? ... that upstream had. Will need another force-push to update the PR branch.

@mikeller
mikeller force-pushed the update_libdivecomputer_202608 branch from affdbf8 to 0a50373 Compare August 21, 2026 09:09
Copilot AI review requested due to automatic review settings August 21, 2026 09:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 1 comment.

Comment thread src/hw_ostc3.c
Comment on lines 887 to +891
const hw_ostc3_logbook_t *logbook = NULL;
if (compact) {
logbook = &hw_ostc3_logbook_compact;
} else {
logbook = &hw_ostc3_logbook_full;
logbook = layout;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the amended commit (0a06cd0d). The COMPACT command attempt is now guarded by !device->frog — Frog devices always go straight to the full HEADER download. compact is initialised to !device->frog rather than 1, so the subsequent logbook-layout selection, profile-length calculation, and header-verification ternary all remain correct for both code paths. Will need another force-push.

Copilot AI review requested due to automatic review settings August 21, 2026 09:22
@mikeller
mikeller force-pushed the update_libdivecomputer_202608 branch from 0a50373 to 0a06cd0 Compare August 21, 2026 09:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.

Suppressed comments (2)

src/shearwater_petrel.c:371

  • This error message duplicates logging already performed inside shearwater_common_get_model() and is also misleading (that helper reads the hardware type and maps it). Returning status directly avoids double error logs.
	unsigned int model = 0;
	status = shearwater_common_get_model (device, &model);
	if (status != DC_STATUS_SUCCESS) {
		ERROR (abstract->context, "Failed to read the model number.");
		return status;
	}

src/shearwater_petrel.c:198

  • The failure path here logs an error message that’s both duplicated and slightly misleading: shearwater_common_get_model() already logs "Failed to read the hardware type." on failure, and it reads ID_HARDWARE (mapping to a model), not a model number directly. Consider returning rc without additional ERROR() here to avoid double-logging and confusion.

This issue also appears on line 366 of the same file.

	unsigned int model = 0;
	rc = shearwater_common_get_model (&device->base, &model);
	if (rc != DC_STATUS_SUCCESS) {
		ERROR (abstract->context, "Failed to read the model number.");
		return rc;
	}

Comment on lines 138 to 144
hw_ostc_device_md2hash
hw_ostc_device_eeprom_read
hw_ostc_device_eeprom_write
hw_ostc_device_reset
hw_ostc_device_screenshot
hw_ostc_device_fwupdate
hw_frog_device_version
hw_frog_device_display
hw_frog_device_customtext
hw_ostc3_device_version

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applicable to this fork. subsurface/libdc is a vendored submodule built directly into Subsurface; it is not distributed as an independently versioned shared library for external consumers. Subsurface always builds libdivecomputer from source as part of its own build, so there are no binary compatibility obligations. The symbol removal is upstream's deliberate design decision (folding Frog into the OSTC3 backend), and Subsurface does not call any hw_frog_device_* functions directly — it goes through the descriptor/device layer.

Comment on lines 336 to 338
unsigned int gasmix; /* Gas mix index */
dc_location_t location;
} dc_sample_value_t;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not applicable to this fork. subsurface/libdc is a vendored submodule always built from source together with Subsurface; it is not distributed as a standalone shared library for external binary consumers. Any change to dc_sample_value_t's layout is visible at compile time and there is no binary compatibility concern. The union extension is upstream's deliberate design change to support DC_SAMPLE_LOCATION.

@mikeller

Copy link
Copy Markdown
Member Author

Re: the two suppressed comments in the latest review (both in shearwater_petrel.c): the redundant ERROR(abstract->context, "Failed to read the model number.") lines have been removed from both call sites (shearwater_petrel_device_foreach and shearwater_petrel_device_timesync). shearwater_common_get_model() already logs "Failed to read the hardware type." internally on failure, so the caller's error message was duplicate and slightly misleading. The amended commit is now 7db15b3a. Requires another force-push.

Copilot AI review requested due to automatic review settings August 22, 2026 00:04
@mikeller
mikeller force-pushed the update_libdivecomputer_202608 branch from 0a06cd0 to 7db15b3 Compare August 22, 2026 00:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 1 comment.

Comment thread src/shearwater_common.h
Comment on lines 35 to 43
#define ID_SERIAL 0x8010
#define ID_FIRMWARE 0x8011
#define ID_LOGUPLOAD 0x8021
#define ID_HARDWARE 0x8050
#define ID_LOCAL_TIME 0x9030
#define ID_UTC_TIME 0x9031
#define ID_LOCAL_TIME_OFFSET 0x9032
#define ID_LOCAL_TIME_DST 0x9033

#define WDBI_TIME_PACKET_SIZE 7
#define ID_MODEL 0x8060

#define ID_TIME_LOCAL 0x9030
#define ID_TIME_UTC 0x9031

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the amended commit (f5ce0f03). shearwater_common_get_model() has been removed entirely from shearwater_common.c and .h. Both call sites in shearwater_petrel.c now read ID_MODEL (0x8060) directly via shearwater_common_rdbi() as a single unsigned char, matching upstream exactly. This also corrects the PERDIX3 (model 14) case, which the hardware-type mapping switch never handled and would have silently returned model 0. Requires another force-push.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.

Comment thread src/shearwater_petrel.c
@@ -192,10 +192,10 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call

unsigned int model = 0;
rc = shearwater_common_get_model (&device->base, &model);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the same amended commit (f5ce0f03). shearwater_petrel_device_foreach now reads ID_MODEL directly as unsigned char model via shearwater_common_rdbi(), the shearwater_common_get_model() wrapper is gone, and devinfo.model carries the correct native model number for all devices including PERDIX3.

Comment on lines +1377 to +1390
if (nsamples == 1 || nsamples == parser->nsamples) {
unsigned int record = nsamples == 1 ? parser->opening[9] : parser->closing[9];
if (record != UNDEFINED && parser->logversion >= 17) {
unsigned int gnss = data[record + 16];
int latitude = (signed int) array_uint32_be (data + record + 21);
int longitude = (signed int) array_uint32_be (data + record + 25);
if (gnss == GNSS_FIX_2D || gnss == GNSS_FIX_3D) {
sample.location.latitude = latitude / 100000.0;
sample.location.longitude = longitude / 100000.0;
sample.location.altitude = 0.0;
if (callback) callback (DC_SAMPLE_LOCATION, &sample, userdata);
}
}
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a real bug. For a single-sample dive, nsamples == 1 and parser->nsamples == 1 are both true, but opening[9] and closing[9] point to the same physical record — so the ternary emits the correct single GPS fix once. There is no scenario where a one-sample dive can have different entry and exit GPS records, since those records bracket the sample data and would be identical when there is only one sample. No change needed.

@mikeller

Copy link
Copy Markdown
Member Author

Re: whether the switch from ID_HARDWARE mapping to direct ID_MODEL read loses model information for devices like Petrel vs Petrel 2:

It does not — both approaches yield the same result, for the same reason: #define PETREL2 PETREL in shearwater_common.h means both Petrel and Petrel 2 map to the same model constant (3). The descriptor table also assigns both "Petrel" and "Petrel 2" model number 3 — so they are intentionally indistinguishable by model number. The old shearwater_common_get_model() mapped all hardware type codes for both Petrel (0x0404, 0x0909) and Petrel 2 (0x0505, 0x0808, 0x0838, etc.) to the same constant 3. The new direct ID_MODEL read returns 3 for both as well.

The Petrel / Petrel 2 distinction in Subsurface was always based on transport type at connection time (Petrel 2 adds BLE), not on devinfo.model. Neither approach was ever able to distinguish them from the model number alone — that has not changed.

Three issues introduced by the merge of libdivecomputer/master:

1. parser.h: DC_SAMPLE_LOCATION was added to parsers (divesoft_freedom,
   divesystem_idive, halcyon_symbios, shearwater_predator) but the
   corresponding enum value was omitted from dc_sample_type_t.  Add
   DC_SAMPLE_LOCATION after DC_SAMPLE_TTS and add the matching #define
   guard for compile-time feature testing.

2. shearwater_predator_parser.c (DC_FIELD_LOCATION case): latitude and
   longitude were used but never declared.  The upstream version declared
   them as signed int inside a block; reproduce that with an explicit
   block scope so the variables are properly declared.

3. shearwater_petrel.c: shearwater_common_get_model() returns an
   unsigned int, but HEXDUMP expects const unsigned char *.  Add an
   explicit cast to silence the incompatible-pointer-type error.

Signed-off-by: Michael Keller <github@ike.ch>
@mikeller
mikeller force-pushed the update_libdivecomputer_202608 branch from 7db15b3 to ac7e599 Compare August 22, 2026 03:02
Copilot AI review requested due to automatic review settings August 22, 2026 03:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants