Skip to content

Update libdivecomputer to Latest in Upstream.#112

Open
mikeller wants to merge 31 commits into
subsurface:Subsurface-DS9from
mikeller:update_libdivecomputer_202605
Open

Update libdivecomputer to Latest in Upstream.#112
mikeller wants to merge 31 commits into
subsurface:Subsurface-DS9from
mikeller:update_libdivecomputer_202605

Conversation

@mikeller
Copy link
Copy Markdown
Member

  • Add Github sponsorship information
  • Update libusb and hidapi in the CI builds
  • Use the new libusb_init_context function
  • Add new Shearwater hardware models
  • Add support for the Shearwater Swift GPS
  • Ignore invalid GPS locations
  • Use the AI mode to detect the presence of GPS data
  • Add some new record types
  • Fix a typo in the log message
  • Add support for the OSTC Nano
  • Report the TTS information
  • Use a macro to detect the hwOS variant
  • Add new Shearwater hardware models
  • Fix the setpoint value
  • Fix Halcyon Symbios dive mode parsing
  • Report the correct compass headings
  • Remove the deprecated heading events
  • Add some extra debug logging
  • Log the received hardware response
  • Remove the automatic fallback for the hardware command
  • Replace the hardware descriptor with the model number
  • Add BLE support for the Seac Tablet
  • Increase the Seac BLE timeout
  • Support time sync for Icon HD family.
  • Update the Github actions
  • Upload non-zipped artifacts
  • Fix tank overflow guards in Symbios parser
  • Fix wrong compass offset in Halcyon Symbios parser
  • Extract firmware version from Symbios device status
  • Enable bluetooth for the OSTC 3 and cR

jefdriesen and others added 30 commits November 26, 2025 11:00
Update both dependencies to their latest version.

The workaround to link hidapi statically against libgcc is no longer
needed because it's the default in the hidapi build system now.
The old libusb_init function is deprecated and may be removed in the
future. Detect the API change through the LIBUSB_API_VERSION macro and
fallback to the old function for compatibility with older libusb
versions.
After updating the firmware to version 102, the hardware type of the
dive computer appears to change as well. This is an unfortunate change,
because the model is no longer detected correctly until the table is
fully updated.
With the new Swift GPS transmitter, the GPS location of the dive entry
and exit points are stored in the opening and closing record number 9.

At the moment only the entry location is reported because the api only
supports a single location.
Apparantly the GPS location fields can also contain the magic value
0xFFFFFFFF (or -1 as signed integer) to indicate the absence of a GPS
location.

Reported-by: Greg McLaughlin <support@moremobilesoftware.com>
To enable the GPS feature of the Swift transmitter, the AI mode needs to
be configured as "On + GPS". Use this new setting to detect the presence
of GPS data instead of the log version.
These new record types are not used by libdivecomputer. This change
mainly removes some (harmless) "Unknown record" warnings at runtime.
The OSTC Nano is a new hwOS based model with a USB-C port (supporting
both data communication and battery charging) and a bluetooth module
(BLE only). The bluetooth device name is "OSTC nano" (without a serial
number).
The excursion V1 data format stores TTS information. Report this info
when available.

This also fixes a bug where the tts field wasn't correctly initialized
to zero.
The macro makes it easier to update the logic in a central place.

It also fixes some small bugs in the OSTC4 detection logic in the
parser. Since the parser code is shared with the older non-hwOS models,
each check for the model number should be preceeded with a check for the
hwos flag.
Source of the information is the Shearwater firmware update file:

  https://downloads.shearwater.com/liveupdates/firmwareupdate.xml
Read the setpoint value from the sample instead of at a fixed offset
somewhere in the dive header (where the dive number happens to be
located).
The Halcyon Symbios has five dive modes:

- OC (Open Circuit) = 0
- CCR (Closed Circuit Rebreather) = 1
- CCR FSP (CCR Fixed Set Point) = 2
- Sidemount = 3
- Bottom Timer (Gauge) = 4

The previous code incorrectly assigned GAUGE = 2, which caused CCR FSP
dives to be reported as gauge mode instead of CCR mode.

CCR FSP is a CCR mode where the setpoint is fixed (typically 1.3 ppO2)
rather than manually adjusted by the diver. Both CCR and CCR FSP should
map to DC_DIVEMODE_CCR.

Signed-off-by: Simone Carletti <weppos@weppos.net>
The Divesoft dive computers support two types of orientation related
records:

 - The EVENT_WAYPOINT record contains the compass heading and is
   manually bookmarked by the diver on the (virtual) compass.

 - The POINT_2 record contains spatial orientation data and is recorded
   continuously throughout the dive by the dive computer. This
   orientation data does not only include the heading, but also pitch
   and roll info.

At the moment, the libdivecomputer compass bearing sample only supports
the first type of orientation data. Supporting the second type would
require a new sample type, to be able to include the pitch and roll
info.
The bearing sample has been introduced long time ago already, but the
Suunto backends were never updated and are still using the legacy
heading event. Switch to the bearing sample and mark the heading event
as deprecated.
Log only the hardware bytes that were actually received from the dive
computer and not the full internal buffer.
The automatic fallback from the 5 byte HARDWARE2 (0x60) command to the 1
byte HARDWARE (0x6A) command makes it impossible for the caller to know
which bytes in the response are actually valid. Fixed by removing the
automatic fallback.

An application trying to read the 5 byte variant can now detect whether
the command isn't supported (by means of the DC_STATUS_UNSUPPORTED
return value) and manually fallback to the 1 byte variant. If only the 1
byte hardware descriptor is needed, there is no need to even try reading
the 5 byte variant.
The different bits in the hardware descriptor describe the available
hardware features:

  0  Rechargeable battery with battery management chip
  1  Ambient sensor
  2  Analog inputs and S8 digital
  3  Digital optical input
  4  BLE module
  5  32bit dual core
  6  Low voltage core
  7  External flash memory with block write support

Since different models can share the same hardware features, the
hardware descriptor can no longer be used to reliably identify the exact
model. Trying to maintain this relationship anyway, only results in many
duplicated entries in the list of supported devices with the same name
but a different model number.

For this reason, the hwOS firmware even masks off the upper 2 bits of
the hardware descriptor before sending the value.

Use the model descriptor as the internal model number instead. All the
hwOS models, except for the OSTC 4 and 5, report a zero value here.
The Seac Tablet supports both usb-serial and BLE communication. Both
transports share the same high-level communication protocol. Only the
packetization is different.

The BLE communication is based on the typical UART-over-BLE protocol,
featuring the following service and Rx/Tx characteristics:

  Service: 84968ffe-d26d-478a-b953-5010bcf58bca
  Characteristics:
    - Rx/Tx: 43c620c2-1b09-4951-bc1e-9c75298cddeb (read, write)

Remarkably, the Tx characteristic does not support notifications or
indications and must be read instead.

The bluetooth device name is "TabletXXXXXX" where XXXXXX is the serial
number of the dive computer.
After sending a command to the dive computer, the first BLE data packet
always arrives after a delay of about 2.1 to 2.3 seconds. All following
data packets arrive within a few tens of milliseconds:

  [40.438010] [0.017709] INFO: Write: size=15, data=..
  [42.624359] [2.186349] INFO: Read: size=128, data=..
  [42.640406] [0.016047] INFO: Read: size=128, data=..
  [42.661683] [0.021277] INFO: Read: size=128, data=..
  [42.675335] [0.013652] INFO: Read: size=128, data=..
  [42.690446] [0.015111] INFO: Read: size=128, data=..
  [42.705340] [0.014894] INFO: Read: size=128, data=..
  [42.720271] [0.014931] INFO: Read: size=128, data=..
  [42.735221] [0.014950] INFO: Read: size=128, data=..
  [42.752563] [0.017342] INFO: Read: size=128, data=..
  [42.774315] [0.021752] INFO: Read: size=128, data=..
  [42.788240] [0.013925] INFO: Read: size=128, data=..
  [42.803374] [0.015134] INFO: Read: size=128, data=..
  [42.819374] [0.016000] INFO: Read: size=128, data=..
  [42.834397] [0.015023] INFO: Read: size=128, data=..
  [42.850315] [0.015918] INFO: Read: size=128, data=..
  [42.870331] [0.020016] INFO: Read: size=128, data=..
  [42.883544] [0.013213] INFO: Read: size=8, data=..

Occasionally, this first packet delay even increases to around 5.6
seconds!

Therefore, the BLE timeout needs to be increased to a larger value. For
the USB communication, the default timeout of 1 seconds is more than
sufficient because the response is typically received within 200
milliseconds.

Due to the lack of notification/indication support for the Seac characteristic,
read timeouts are even more problematic. Whenever a read timeout happens:

  [0.000000] [0.000000] INFO: Write: size=7, data=55000618331923
  [3.007000] [3.007000] INFO: Read: size=0, data=

it also causes the next retry to fail:

   [3.014000] [0.003000] INFO: Sleep: value=100
   [3.130000] [0.116000] INFO: Purge: direction=1
   [4.266000] [1.136000] INFO: Write: size=7, data=55000618331923
   [4.269000] [0.003000] INFO: Read: size=128, data=5501071833..
   [6.492000] [2.223000] INFO: Read: size=128, data=5501071833..
   [6.508000] [0.016000] INFO: Read: size=128, data=..

The first BLE packet arrives immediately without the usual 2 second delay and
the payload of this packet is identical to the payload of the second packet,
which happens to arrive after the usual 2 second delay. This indicates the first
packet is actually the response to the first attempt.

The purge operation doesn't help to discard this packet, because without
notifications the packet remains queued on the device side until we
retrieve it by reading the characteristic.

Since the response is now malformed due to the presence of the extra packet,
this condition is detected by means of a checksum error and another attempt is
needed:

   [6.515000] [0.002000] INFO: Sleep: value=100
   [6.618000] [0.103000] INFO: Purge: direction=1
   [6.649000] [0.031000] INFO: Write: size=7, data=55000618331923
   [8.842000] [2.193000] INFO: Read: size=128, data=5501071833..
   [8.874000] [0.032000] INFO: Read: size=128, data=..
   [8.905000] [0.031000] INFO: Read: size=8, data=..

Co-authored-by: Jef Driesen <jef@libdivecomputer.org>
Source is a BT snoop log from the official Mares app against a Mares
Sirius.
All Github actions using Node.js 20 are deprecated [1]. Update the
following actions to the latest version using Node.js 24:

 - actions/checkout
 - actions/upload-artifact
 - microsoft/setup-msbuild

[1] https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
The latest upload-artifact@v7 action added support for uploading
non-zipped artifacts [1]. This prevents the uploading of a compressed
tar.gz file within another compressed zip file.

To indicate the type of the uploaded file, the file extension is added
to the artifact name. For the new non-zipped artifacts this is already
the default.

[1] https://github.blog/changelog/2026-02-26-github-actions-now-supports-uploading-and-downloading-non-zipped-artifacts/
It is referencing the wrong variable, the gasmix counter instead of the
tanks counter.
The ID_COMPASS (0x0E) record is 4 bytes: id, size, uint16_le heading.
The heading payload starts at offset+2, but the code reads from
offset+4 which is past the record boundary into the next record's
id and size bytes, producing invalid bearings.
The firmware version (major.minor.bugfix) is available at bytes 16-18
of the BT_device_status_t response, but was hardcoded to 0.
Later models of the OSTC 3 and cR use Bluetooth instead of USB
communication.

This change allows owners of these computers to select the correct model
to connect via Bluetooth, instead of having to choose one of the other
computers from the same family.
Copilot AI review requested due to automatic review settings May 11, 2026 01:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 updates libdivecomputer to match newer upstream behavior, including new device support (notably BLE and new models), parsing/event API adjustments (bearing vs heading, GPS-related records), and CI workflow updates.

Changes:

  • Update USB initialization to use libusb_init_context when available.
  • Extend device/model support and parsing (new Shearwater models/GPS handling, Symbios fixes, OSTC hwOS changes, Seac Tablet BLE, Icon HD time sync).
  • Update sample/event API usage (deprecate heading events in favor of DC_SAMPLE_BEARING, add/propagate additional record data like TTS fields).

Reviewed changes

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

Show a summary per file
File Description
src/usbhid.c Use libusb_init_context on newer libusb versions.
src/usb.c Same libusb initialization update as USBHID.
src/suunto_eonsteel_parser.c Emit compass as DC_SAMPLE_BEARING instead of heading events.
src/suunto_d9_parser.c Emit bearing samples for heading records; adjust bookmark timing emission.
src/shearwater_predator_parser.c Add AI mode value for GPS detection; gate location field on GPS AI mode.
src/shearwater_common.c Add new Shearwater model identifiers.
src/seac_screen.c Add BLE packet stream wrapping + close hook; adjust timeout for BLE.
src/mares_iconhd.c Add device time-sync support via new command.
src/hw_ostc3.h Replace helper with macro-based hwOS variant detection.
src/hw_ostc3.c hwOS macro usage, more debug logging, model reporting changes, command selection tweaks.
src/hw_ostc_parser.c Update OSTC4/5 constants and hwOS4 detection macro usage.
src/halcyon_symbios.c Report firmware version in devinfo and debug output.
src/halcyon_symbios_parser.c Add new record types, fix tank guards, compass offset, and record-size workaround.
src/divesoft_freedom_parser.c Fix setpoint parsing and bearing reporting for waypoint events.
src/descriptor.c Add Seac BLE filter, enable BLE transports for additional HW descriptors.
src/deepsix_excursion_parser.c Attempt to report TTS in deco samples.
include/libdivecomputer/parser.h Mark SAMPLE_EVENT_HEADING as deprecated (bearing replacement).
examples/common.c Adjust example backend model for ostc3.
doc/man/dc_parser_samples_foreach.3 Remove SAMPLE_EVENT_HEADING from man page event list.
.github/workflows/release.yml Bump checkout action version.
.github/workflows/build.yml Update action versions and artifact upload behavior.
.github/FUNDING.yml Add GitHub sponsorship/PayPal funding metadata.
Comments suppressed due to low confidence (1)

src/deepsix_excursion_parser.c:760

  • In the SAMPLE_DECO_NDL case, sample.deco.tts is assigned in each branch (including deco_ndl_tts for DECOSTOP) but then immediately overwritten with sample.deco.tts = 0; just before invoking the callback. This makes the new TTS reporting ineffective. Remove the unconditional reset, or only set tts once to the intended value for each deco type before calling the callback.
					if (deco_flags & DECOSTOP) {
						sample.deco.type = DC_DECO_DECOSTOP;
						sample.deco.depth = pressure_to_depth(deco_depth, atmospheric, density);
						sample.deco.time = deco_time;
						sample.deco.tts = deco_ndl_tts;
					} else if (deco_flags & SAFETYSTOP) {
						sample.deco.type = DC_DECO_SAFETYSTOP;
						sample.deco.depth = pressure_to_depth(deco_depth, atmospheric, density);
						sample.deco.time = deco_time;
						sample.deco.tts = 0;
					} else {
						sample.deco.type = DC_DECO_NDL;
						sample.deco.depth = 0;
						sample.deco.time = deco_ndl_tts;
						sample.deco.tts = 0;
					}
					sample.deco.tts = 0;
					if (callback) callback (DC_SAMPLE_DECO, &sample, userdata);
					break;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 31 to 39
- name: Package artifacts
run: |
make install DESTDIR=$PWD/artifacts
tar -czf ${{ github.job }}-${{ matrix.compiler }}.tar.gz -C artifacts usr/local
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ github.job }}-${{ matrix.compiler }}
path: ${{ github.job }}-${{ matrix.compiler }}.tar.gz
archive: false

Comment on lines 61 to +69
- run: make distcheck
- name: Package artifacts
run: |
make install DESTDIR=$PWD/artifacts
tar -czf ${{ github.job }}-${{ matrix.compiler }}.tar.gz -C artifacts usr/local
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ github.job }}-${{ matrix.compiler }}
path: ${{ github.job }}-${{ matrix.compiler }}.tar.gz
archive: false
tar -czf ${{ github.job }}-${{ matrix.arch }}.tar.gz -C artifacts usr/local
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
Comment thread src/hw_ostc3.c
else
devinfo.model = OSTC3;
}
devinfo.model = device->model;
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.

6 participants