Opening a device
Use one of the device specific xx_device_open() functions to open a connection with the device.
device_status_t xx_device_open (device_t **device, ...);
Closing a device
To close a device handle and free all associated resources, call the device_close() function on the device handle.
device_status_t device_close (device_t *device);
The device_foreach() function can be used to download individual dives from the device.
device_status_t device_foreach (device_t *device, dive_callback_t callback, void *userdata); int callback (const unsigned char *data, unsigned int size, void *userdata);
Dives are always returned in reverse order (newest first).
The callback function should normally return 1. If the callback function returns 0, the operation is immediately aborted. Combined with the reverse order, this allows you to stop downloading once an old dive is detected. Note that this feature is depecrated (replaced by the fingerprint feature) and will likely be removed in future versions.
The device_dump() function can be used to download the entire internal memory of the device. This method is intended for diagnostic purposes only, because it always downloads the maximum amount of data and you'll have to extract the individual dives manually.
device_status_t device_dump (device_t *device, dc_buffer_t *buffer);
Use the dc_buffer_new() function to create a new buffer. Once the data has been downloaded, the contents and the size of the buffer can be retrieved with the dc_buffer_get_data() and dc_buffer_get_size() functions. Note that any existing data in the buffer will have been overwritten. Finally, the buffer needs to be destroyed with the dc_buffer_free() function.
The device_set_events() function can be used to register a callback function with a device handle. The callback function will be invoked whenever one of the events specified in the event mask is emitted.
device_status_t device_set_events (device_t *device, unsigned int events, device_event_callback_t callback, void *userdata); void callback (device_t *device, device_event_t event, const void *data, void *userdata);
The contents of the data parameter depends on the type of the emitted event, and needs to be casted to the appropriate data structure. Currently, these events are defined:
- The operation is waiting for some user action. Typically this indicates that the user needs to initiate the transfer manually on the device. The data parameter is always NULL.
- Provides information on the progress of the operation. The data parameter is a pointer to a device_progress_t structure. A percentage can be calculated by dividing the current and maximum fields, and the result is guaranteed to be between 0 and 1 (inclusive). You should not assume that these values are byte counts.
- Provides information about the connected device. The data parameter is a pointer to a device_devinfo_t structure. This event is intended to be used with the fingerprint feature.
- Provides a device and system timestamp to be able to synchronize both clocks. The data parameter is a pointer to a device_clock_t structure.
The device_set_fingerprint function can be used to associate a fingerprint with the device handle. The fingerprint data will be used to identify previously download dives, which will reduce the download time significantly by not downloading old data.
device_status_t device_set_fingerprint (device_t *device, const unsigned char data, unsigned int size);
After each successfull download, an application should should store the fingerprint of the most recent dive, along with the device type and the serial number. When the application receives a DEVINFO event, it should retrieve the fingerprint for that specific device and pass it back to the library. This is the only reliable method to download only new dives. If you only intend to support a single device, you can ignore the DEVINFO event and store only a single fingerprint (not recommended).
The library can be safely used in a multi-threaded application, provided that a single object is never accessed simulataneously from two or more threads. If you need to access objects from multiple threads at once, you'll have to use an appropriate synchronization mechanism.
Remark: The debugging code for writing error and warning messages is not thread-safe!
To be able to cancel an operation, an application should use the device_set_cancel() function to register a callback function with the device handle. This callback function should return a non-zero value whenever the active operaton should be cancelled.
device_status_t device_set_cancel (device_t *device, device_cancel_callback_t callback, void *userdata); int callback (void *userdata);
Note that there is NO guarantee that the operation will be cancelled. Not all backends support cancellation, and those that do may not always notice a cancellation request in time.
The api for parsing the dive data is very similar to downloading data. First, you use one of the device specific xx_parser_create() functions to create the appropriate parser object. Next, you attach the dive data to the parser with the parser_set_data() function and execute the parser_samples_foreach() function. This step can be repeated many times. Once you are finished, the parser should be destroyed with the parser_destroy() function.
The callback function will receive a stream of sample values. Each sample value has a sample type to indicate how the sample data should be interpreted. The time sample is special in the sense that it indicates a new sample point has started. For instance if you receive this sequence:
<time> <depth> <pressure> <time> <event> <whatever>
It translates to this structure:
<sample> <time> <depth> <pressure> </sample> <sample> <time> <event> <whatever> </sample>