source: subsurface/core/configuredivecomputerthreads.cpp @ 527763f

Last change on this file since 527763f was 527763f, checked in by Dirk Hohndel <dirk@…>, 7 months ago

Start to read/write and present some OSTC4 settings

This is mostly copy-paste from the ostc3 case, but there are some minor
differences. Some minor things have different meaning, and there's a
slightly different command set, but I couldn't figure out a sane way of
joining them.

Signed-off-by: Anton Lundin <glance@…>

  • Property mode set to 100644
File size: 64.0 KB
Line 
1// SPDX-License-Identifier: GPL-2.0
2#include "configuredivecomputerthreads.h"
3#include "libdivecomputer/hw_ostc.h"
4#include "libdivecomputer/hw_ostc3.h"
5#include "libdivecomputer.h"
6
7#define OSTC3_GAS1                      0x10
8#define OSTC3_GAS2                      0x11
9#define OSTC3_GAS3                      0x12
10#define OSTC3_GAS4                      0x13
11#define OSTC3_GAS5                      0x14
12#define OSTC3_DIL1                      0x15
13#define OSTC3_DIL2                      0x16
14#define OSTC3_DIL3                      0x17
15#define OSTC3_DIL4                      0x18
16#define OSTC3_DIL5                      0x19
17#define OSTC3_SP1                       0x1A
18#define OSTC3_SP2                       0x1B
19#define OSTC3_SP3                       0x1C
20#define OSTC3_SP4                       0x1D
21#define OSTC3_SP5                       0x1E
22#define OSTC3_CCR_MODE                  0x1F
23#define OSTC3_DIVE_MODE                 0x20
24#define OSTC3_DECO_TYPE                 0x21
25#define OSTC3_PPO2_MAX                  0x22
26#define OSTC3_PPO2_MIN                  0x23
27#define OSTC3_FUTURE_TTS                0x24
28#define OSTC3_GF_LOW                    0x25
29#define OSTC3_GF_HIGH                   0x26
30#define OSTC3_AGF_LOW                   0x27
31#define OSTC3_AGF_HIGH                  0x28
32#define OSTC3_AGF_SELECTABLE            0x29
33#define OSTC3_SATURATION                0x2A
34#define OSTC3_DESATURATION              0x2B
35#define OSTC3_LAST_DECO                 0x2C
36#define OSTC3_BRIGHTNESS                0x2D
37#define OSTC3_UNITS                     0x2E
38#define OSTC3_SAMPLING_RATE             0x2F
39#define OSTC3_SALINITY                  0x30
40#define OSTC3_DIVEMODE_COLOR            0x31
41#define OSTC3_LANGUAGE                  0x32
42#define OSTC3_DATE_FORMAT               0x33
43#define OSTC3_COMPASS_GAIN              0x34
44#define OSTC3_PRESSURE_SENSOR_OFFSET    0x35
45#define OSTC3_SAFETY_STOP               0x36
46#define OSTC3_CALIBRATION_GAS_O2        0x37
47#define OSTC3_SETPOINT_FALLBACK 0x38
48#define OSTC3_FLIP_SCREEN       0x39
49#define OSTC3_LEFT_BUTTON_SENSIVITY     0x3A
50#define OSTC3_RIGHT_BUTTON_SENSIVITY    0x3A
51#define OSTC3_BOTTOM_GAS_CONSUMPTION    0x3C
52#define OSTC3_DECO_GAS_CONSUMPTION      0x3D
53#define OSTC3_MOD_WARNING               0x3E
54#define OSTC3_DYNAMIC_ASCEND_RATE       0x3F
55#define OSTC3_GRAPHICAL_SPEED_INDICATOR 0x40
56#define OSTC3_ALWAYS_SHOW_PPO2          0x41
57#define OSTC3_TEMP_SENSOR_OFFSET        0x42
58#define OSTC3_SAFETY_STOP_LENGTH        0x43
59#define OSTC3_SAFETY_STOP_START_DEPTH   0x44
60#define OSTC3_SAFETY_STOP_END_DEPTH     0x45
61#define OSTC3_SAFETY_STOP_RESET_DEPTH   0x46
62
63#define SUUNTO_VYPER_MAXDEPTH             0x1e
64#define SUUNTO_VYPER_TOTAL_TIME           0x20
65#define SUUNTO_VYPER_NUMBEROFDIVES        0x22
66#define SUUNTO_VYPER_COMPUTER_TYPE        0x24
67#define SUUNTO_VYPER_FIRMWARE             0x25
68#define SUUNTO_VYPER_SERIALNUMBER         0x26
69#define SUUNTO_VYPER_CUSTOM_TEXT          0x2c
70#define SUUNTO_VYPER_SAMPLING_RATE        0x53
71#define SUUNTO_VYPER_ALTITUDE_SAFETY      0x54
72#define SUUNTO_VYPER_TIMEFORMAT           0x60
73#define SUUNTO_VYPER_UNITS                0x62
74#define SUUNTO_VYPER_MODEL                0x63
75#define SUUNTO_VYPER_LIGHT                0x64
76#define SUUNTO_VYPER_ALARM_DEPTH_TIME     0x65
77#define SUUNTO_VYPER_ALARM_TIME           0x66
78#define SUUNTO_VYPER_ALARM_DEPTH          0x68
79#define SUUNTO_VYPER_CUSTOM_TEXT_LENGHT   30
80
81#ifdef DEBUG_OSTC
82// Fake io to ostc memory banks
83#define hw_ostc_device_eeprom_read local_hw_ostc_device_eeprom_read
84#define hw_ostc_device_eeprom_write local_hw_ostc_device_eeprom_write
85#define hw_ostc_device_clock local_hw_ostc_device_clock
86#define OSTC_FILE "../OSTC-data-dump.bin"
87
88// Fake the open function.
89static dc_status_t local_dc_device_open(dc_device_t **out, dc_context_t *context, dc_descriptor_t *descriptor, const char *name)
90{
91        if (strcmp(dc_descriptor_get_vendor(descriptor), "Heinrichs Weikamp") == 0 &&strcmp(dc_descriptor_get_product(descriptor), "OSTC 2N") == 0)
92                return DC_STATUS_SUCCESS;
93        else
94                return dc_device_open(out, context, descriptor, name);
95}
96#define dc_device_open local_dc_device_open
97
98static dc_status_t local_hw_ostc_device_eeprom_read(void *ignored, unsigned char bank, unsigned char data[], unsigned int data_size)
99{
100        FILE *f;
101        if ((f = fopen(OSTC_FILE, "r")) == NULL)
102                return DC_STATUS_NODEVICE;
103        fseek(f, bank * 256, SEEK_SET);
104        if (fread(data, sizeof(unsigned char), data_size, f) != data_size) {
105                fclose(f);
106                return DC_STATUS_IO;
107        }
108        fclose(f);
109
110        return DC_STATUS_SUCCESS;
111}
112
113static dc_status_t local_hw_ostc_device_eeprom_write(void *ignored, unsigned char bank, unsigned char data[], unsigned int data_size)
114{
115        FILE *f;
116        if ((f = fopen(OSTC_FILE, "r+")) == NULL)
117                f = fopen(OSTC_FILE, "w");
118        fseek(f, bank * 256, SEEK_SET);
119        fwrite(data, sizeof(unsigned char), data_size, f);
120        fclose(f);
121
122        return DC_STATUS_SUCCESS;
123}
124
125static dc_status_t local_hw_ostc_device_clock(void *ignored, dc_datetime_t *time)
126{
127        return DC_STATUS_SUCCESS;
128}
129#endif
130
131static int read_ostc_cf(unsigned char data[], unsigned char cf)
132{
133        return data[128 + (cf % 32) * 4 + 3] << 8 ^ data[128 + (cf % 32) * 4 + 2];
134}
135
136static void write_ostc_cf(unsigned char data[], unsigned char cf, unsigned char max_CF, unsigned int value)
137{
138        // Only write settings supported by this firmware.
139        if (cf > max_CF)
140                return;
141
142        data[128 + (cf % 32) * 4 + 3] = (value & 0xff00) >> 8;
143        data[128 + (cf % 32) * 4 + 2] = (value & 0x00ff);
144}
145
146#define EMIT_PROGRESS() do { \
147                progress.current++; \
148                progress_cb(device, DC_EVENT_PROGRESS, &progress, userdata); \
149        } while (0)
150
151static dc_status_t read_suunto_vyper_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
152{
153        unsigned char data[SUUNTO_VYPER_CUSTOM_TEXT_LENGHT + 1];
154        dc_status_t rc;
155        dc_event_progress_t progress;
156        progress.current = 0;
157        progress.maximum = 16;
158
159        rc = dc_device_read(device, SUUNTO_VYPER_COMPUTER_TYPE, data, 1);
160        if (rc == DC_STATUS_SUCCESS) {
161                dc_descriptor_t *desc = get_descriptor(DC_FAMILY_SUUNTO_VYPER, data[0]);
162
163                if (desc) {
164                        // We found a supported device
165                        // we can safely proceed with reading/writing to this device.
166                        m_deviceDetails->model = dc_descriptor_get_product(desc);
167                        dc_descriptor_free(desc);
168                } else {
169                        return DC_STATUS_UNSUPPORTED;
170                }
171        }
172        EMIT_PROGRESS();
173
174        rc = dc_device_read(device, SUUNTO_VYPER_MAXDEPTH, data, 2);
175        if (rc != DC_STATUS_SUCCESS)
176                return rc;
177        // in ft * 128.0
178        int depth = feet_to_mm(data[0] << 8 ^ data[1]) / 128;
179        m_deviceDetails->maxDepth = depth;
180        EMIT_PROGRESS();
181
182        rc = dc_device_read(device, SUUNTO_VYPER_TOTAL_TIME, data, 2);
183        if (rc != DC_STATUS_SUCCESS)
184                return rc;
185        int total_time = data[0] << 8 ^ data[1];
186        m_deviceDetails->totalTime = total_time;
187        EMIT_PROGRESS();
188
189        rc = dc_device_read(device, SUUNTO_VYPER_NUMBEROFDIVES, data, 2);
190        if (rc != DC_STATUS_SUCCESS)
191                return rc;
192        int number_of_dives = data[0] << 8 ^ data[1];
193        m_deviceDetails->numberOfDives = number_of_dives;
194        EMIT_PROGRESS();
195
196        rc = dc_device_read(device, SUUNTO_VYPER_FIRMWARE, data, 1);
197        if (rc != DC_STATUS_SUCCESS)
198                return rc;
199        m_deviceDetails->firmwareVersion = QString::number(data[0]) + ".0.0";
200        EMIT_PROGRESS();
201
202        rc = dc_device_read(device, SUUNTO_VYPER_SERIALNUMBER, data, 4);
203        if (rc != DC_STATUS_SUCCESS)
204                return rc;
205        int serial_number = data[0] * 1000000 + data[1] * 10000 + data[2] * 100 + data[3];
206        m_deviceDetails->serialNo = QString::number(serial_number);
207        EMIT_PROGRESS();
208
209        rc = dc_device_read(device, SUUNTO_VYPER_CUSTOM_TEXT, data, SUUNTO_VYPER_CUSTOM_TEXT_LENGHT);
210        if (rc != DC_STATUS_SUCCESS)
211                return rc;
212        data[SUUNTO_VYPER_CUSTOM_TEXT_LENGHT] = 0;
213        m_deviceDetails->customText = (const char *)data;
214        EMIT_PROGRESS();
215
216        rc = dc_device_read(device, SUUNTO_VYPER_SAMPLING_RATE, data, 1);
217        if (rc != DC_STATUS_SUCCESS)
218                return rc;
219        m_deviceDetails->samplingRate = (int)data[0];
220        EMIT_PROGRESS();
221
222        rc = dc_device_read(device, SUUNTO_VYPER_ALTITUDE_SAFETY, data, 1);
223        if (rc != DC_STATUS_SUCCESS)
224                return rc;
225        m_deviceDetails->altitude = data[0] & 0x03;
226        m_deviceDetails->personalSafety = data[0] >> 2 & 0x03;
227        EMIT_PROGRESS();
228
229        rc = dc_device_read(device, SUUNTO_VYPER_TIMEFORMAT, data, 1);
230        if (rc != DC_STATUS_SUCCESS)
231                return rc;
232        m_deviceDetails->timeFormat = data[0] & 0x01;
233        EMIT_PROGRESS();
234
235        rc = dc_device_read(device, SUUNTO_VYPER_UNITS, data, 1);
236        if (rc != DC_STATUS_SUCCESS)
237                return rc;
238        m_deviceDetails->units = data[0] & 0x01;
239        EMIT_PROGRESS();
240
241        rc = dc_device_read(device, SUUNTO_VYPER_MODEL, data, 1);
242        if (rc != DC_STATUS_SUCCESS)
243                return rc;
244        m_deviceDetails->diveMode = data[0] & 0x03;
245        EMIT_PROGRESS();
246
247        rc = dc_device_read(device, SUUNTO_VYPER_LIGHT, data, 1);
248        if (rc != DC_STATUS_SUCCESS)
249                return rc;
250        m_deviceDetails->lightEnabled = data[0] >> 7;
251        m_deviceDetails->light = data[0] & 0x7F;
252        EMIT_PROGRESS();
253
254        rc = dc_device_read(device, SUUNTO_VYPER_ALARM_DEPTH_TIME, data, 1);
255        if (rc != DC_STATUS_SUCCESS)
256                return rc;
257        m_deviceDetails->alarmTimeEnabled = data[0] & 0x01;
258        m_deviceDetails->alarmDepthEnabled = data[0] >> 1 & 0x01;
259        EMIT_PROGRESS();
260
261        rc = dc_device_read(device, SUUNTO_VYPER_ALARM_TIME, data, 2);
262        if (rc != DC_STATUS_SUCCESS)
263                return rc;
264        int time = data[0] << 8 ^ data[1];
265        // The stinger stores alarm time in seconds instead of minutes.
266        if (m_deviceDetails->model == "Stinger")
267                time /= 60;
268        m_deviceDetails->alarmTime = time;
269        EMIT_PROGRESS();
270
271        rc = dc_device_read(device, SUUNTO_VYPER_ALARM_DEPTH, data, 2);
272        if (rc != DC_STATUS_SUCCESS)
273                return rc;
274        depth = feet_to_mm(data[0] << 8 ^ data[1]) / 128;
275        m_deviceDetails->alarmDepth = depth;
276        EMIT_PROGRESS();
277
278        return DC_STATUS_SUCCESS;
279}
280
281static dc_status_t write_suunto_vyper_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
282{
283        dc_status_t rc;
284        dc_event_progress_t progress;
285        progress.current = 0;
286        progress.maximum = 10;
287        unsigned char data;
288        unsigned char data2[2];
289        int time;
290
291        // Maybee we should read the model from the device to sanity check it here too..
292        // For now we just check that we actually read a device before writing to one.
293        if (m_deviceDetails->model == "")
294                return DC_STATUS_UNSUPPORTED;
295
296        rc = dc_device_write(device, SUUNTO_VYPER_CUSTOM_TEXT,
297                             // Convert the customText to a 30 char wide padded with " "
298                             (const unsigned char *)QString("%1").arg(m_deviceDetails->customText, -30, QChar(' ')).toUtf8().data(),
299                             SUUNTO_VYPER_CUSTOM_TEXT_LENGHT);
300        if (rc != DC_STATUS_SUCCESS)
301                return rc;
302        EMIT_PROGRESS();
303
304        data = m_deviceDetails->samplingRate;
305        rc = dc_device_write(device, SUUNTO_VYPER_SAMPLING_RATE, &data, 1);
306        if (rc != DC_STATUS_SUCCESS)
307                return rc;
308        EMIT_PROGRESS();
309
310        data = m_deviceDetails->personalSafety << 2 ^ m_deviceDetails->altitude;
311        rc = dc_device_write(device, SUUNTO_VYPER_ALTITUDE_SAFETY, &data, 1);
312        if (rc != DC_STATUS_SUCCESS)
313                return rc;
314        EMIT_PROGRESS();
315
316        data = m_deviceDetails->timeFormat;
317        rc = dc_device_write(device, SUUNTO_VYPER_TIMEFORMAT, &data, 1);
318        if (rc != DC_STATUS_SUCCESS)
319                return rc;
320        EMIT_PROGRESS();
321
322        data = m_deviceDetails->units;
323        rc = dc_device_write(device, SUUNTO_VYPER_UNITS, &data, 1);
324        if (rc != DC_STATUS_SUCCESS)
325                return rc;
326        EMIT_PROGRESS();
327
328        data = m_deviceDetails->diveMode;
329        rc = dc_device_write(device, SUUNTO_VYPER_MODEL, &data, 1);
330        if (rc != DC_STATUS_SUCCESS)
331                return rc;
332        EMIT_PROGRESS();
333
334        data = m_deviceDetails->lightEnabled << 7 ^ (m_deviceDetails->light & 0x7F);
335        rc = dc_device_write(device, SUUNTO_VYPER_LIGHT, &data, 1);
336        if (rc != DC_STATUS_SUCCESS)
337                return rc;
338        EMIT_PROGRESS();
339
340        data = m_deviceDetails->alarmDepthEnabled << 1 ^ m_deviceDetails->alarmTimeEnabled;
341        rc = dc_device_write(device, SUUNTO_VYPER_ALARM_DEPTH_TIME, &data, 1);
342        if (rc != DC_STATUS_SUCCESS)
343                return rc;
344        EMIT_PROGRESS();
345
346        // The stinger stores alarm time in seconds instead of minutes.
347        time = m_deviceDetails->alarmTime;
348        if (m_deviceDetails->model == "Stinger")
349                time *= 60;
350        data2[0] = time >> 8;
351        data2[1] = time & 0xFF;
352        rc = dc_device_write(device, SUUNTO_VYPER_ALARM_TIME, data2, 2);
353        if (rc != DC_STATUS_SUCCESS)
354                return rc;
355        EMIT_PROGRESS();
356
357        data2[0] = (int)(mm_to_feet(m_deviceDetails->alarmDepth) * 128) >> 8;
358        data2[1] = (int)(mm_to_feet(m_deviceDetails->alarmDepth) * 128) & 0x0FF;
359        rc = dc_device_write(device, SUUNTO_VYPER_ALARM_DEPTH, data2, 2);
360        EMIT_PROGRESS();
361        return rc;
362}
363
364static dc_status_t read_ostc4_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
365{
366        // This code is really similar to the OSTC3 code, but there are minor
367        // differences in what the data means, and how to communicate with the
368        // device. If anyone can find a good way to harmonize the two, be my guest.
369        dc_status_t rc = DC_STATUS_SUCCESS;
370        dc_event_progress_t progress;
371        progress.current = 0;
372        progress.maximum = 19;
373        unsigned char hardware[1];
374
375        EMIT_PROGRESS();
376
377        //Read gas mixes
378        gas gas1;
379        gas gas2;
380        gas gas3;
381        gas gas4;
382        gas gas5;
383        unsigned char gasData[4] = { 0, 0, 0, 0 };
384
385        rc = hw_ostc3_device_config_read(device, OSTC3_GAS1, gasData, sizeof(gasData));
386        if (rc != DC_STATUS_SUCCESS)
387                return rc;
388        gas1.oxygen = gasData[0];
389        gas1.helium = gasData[1];
390        gas1.type = gasData[2];
391        gas1.depth = gasData[3];
392        EMIT_PROGRESS();
393
394        rc = hw_ostc3_device_config_read(device, OSTC3_GAS2, gasData, sizeof(gasData));
395        if (rc != DC_STATUS_SUCCESS)
396                return rc;
397        gas2.oxygen = gasData[0];
398        gas2.helium = gasData[1];
399        gas2.type = gasData[2];
400        gas2.depth = gasData[3];
401        EMIT_PROGRESS();
402
403        rc = hw_ostc3_device_config_read(device, OSTC3_GAS3, gasData, sizeof(gasData));
404        if (rc != DC_STATUS_SUCCESS)
405                return rc;
406        gas3.oxygen = gasData[0];
407        gas3.helium = gasData[1];
408        gas3.type = gasData[2];
409        gas3.depth = gasData[3];
410        EMIT_PROGRESS();
411
412        rc = hw_ostc3_device_config_read(device, OSTC3_GAS4, gasData, sizeof(gasData));
413        if (rc != DC_STATUS_SUCCESS)
414                return rc;
415        gas4.oxygen = gasData[0];
416        gas4.helium = gasData[1];
417        gas4.type = gasData[2];
418        gas4.depth = gasData[3];
419        EMIT_PROGRESS();
420
421        rc = hw_ostc3_device_config_read(device, OSTC3_GAS5, gasData, sizeof(gasData));
422        if (rc != DC_STATUS_SUCCESS)
423                return rc;
424        gas5.oxygen = gasData[0];
425        gas5.helium = gasData[1];
426        gas5.type = gasData[2];
427        gas5.depth = gasData[3];
428        EMIT_PROGRESS();
429
430        m_deviceDetails->gas1 = gas1;
431        m_deviceDetails->gas2 = gas2;
432        m_deviceDetails->gas3 = gas3;
433        m_deviceDetails->gas4 = gas4;
434        m_deviceDetails->gas5 = gas5;
435        EMIT_PROGRESS();
436
437        //Read Dil Values
438        gas dil1;
439        gas dil2;
440        gas dil3;
441        gas dil4;
442        gas dil5;
443        unsigned char dilData[4] = { 0, 0, 0, 0 };
444
445        rc = hw_ostc3_device_config_read(device, OSTC3_DIL1, dilData, sizeof(dilData));
446        if (rc != DC_STATUS_SUCCESS)
447                return rc;
448        dil1.oxygen = dilData[0];
449        dil1.helium = dilData[1];
450        dil1.type = dilData[2];
451        dil1.depth = dilData[3];
452        EMIT_PROGRESS();
453
454        rc = hw_ostc3_device_config_read(device, OSTC3_DIL2, dilData, sizeof(dilData));
455        if (rc != DC_STATUS_SUCCESS)
456                return rc;
457        dil2.oxygen = dilData[0];
458        dil2.helium = dilData[1];
459        dil2.type = dilData[2];
460        dil2.depth = dilData[3];
461        EMIT_PROGRESS();
462
463        rc = hw_ostc3_device_config_read(device, OSTC3_DIL3, dilData, sizeof(dilData));
464        if (rc != DC_STATUS_SUCCESS)
465                return rc;
466        dil3.oxygen = dilData[0];
467        dil3.helium = dilData[1];
468        dil3.type = dilData[2];
469        dil3.depth = dilData[3];
470        EMIT_PROGRESS();
471
472        rc = hw_ostc3_device_config_read(device, OSTC3_DIL4, dilData, sizeof(dilData));
473        if (rc != DC_STATUS_SUCCESS)
474                return rc;
475        dil4.oxygen = dilData[0];
476        dil4.helium = dilData[1];
477        dil4.type = dilData[2];
478        dil4.depth = dilData[3];
479        EMIT_PROGRESS();
480
481        rc = hw_ostc3_device_config_read(device, OSTC3_DIL5, dilData, sizeof(dilData));
482        if (rc != DC_STATUS_SUCCESS)
483                return rc;
484        dil5.oxygen = dilData[0];
485        dil5.helium = dilData[1];
486        dil5.type = dilData[2];
487        dil5.depth = dilData[3];
488        EMIT_PROGRESS();
489
490        m_deviceDetails->dil1 = dil1;
491        m_deviceDetails->dil2 = dil2;
492        m_deviceDetails->dil3 = dil3;
493        m_deviceDetails->dil4 = dil4;
494        m_deviceDetails->dil5 = dil5;
495
496        //Read setpoint Values
497        setpoint sp1;
498        setpoint sp2;
499        setpoint sp3;
500        setpoint sp4;
501        setpoint sp5;
502        unsigned char spData[4] = { 0, 0, 0, 0};
503
504        rc = hw_ostc3_device_config_read(device, OSTC3_SP1, spData, sizeof(spData));
505        if (rc != DC_STATUS_SUCCESS)
506                return rc;
507        sp1.sp = spData[0];
508        sp1.depth = spData[1];
509        EMIT_PROGRESS();
510
511        rc = hw_ostc3_device_config_read(device, OSTC3_SP2, spData, sizeof(spData));
512        if (rc != DC_STATUS_SUCCESS)
513                return rc;
514        sp2.sp = spData[0];
515        sp2.depth = spData[1];
516        EMIT_PROGRESS();
517
518        rc = hw_ostc3_device_config_read(device, OSTC3_SP3, spData, sizeof(spData));
519        if (rc != DC_STATUS_SUCCESS)
520                return rc;
521        sp3.sp = spData[0];
522        sp3.depth = spData[1];
523        EMIT_PROGRESS();
524
525        rc = hw_ostc3_device_config_read(device, OSTC3_SP4, spData, sizeof(spData));
526        if (rc != DC_STATUS_SUCCESS)
527                return rc;
528        sp4.sp = spData[0];
529        sp4.depth = spData[1];
530        EMIT_PROGRESS();
531
532        rc = hw_ostc3_device_config_read(device, OSTC3_SP5, spData, sizeof(spData));
533        if (rc != DC_STATUS_SUCCESS)
534                return rc;
535        sp5.sp = spData[0];
536        sp5.depth = spData[1];
537        EMIT_PROGRESS();
538
539        m_deviceDetails->sp1 = sp1;
540        m_deviceDetails->sp2 = sp2;
541        m_deviceDetails->sp3 = sp3;
542        m_deviceDetails->sp4 = sp4;
543        m_deviceDetails->sp5 = sp5;
544
545        //Read other settings
546        unsigned char uData[4] = { 0 };
547
548#define READ_SETTING(_OSTC4_SETTING, _DEVICE_DETAIL)                                            \
549        do {                                                                                    \
550                rc = hw_ostc3_device_config_read(device, _OSTC4_SETTING, uData, sizeof(uData)); \
551                if (rc != DC_STATUS_SUCCESS)                                                    \
552                        return rc;                                                              \
553                m_deviceDetails->_DEVICE_DETAIL = uData[0];                                     \
554                EMIT_PROGRESS();                                                                \
555        } while (0)
556
557#undef READ_SETTING
558
559        rc = hw_ostc3_device_config_read(device, OSTC3_PRESSURE_SENSOR_OFFSET, uData, sizeof(uData));
560        if (rc != DC_STATUS_SUCCESS)
561                return rc;
562        // OSTC3 stores the pressureSensorOffset in two-complement
563        m_deviceDetails->pressureSensorOffset = (signed char)uData[0];
564        EMIT_PROGRESS();
565
566        rc = hw_ostc3_device_config_read(device, OSTC3_TEMP_SENSOR_OFFSET, uData, sizeof(uData));
567        if (rc != DC_STATUS_SUCCESS)
568                return rc;
569        // OSTC3 stores the tempSensorOffset in two-complement
570        m_deviceDetails->tempSensorOffset = (signed char)uData[0];
571        EMIT_PROGRESS();
572
573        //read firmware settings
574        unsigned char fData[64] = { 0 };
575        rc = hw_ostc3_device_version(device, fData, sizeof(fData));
576        if (rc != DC_STATUS_SUCCESS)
577                return rc;
578        int serial = fData[0] + (fData[1] << 8);
579        m_deviceDetails->serialNo = QString::number(serial);
580        unsigned char X, Y, Z, beta;
581        unsigned int firmwareOnDevice = (fData[3] << 8) + fData[2];
582        X = (firmwareOnDevice & 0xF800) >> 11;
583        Y = (firmwareOnDevice & 0x07C0) >> 6;
584        Z = (firmwareOnDevice & 0x003E) >> 1;
585        beta = firmwareOnDevice & 0x0001;
586        m_deviceDetails->firmwareVersion = QString("%1.%2.%3%4").arg(X).arg(Y).arg(Z).arg(beta?" beta":"");
587        QByteArray ar((char *)fData + 4, 60);
588        m_deviceDetails->customText = ar.trimmed();
589        EMIT_PROGRESS();
590
591        return rc;
592}
593
594static dc_status_t write_ostc4_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
595{
596        // This code is really similar to the OSTC3 code, but there are minor
597        // differences in what the data means, and how to communicate with the
598        // device. If anyone can find a good way to harmonize the two, be my guest.
599        dc_status_t rc = DC_STATUS_SUCCESS;
600        dc_event_progress_t progress;
601        progress.current = 0;
602        progress.maximum = 18;
603
604        //write gas values
605        unsigned char gas1Data[4] = {
606                m_deviceDetails->gas1.oxygen,
607                m_deviceDetails->gas1.helium,
608                m_deviceDetails->gas1.type,
609                m_deviceDetails->gas1.depth
610        };
611
612        unsigned char gas2Data[4] = {
613                m_deviceDetails->gas2.oxygen,
614                m_deviceDetails->gas2.helium,
615                m_deviceDetails->gas2.type,
616                m_deviceDetails->gas2.depth
617        };
618
619        unsigned char gas3Data[4] = {
620                m_deviceDetails->gas3.oxygen,
621                m_deviceDetails->gas3.helium,
622                m_deviceDetails->gas3.type,
623                m_deviceDetails->gas3.depth
624        };
625
626        unsigned char gas4Data[4] = {
627                m_deviceDetails->gas4.oxygen,
628                m_deviceDetails->gas4.helium,
629                m_deviceDetails->gas4.type,
630                m_deviceDetails->gas4.depth
631        };
632
633        unsigned char gas5Data[4] = {
634                m_deviceDetails->gas5.oxygen,
635                m_deviceDetails->gas5.helium,
636                m_deviceDetails->gas5.type,
637                m_deviceDetails->gas5.depth
638        };
639        //gas 1
640        rc = hw_ostc3_device_config_write(device, OSTC3_GAS1, gas1Data, sizeof(gas1Data));
641        if (rc != DC_STATUS_SUCCESS)
642                return rc;
643        EMIT_PROGRESS();
644        //gas 2
645        rc = hw_ostc3_device_config_write(device, OSTC3_GAS2, gas2Data, sizeof(gas2Data));
646        if (rc != DC_STATUS_SUCCESS)
647                return rc;
648        EMIT_PROGRESS();
649        //gas 3
650        rc = hw_ostc3_device_config_write(device, OSTC3_GAS3, gas3Data, sizeof(gas3Data));
651        if (rc != DC_STATUS_SUCCESS)
652                return rc;
653        EMIT_PROGRESS();
654        //gas 4
655        rc = hw_ostc3_device_config_write(device, OSTC3_GAS4, gas4Data, sizeof(gas4Data));
656        if (rc != DC_STATUS_SUCCESS)
657                return rc;
658        EMIT_PROGRESS();
659        //gas 5
660        rc = hw_ostc3_device_config_write(device, OSTC3_GAS5, gas5Data, sizeof(gas5Data));
661        if (rc != DC_STATUS_SUCCESS)
662                return rc;
663        EMIT_PROGRESS();
664
665        //write setpoint values
666        unsigned char sp1Data[4] = {
667                m_deviceDetails->sp1.sp,
668                m_deviceDetails->sp1.depth
669        };
670
671        unsigned char sp2Data[4] = {
672                m_deviceDetails->sp2.sp,
673                m_deviceDetails->sp2.depth
674        };
675
676        unsigned char sp3Data[4] = {
677                m_deviceDetails->sp3.sp,
678                m_deviceDetails->sp3.depth
679        };
680
681        unsigned char sp4Data[4] = {
682                m_deviceDetails->sp4.sp,
683                m_deviceDetails->sp4.depth
684        };
685
686        unsigned char sp5Data[4] = {
687                m_deviceDetails->sp5.sp,
688                m_deviceDetails->sp5.depth
689        };
690
691        //sp 1
692        rc = hw_ostc3_device_config_write(device, OSTC3_SP1, sp1Data, sizeof(sp1Data));
693        if (rc != DC_STATUS_SUCCESS)
694                return rc;
695        EMIT_PROGRESS();
696        //sp 2
697        rc = hw_ostc3_device_config_write(device, OSTC3_SP2, sp2Data, sizeof(sp2Data));
698        if (rc != DC_STATUS_SUCCESS)
699                return rc;
700        EMIT_PROGRESS();
701        //sp 3
702        rc = hw_ostc3_device_config_write(device, OSTC3_SP3, sp3Data, sizeof(sp3Data));
703        if (rc != DC_STATUS_SUCCESS)
704                return rc;
705        EMIT_PROGRESS();
706        //sp 4
707        rc = hw_ostc3_device_config_write(device, OSTC3_SP4, sp4Data, sizeof(sp4Data));
708        if (rc != DC_STATUS_SUCCESS)
709                return rc;
710        EMIT_PROGRESS();
711        //sp 5
712        rc = hw_ostc3_device_config_write(device, OSTC3_SP5, sp5Data, sizeof(sp5Data));
713        if (rc != DC_STATUS_SUCCESS)
714                return rc;
715        EMIT_PROGRESS();
716
717        //write dil values
718        unsigned char dil1Data[4] = {
719                m_deviceDetails->dil1.oxygen,
720                m_deviceDetails->dil1.helium,
721                m_deviceDetails->dil1.type,
722                m_deviceDetails->dil1.depth
723        };
724
725        unsigned char dil2Data[4] = {
726                m_deviceDetails->dil2.oxygen,
727                m_deviceDetails->dil2.helium,
728                m_deviceDetails->dil2.type,
729                m_deviceDetails->dil2.depth
730        };
731
732        unsigned char dil3Data[4] = {
733                m_deviceDetails->dil3.oxygen,
734                m_deviceDetails->dil3.helium,
735                m_deviceDetails->dil3.type,
736                m_deviceDetails->dil3.depth
737        };
738
739        unsigned char dil4Data[4] = {
740                m_deviceDetails->dil4.oxygen,
741                m_deviceDetails->dil4.helium,
742                m_deviceDetails->dil4.type,
743                m_deviceDetails->dil4.depth
744        };
745
746        unsigned char dil5Data[4] = {
747                m_deviceDetails->dil5.oxygen,
748                m_deviceDetails->dil5.helium,
749                m_deviceDetails->dil5.type,
750                m_deviceDetails->dil5.depth
751        };
752        //dil 1
753        rc = hw_ostc3_device_config_write(device, OSTC3_DIL1, dil1Data, sizeof(gas1Data));
754        if (rc != DC_STATUS_SUCCESS)
755                return rc;
756        EMIT_PROGRESS();
757        //dil 2
758        rc = hw_ostc3_device_config_write(device, OSTC3_DIL2, dil2Data, sizeof(dil2Data));
759        if (rc != DC_STATUS_SUCCESS)
760                return rc;
761        EMIT_PROGRESS();
762        //dil 3
763        rc = hw_ostc3_device_config_write(device, OSTC3_DIL3, dil3Data, sizeof(dil3Data));
764        if (rc != DC_STATUS_SUCCESS)
765                return rc;
766        EMIT_PROGRESS();
767        //dil 4
768        rc = hw_ostc3_device_config_write(device, OSTC3_DIL4, dil4Data, sizeof(dil4Data));
769        if (rc != DC_STATUS_SUCCESS)
770                return rc;
771        EMIT_PROGRESS();
772        //dil 5
773        rc = hw_ostc3_device_config_write(device, OSTC3_DIL5, dil5Data, sizeof(dil5Data));
774        if (rc != DC_STATUS_SUCCESS)
775                return rc;
776        EMIT_PROGRESS();
777
778        //write general settings
779        //custom text
780        rc = hw_ostc3_device_customtext(device, m_deviceDetails->customText.toUtf8().data());
781        if (rc != DC_STATUS_SUCCESS)
782                return rc;
783        EMIT_PROGRESS();
784
785        unsigned char data[4] = { 0 };
786#define WRITE_SETTING(_OSTC4_SETTING, _DEVICE_DETAIL)                                          \
787        do {                                                                                   \
788                data[0] = m_deviceDetails->_DEVICE_DETAIL;                                     \
789                rc = hw_ostc3_device_config_write(device, _OSTC4_SETTING, data, sizeof(data)); \
790                if (rc != DC_STATUS_SUCCESS)                                                   \
791                        return rc;                                                             \
792                EMIT_PROGRESS();                                                               \
793        } while (0)
794
795#undef WRITE_SETTING
796
797        // OSTC3 stores the pressureSensorOffset in two-complement
798        data[0] = (unsigned char)m_deviceDetails->pressureSensorOffset;
799        rc = hw_ostc3_device_config_write(device, OSTC3_PRESSURE_SENSOR_OFFSET, data, sizeof(data));
800        if (rc != DC_STATUS_SUCCESS)
801                return rc;
802        EMIT_PROGRESS();
803
804        // OSTC3 stores the tempSensorOffset in two-complement
805        data[0] = (unsigned char)m_deviceDetails->tempSensorOffset;
806        rc = hw_ostc3_device_config_write(device, OSTC3_TEMP_SENSOR_OFFSET, data, sizeof(data));
807        if (rc != DC_STATUS_SUCCESS)
808                return rc;
809        EMIT_PROGRESS();
810
811
812        //sync date and time
813        if (m_deviceDetails->syncTime) {
814                dc_datetime_t now;
815                dc_datetime_localtime(&now, dc_datetime_now());
816
817                rc = hw_ostc3_device_clock(device, &now);
818        }
819
820        EMIT_PROGRESS();
821
822        return rc;
823}
824
825
826#if DC_VERSION_CHECK(0, 5, 0)
827static dc_status_t read_ostc3_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
828{
829        dc_status_t rc;
830        dc_event_progress_t progress;
831        progress.current = 0;
832        progress.maximum = 57;
833        unsigned char hardware[1];
834
835        //Read hardware type
836        rc = hw_ostc3_device_hardware (device, hardware, sizeof (hardware));
837        if (rc != DC_STATUS_SUCCESS)
838                return rc;
839
840        dc_descriptor_t *desc = get_descriptor(DC_FAMILY_HW_OSTC3, hardware[0]);
841        if (desc) {
842                m_deviceDetails->model = dc_descriptor_get_product(desc);
843                dc_descriptor_free(desc);
844        } else {
845                return DC_STATUS_UNSUPPORTED;
846        }
847
848        if (m_deviceDetails->model == "OSTC 4")
849                return read_ostc4_settings(device, m_deviceDetails, progress_cb, userdata);
850
851        EMIT_PROGRESS();
852
853        //Read gas mixes
854        gas gas1;
855        gas gas2;
856        gas gas3;
857        gas gas4;
858        gas gas5;
859        unsigned char gasData[4] = { 0, 0, 0, 0 };
860
861        rc = hw_ostc3_device_config_read(device, OSTC3_GAS1, gasData, sizeof(gasData));
862        if (rc != DC_STATUS_SUCCESS)
863                return rc;
864        gas1.oxygen = gasData[0];
865        gas1.helium = gasData[1];
866        gas1.type = gasData[2];
867        gas1.depth = gasData[3];
868        EMIT_PROGRESS();
869
870        rc = hw_ostc3_device_config_read(device, OSTC3_GAS2, gasData, sizeof(gasData));
871        if (rc != DC_STATUS_SUCCESS)
872                return rc;
873        gas2.oxygen = gasData[0];
874        gas2.helium = gasData[1];
875        gas2.type = gasData[2];
876        gas2.depth = gasData[3];
877        EMIT_PROGRESS();
878
879        rc = hw_ostc3_device_config_read(device, OSTC3_GAS3, gasData, sizeof(gasData));
880        if (rc != DC_STATUS_SUCCESS)
881                return rc;
882        gas3.oxygen = gasData[0];
883        gas3.helium = gasData[1];
884        gas3.type = gasData[2];
885        gas3.depth = gasData[3];
886        EMIT_PROGRESS();
887
888        rc = hw_ostc3_device_config_read(device, OSTC3_GAS4, gasData, sizeof(gasData));
889        if (rc != DC_STATUS_SUCCESS)
890                return rc;
891        gas4.oxygen = gasData[0];
892        gas4.helium = gasData[1];
893        gas4.type = gasData[2];
894        gas4.depth = gasData[3];
895        EMIT_PROGRESS();
896
897        rc = hw_ostc3_device_config_read(device, OSTC3_GAS5, gasData, sizeof(gasData));
898        if (rc != DC_STATUS_SUCCESS)
899                return rc;
900        gas5.oxygen = gasData[0];
901        gas5.helium = gasData[1];
902        gas5.type = gasData[2];
903        gas5.depth = gasData[3];
904        EMIT_PROGRESS();
905
906        m_deviceDetails->gas1 = gas1;
907        m_deviceDetails->gas2 = gas2;
908        m_deviceDetails->gas3 = gas3;
909        m_deviceDetails->gas4 = gas4;
910        m_deviceDetails->gas5 = gas5;
911        EMIT_PROGRESS();
912
913        //Read Dil Values
914        gas dil1;
915        gas dil2;
916        gas dil3;
917        gas dil4;
918        gas dil5;
919        unsigned char dilData[4] = { 0, 0, 0, 0 };
920
921        rc = hw_ostc3_device_config_read(device, OSTC3_DIL1, dilData, sizeof(dilData));
922        if (rc != DC_STATUS_SUCCESS)
923                return rc;
924        dil1.oxygen = dilData[0];
925        dil1.helium = dilData[1];
926        dil1.type = dilData[2];
927        dil1.depth = dilData[3];
928        EMIT_PROGRESS();
929
930        rc = hw_ostc3_device_config_read(device, OSTC3_DIL2, dilData, sizeof(dilData));
931        if (rc != DC_STATUS_SUCCESS)
932                return rc;
933        dil2.oxygen = dilData[0];
934        dil2.helium = dilData[1];
935        dil2.type = dilData[2];
936        dil2.depth = dilData[3];
937        EMIT_PROGRESS();
938
939        rc = hw_ostc3_device_config_read(device, OSTC3_DIL3, dilData, sizeof(dilData));
940        if (rc != DC_STATUS_SUCCESS)
941                return rc;
942        dil3.oxygen = dilData[0];
943        dil3.helium = dilData[1];
944        dil3.type = dilData[2];
945        dil3.depth = dilData[3];
946        EMIT_PROGRESS();
947
948        rc = hw_ostc3_device_config_read(device, OSTC3_DIL4, dilData, sizeof(dilData));
949        if (rc != DC_STATUS_SUCCESS)
950                return rc;
951        dil4.oxygen = dilData[0];
952        dil4.helium = dilData[1];
953        dil4.type = dilData[2];
954        dil4.depth = dilData[3];
955        EMIT_PROGRESS();
956
957        rc = hw_ostc3_device_config_read(device, OSTC3_DIL5, dilData, sizeof(dilData));
958        if (rc != DC_STATUS_SUCCESS)
959                return rc;
960        dil5.oxygen = dilData[0];
961        dil5.helium = dilData[1];
962        dil5.type = dilData[2];
963        dil5.depth = dilData[3];
964        EMIT_PROGRESS();
965
966        m_deviceDetails->dil1 = dil1;
967        m_deviceDetails->dil2 = dil2;
968        m_deviceDetails->dil3 = dil3;
969        m_deviceDetails->dil4 = dil4;
970        m_deviceDetails->dil5 = dil5;
971
972        //Read setpoint Values
973        setpoint sp1;
974        setpoint sp2;
975        setpoint sp3;
976        setpoint sp4;
977        setpoint sp5;
978        unsigned char spData[2] = { 0, 0 };
979
980        rc = hw_ostc3_device_config_read(device, OSTC3_SP1, spData, sizeof(spData));
981        if (rc != DC_STATUS_SUCCESS)
982                return rc;
983        sp1.sp = spData[0];
984        sp1.depth = spData[1];
985        EMIT_PROGRESS();
986
987        rc = hw_ostc3_device_config_read(device, OSTC3_SP2, spData, sizeof(spData));
988        if (rc != DC_STATUS_SUCCESS)
989                return rc;
990        sp2.sp = spData[0];
991        sp2.depth = spData[1];
992        EMIT_PROGRESS();
993
994        rc = hw_ostc3_device_config_read(device, OSTC3_SP3, spData, sizeof(spData));
995        if (rc != DC_STATUS_SUCCESS)
996                return rc;
997        sp3.sp = spData[0];
998        sp3.depth = spData[1];
999        EMIT_PROGRESS();
1000
1001        rc = hw_ostc3_device_config_read(device, OSTC3_SP4, spData, sizeof(spData));
1002        if (rc != DC_STATUS_SUCCESS)
1003                return rc;
1004        sp4.sp = spData[0];
1005        sp4.depth = spData[1];
1006        EMIT_PROGRESS();
1007
1008        rc = hw_ostc3_device_config_read(device, OSTC3_SP5, spData, sizeof(spData));
1009        if (rc != DC_STATUS_SUCCESS)
1010                return rc;
1011        sp5.sp = spData[0];
1012        sp5.depth = spData[1];
1013        EMIT_PROGRESS();
1014
1015        m_deviceDetails->sp1 = sp1;
1016        m_deviceDetails->sp2 = sp2;
1017        m_deviceDetails->sp3 = sp3;
1018        m_deviceDetails->sp4 = sp4;
1019        m_deviceDetails->sp5 = sp5;
1020
1021        //Read other settings
1022        unsigned char uData[1] = { 0 };
1023
1024#define READ_SETTING(_OSTC3_SETTING, _DEVICE_DETAIL)                                            \
1025        do {                                                                                    \
1026                rc = hw_ostc3_device_config_read(device, _OSTC3_SETTING, uData, sizeof(uData)); \
1027                if (rc != DC_STATUS_SUCCESS)                                                    \
1028                        return rc;                                                              \
1029                m_deviceDetails->_DEVICE_DETAIL = uData[0];                                     \
1030                EMIT_PROGRESS();                                                                \
1031        } while (0)
1032
1033        READ_SETTING(OSTC3_DIVE_MODE, diveMode);
1034        READ_SETTING(OSTC3_SATURATION, saturation);
1035        READ_SETTING(OSTC3_DESATURATION, desaturation);
1036        READ_SETTING(OSTC3_LAST_DECO, lastDeco);
1037        READ_SETTING(OSTC3_BRIGHTNESS, brightness);
1038        READ_SETTING(OSTC3_UNITS, units);
1039        READ_SETTING(OSTC3_SAMPLING_RATE, samplingRate);
1040        READ_SETTING(OSTC3_SALINITY, salinity);
1041        READ_SETTING(OSTC3_DIVEMODE_COLOR, diveModeColor);
1042        READ_SETTING(OSTC3_LANGUAGE, language);
1043        READ_SETTING(OSTC3_DATE_FORMAT, dateFormat);
1044        READ_SETTING(OSTC3_COMPASS_GAIN, compassGain);
1045        READ_SETTING(OSTC3_SAFETY_STOP, safetyStop);
1046        READ_SETTING(OSTC3_GF_HIGH, gfHigh);
1047        READ_SETTING(OSTC3_GF_LOW, gfLow);
1048        READ_SETTING(OSTC3_PPO2_MIN, ppO2Min);
1049        READ_SETTING(OSTC3_PPO2_MAX, ppO2Max);
1050        READ_SETTING(OSTC3_FUTURE_TTS, futureTTS);
1051        READ_SETTING(OSTC3_CCR_MODE, ccrMode);
1052        READ_SETTING(OSTC3_DECO_TYPE, decoType);
1053        READ_SETTING(OSTC3_AGF_SELECTABLE, aGFSelectable);
1054        READ_SETTING(OSTC3_AGF_HIGH, aGFHigh);
1055        READ_SETTING(OSTC3_AGF_LOW, aGFLow);
1056        READ_SETTING(OSTC3_CALIBRATION_GAS_O2, calibrationGas);
1057        READ_SETTING(OSTC3_FLIP_SCREEN, flipScreen);
1058        READ_SETTING(OSTC3_SETPOINT_FALLBACK, setPointFallback);
1059        READ_SETTING(OSTC3_LEFT_BUTTON_SENSIVITY, leftButtonSensitivity);
1060        READ_SETTING(OSTC3_RIGHT_BUTTON_SENSIVITY, rightButtonSensitivity);
1061        READ_SETTING(OSTC3_BOTTOM_GAS_CONSUMPTION, bottomGasConsumption);
1062        READ_SETTING(OSTC3_DECO_GAS_CONSUMPTION, decoGasConsumption);
1063        READ_SETTING(OSTC3_MOD_WARNING, modWarning);
1064        READ_SETTING(OSTC3_DYNAMIC_ASCEND_RATE, dynamicAscendRate);
1065        READ_SETTING(OSTC3_GRAPHICAL_SPEED_INDICATOR, graphicalSpeedIndicator);
1066        READ_SETTING(OSTC3_ALWAYS_SHOW_PPO2, alwaysShowppO2);
1067        READ_SETTING(OSTC3_SAFETY_STOP_LENGTH, safetyStopLength);
1068        READ_SETTING(OSTC3_SAFETY_STOP_START_DEPTH, safetyStopStartDepth);
1069        READ_SETTING(OSTC3_SAFETY_STOP_END_DEPTH, safetyStopEndDepth);
1070        READ_SETTING(OSTC3_SAFETY_STOP_RESET_DEPTH, safetyStopResetDepth);
1071
1072#undef READ_SETTING
1073
1074        rc = hw_ostc3_device_config_read(device, OSTC3_PRESSURE_SENSOR_OFFSET, uData, sizeof(uData));
1075        if (rc != DC_STATUS_SUCCESS)
1076                return rc;
1077        // OSTC3 stores the pressureSensorOffset in two-complement
1078        m_deviceDetails->pressureSensorOffset = (signed char)uData[0];
1079        EMIT_PROGRESS();
1080
1081        rc = hw_ostc3_device_config_read(device, OSTC3_TEMP_SENSOR_OFFSET, uData, sizeof(uData));
1082        if (rc != DC_STATUS_SUCCESS)
1083                return rc;
1084        // OSTC3 stores the tempSensorOffset in two-complement
1085        m_deviceDetails->tempSensorOffset = (signed char)uData[0];
1086        EMIT_PROGRESS();
1087
1088        //read firmware settings
1089        unsigned char fData[64] = { 0 };
1090        rc = hw_ostc3_device_version(device, fData, sizeof(fData));
1091        if (rc != DC_STATUS_SUCCESS)
1092                return rc;
1093        int serial = fData[0] + (fData[1] << 8);
1094        m_deviceDetails->serialNo = QString::number(serial);
1095        m_deviceDetails->firmwareVersion = QString::number(fData[2]) + "." + QString::number(fData[3]);
1096        QByteArray ar((char *)fData + 4, 60);
1097        m_deviceDetails->customText = ar.trimmed();
1098        EMIT_PROGRESS();
1099
1100        return rc;
1101}
1102
1103static dc_status_t write_ostc3_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
1104{
1105        dc_status_t rc;
1106        dc_event_progress_t progress;
1107        progress.current = 0;
1108        progress.maximum = 56;
1109
1110        //write gas values
1111        unsigned char gas1Data[4] = {
1112                m_deviceDetails->gas1.oxygen,
1113                m_deviceDetails->gas1.helium,
1114                m_deviceDetails->gas1.type,
1115                m_deviceDetails->gas1.depth
1116        };
1117
1118        unsigned char gas2Data[4] = {
1119                m_deviceDetails->gas2.oxygen,
1120                m_deviceDetails->gas2.helium,
1121                m_deviceDetails->gas2.type,
1122                m_deviceDetails->gas2.depth
1123        };
1124
1125        unsigned char gas3Data[4] = {
1126                m_deviceDetails->gas3.oxygen,
1127                m_deviceDetails->gas3.helium,
1128                m_deviceDetails->gas3.type,
1129                m_deviceDetails->gas3.depth
1130        };
1131
1132        unsigned char gas4Data[4] = {
1133                m_deviceDetails->gas4.oxygen,
1134                m_deviceDetails->gas4.helium,
1135                m_deviceDetails->gas4.type,
1136                m_deviceDetails->gas4.depth
1137        };
1138
1139        unsigned char gas5Data[4] = {
1140                m_deviceDetails->gas5.oxygen,
1141                m_deviceDetails->gas5.helium,
1142                m_deviceDetails->gas5.type,
1143                m_deviceDetails->gas5.depth
1144        };
1145        //gas 1
1146        rc = hw_ostc3_device_config_write(device, OSTC3_GAS1, gas1Data, sizeof(gas1Data));
1147        if (rc != DC_STATUS_SUCCESS)
1148                return rc;
1149        EMIT_PROGRESS();
1150        //gas 2
1151        rc = hw_ostc3_device_config_write(device, OSTC3_GAS2, gas2Data, sizeof(gas2Data));
1152        if (rc != DC_STATUS_SUCCESS)
1153                return rc;
1154        EMIT_PROGRESS();
1155        //gas 3
1156        rc = hw_ostc3_device_config_write(device, OSTC3_GAS3, gas3Data, sizeof(gas3Data));
1157        if (rc != DC_STATUS_SUCCESS)
1158                return rc;
1159        EMIT_PROGRESS();
1160        //gas 4
1161        rc = hw_ostc3_device_config_write(device, OSTC3_GAS4, gas4Data, sizeof(gas4Data));
1162        if (rc != DC_STATUS_SUCCESS)
1163                return rc;
1164        EMIT_PROGRESS();
1165        //gas 5
1166        rc = hw_ostc3_device_config_write(device, OSTC3_GAS5, gas5Data, sizeof(gas5Data));
1167        if (rc != DC_STATUS_SUCCESS)
1168                return rc;
1169        EMIT_PROGRESS();
1170
1171        //write setpoint values
1172        unsigned char sp1Data[2] = {
1173                m_deviceDetails->sp1.sp,
1174                m_deviceDetails->sp1.depth
1175        };
1176
1177        unsigned char sp2Data[2] = {
1178                m_deviceDetails->sp2.sp,
1179                m_deviceDetails->sp2.depth
1180        };
1181
1182        unsigned char sp3Data[2] = {
1183                m_deviceDetails->sp3.sp,
1184                m_deviceDetails->sp3.depth
1185        };
1186
1187        unsigned char sp4Data[2] = {
1188                m_deviceDetails->sp4.sp,
1189                m_deviceDetails->sp4.depth
1190        };
1191
1192        unsigned char sp5Data[2] = {
1193                m_deviceDetails->sp5.sp,
1194                m_deviceDetails->sp5.depth
1195        };
1196
1197        //sp 1
1198        rc = hw_ostc3_device_config_write(device, OSTC3_SP1, sp1Data, sizeof(sp1Data));
1199        if (rc != DC_STATUS_SUCCESS)
1200                return rc;
1201        EMIT_PROGRESS();
1202        //sp 2
1203        rc = hw_ostc3_device_config_write(device, OSTC3_SP2, sp2Data, sizeof(sp2Data));
1204        if (rc != DC_STATUS_SUCCESS)
1205                return rc;
1206        EMIT_PROGRESS();
1207        //sp 3
1208        rc = hw_ostc3_device_config_write(device, OSTC3_SP3, sp3Data, sizeof(sp3Data));
1209        if (rc != DC_STATUS_SUCCESS)
1210                return rc;
1211        EMIT_PROGRESS();
1212        //sp 4
1213        rc = hw_ostc3_device_config_write(device, OSTC3_SP4, sp4Data, sizeof(sp4Data));
1214        if (rc != DC_STATUS_SUCCESS)
1215                return rc;
1216        EMIT_PROGRESS();
1217        //sp 5
1218        rc = hw_ostc3_device_config_write(device, OSTC3_SP5, sp5Data, sizeof(sp5Data));
1219        if (rc != DC_STATUS_SUCCESS)
1220                return rc;
1221        EMIT_PROGRESS();
1222
1223        //write dil values
1224        unsigned char dil1Data[4] = {
1225                m_deviceDetails->dil1.oxygen,
1226                m_deviceDetails->dil1.helium,
1227                m_deviceDetails->dil1.type,
1228                m_deviceDetails->dil1.depth
1229        };
1230
1231        unsigned char dil2Data[4] = {
1232                m_deviceDetails->dil2.oxygen,
1233                m_deviceDetails->dil2.helium,
1234                m_deviceDetails->dil2.type,
1235                m_deviceDetails->dil2.depth
1236        };
1237
1238        unsigned char dil3Data[4] = {
1239                m_deviceDetails->dil3.oxygen,
1240                m_deviceDetails->dil3.helium,
1241                m_deviceDetails->dil3.type,
1242                m_deviceDetails->dil3.depth
1243        };
1244
1245        unsigned char dil4Data[4] = {
1246                m_deviceDetails->dil4.oxygen,
1247                m_deviceDetails->dil4.helium,
1248                m_deviceDetails->dil4.type,
1249                m_deviceDetails->dil4.depth
1250        };
1251
1252        unsigned char dil5Data[4] = {
1253                m_deviceDetails->dil5.oxygen,
1254                m_deviceDetails->dil5.helium,
1255                m_deviceDetails->dil5.type,
1256                m_deviceDetails->dil5.depth
1257        };
1258        //dil 1
1259        rc = hw_ostc3_device_config_write(device, OSTC3_DIL1, dil1Data, sizeof(gas1Data));
1260        if (rc != DC_STATUS_SUCCESS)
1261                return rc;
1262        EMIT_PROGRESS();
1263        //dil 2
1264        rc = hw_ostc3_device_config_write(device, OSTC3_DIL2, dil2Data, sizeof(dil2Data));
1265        if (rc != DC_STATUS_SUCCESS)
1266                return rc;
1267        EMIT_PROGRESS();
1268        //dil 3
1269        rc = hw_ostc3_device_config_write(device, OSTC3_DIL3, dil3Data, sizeof(dil3Data));
1270        if (rc != DC_STATUS_SUCCESS)
1271                return rc;
1272        EMIT_PROGRESS();
1273        //dil 4
1274        rc = hw_ostc3_device_config_write(device, OSTC3_DIL4, dil4Data, sizeof(dil4Data));
1275        if (rc != DC_STATUS_SUCCESS)
1276                return rc;
1277        EMIT_PROGRESS();
1278        //dil 5
1279        rc = hw_ostc3_device_config_write(device, OSTC3_DIL5, dil5Data, sizeof(dil5Data));
1280        if (rc != DC_STATUS_SUCCESS)
1281                return rc;
1282        EMIT_PROGRESS();
1283
1284        //write general settings
1285        //custom text
1286        rc = hw_ostc3_device_customtext(device, m_deviceDetails->customText.toUtf8().data());
1287        if (rc != DC_STATUS_SUCCESS)
1288                return rc;
1289
1290        unsigned char data[1] = { 0 };
1291#define WRITE_SETTING(_OSTC3_SETTING, _DEVICE_DETAIL)                                          \
1292        do {                                                                                   \
1293                data[0] = m_deviceDetails->_DEVICE_DETAIL;                                     \
1294                rc = hw_ostc3_device_config_write(device, _OSTC3_SETTING, data, sizeof(data)); \
1295                if (rc != DC_STATUS_SUCCESS)                                                   \
1296                        return rc;                                                             \
1297                EMIT_PROGRESS();                                                               \
1298        } while (0)
1299
1300        WRITE_SETTING(OSTC3_DIVE_MODE, diveMode);
1301        WRITE_SETTING(OSTC3_SATURATION, saturation);
1302        WRITE_SETTING(OSTC3_DESATURATION, desaturation);
1303        WRITE_SETTING(OSTC3_LAST_DECO, lastDeco);
1304        WRITE_SETTING(OSTC3_BRIGHTNESS, brightness);
1305        WRITE_SETTING(OSTC3_UNITS, units);
1306        WRITE_SETTING(OSTC3_SAMPLING_RATE, samplingRate);
1307        WRITE_SETTING(OSTC3_SALINITY, salinity);
1308        WRITE_SETTING(OSTC3_DIVEMODE_COLOR, diveModeColor);
1309        WRITE_SETTING(OSTC3_LANGUAGE, language);
1310        WRITE_SETTING(OSTC3_DATE_FORMAT, dateFormat);
1311        WRITE_SETTING(OSTC3_COMPASS_GAIN, compassGain);
1312        WRITE_SETTING(OSTC3_SAFETY_STOP, safetyStop);
1313        WRITE_SETTING(OSTC3_GF_HIGH, gfHigh);
1314        WRITE_SETTING(OSTC3_GF_LOW, gfLow);
1315        WRITE_SETTING(OSTC3_PPO2_MIN, ppO2Min);
1316        WRITE_SETTING(OSTC3_PPO2_MAX, ppO2Max);
1317        WRITE_SETTING(OSTC3_FUTURE_TTS, futureTTS);
1318        WRITE_SETTING(OSTC3_CCR_MODE, ccrMode);
1319        WRITE_SETTING(OSTC3_DECO_TYPE, decoType);
1320        WRITE_SETTING(OSTC3_AGF_SELECTABLE, aGFSelectable);
1321        WRITE_SETTING(OSTC3_AGF_HIGH, aGFHigh);
1322        WRITE_SETTING(OSTC3_AGF_LOW, aGFLow);
1323        WRITE_SETTING(OSTC3_CALIBRATION_GAS_O2, calibrationGas);
1324        WRITE_SETTING(OSTC3_FLIP_SCREEN, flipScreen);
1325        WRITE_SETTING(OSTC3_SETPOINT_FALLBACK, setPointFallback);
1326        WRITE_SETTING(OSTC3_LEFT_BUTTON_SENSIVITY, leftButtonSensitivity);
1327        WRITE_SETTING(OSTC3_RIGHT_BUTTON_SENSIVITY, rightButtonSensitivity);
1328        WRITE_SETTING(OSTC3_BOTTOM_GAS_CONSUMPTION, bottomGasConsumption);
1329        WRITE_SETTING(OSTC3_DECO_GAS_CONSUMPTION, decoGasConsumption);
1330        WRITE_SETTING(OSTC3_MOD_WARNING, modWarning);
1331        WRITE_SETTING(OSTC3_DYNAMIC_ASCEND_RATE, dynamicAscendRate);
1332        WRITE_SETTING(OSTC3_GRAPHICAL_SPEED_INDICATOR, graphicalSpeedIndicator);
1333        WRITE_SETTING(OSTC3_ALWAYS_SHOW_PPO2, alwaysShowppO2);
1334        WRITE_SETTING(OSTC3_SAFETY_STOP_LENGTH, safetyStopLength);
1335        WRITE_SETTING(OSTC3_SAFETY_STOP_START_DEPTH, safetyStopStartDepth);
1336        WRITE_SETTING(OSTC3_SAFETY_STOP_END_DEPTH, safetyStopEndDepth);
1337        WRITE_SETTING(OSTC3_SAFETY_STOP_RESET_DEPTH, safetyStopResetDepth);
1338
1339#undef WRITE_SETTING
1340
1341        // OSTC3 stores the pressureSensorOffset in two-complement
1342        data[0] = (unsigned char)m_deviceDetails->pressureSensorOffset;
1343        rc = hw_ostc3_device_config_write(device, OSTC3_PRESSURE_SENSOR_OFFSET, data, sizeof(data));
1344        if (rc != DC_STATUS_SUCCESS)
1345                return rc;
1346        EMIT_PROGRESS();
1347
1348        // OSTC3 stores the tempSensorOffset in two-complement
1349        data[0] = (unsigned char)m_deviceDetails->tempSensorOffset;
1350        rc = hw_ostc3_device_config_write(device, OSTC3_TEMP_SENSOR_OFFSET, data, sizeof(data));
1351        if (rc != DC_STATUS_SUCCESS)
1352                return rc;
1353        EMIT_PROGRESS();
1354
1355        //sync date and time
1356        if (m_deviceDetails->syncTime) {
1357                dc_datetime_t now;
1358                dc_datetime_localtime(&now, dc_datetime_now());
1359
1360                rc = hw_ostc3_device_clock(device, &now);
1361        }
1362        EMIT_PROGRESS();
1363
1364        return rc;
1365}
1366#endif /* DC_VERSION_CHECK(0, 5, 0) */
1367
1368static dc_status_t read_ostc_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
1369{
1370        dc_status_t rc;
1371        dc_event_progress_t progress;
1372        progress.current = 0;
1373        progress.maximum = 3;
1374
1375        unsigned char data[256] = {};
1376#ifdef DEBUG_OSTC_CF
1377        // FIXME: how should we report settings not supported back?
1378        unsigned char max_CF = 0;
1379#endif
1380        rc = hw_ostc_device_eeprom_read(device, 0, data, sizeof(data));
1381        if (rc != DC_STATUS_SUCCESS)
1382                return rc;
1383        EMIT_PROGRESS();
1384        m_deviceDetails->serialNo = QString::number(data[1] << 8 ^ data[0]);
1385        m_deviceDetails->numberOfDives = data[3] << 8 ^ data[2];
1386        //Byte5-6:
1387        //Gas 1 default (%O2=21, %He=0)
1388        gas gas1;
1389        gas1.oxygen = data[6];
1390        gas1.helium = data[7];
1391        //Byte9-10:
1392        //Gas 2 default (%O2=21, %He=0)
1393        gas gas2;
1394        gas2.oxygen = data[10];
1395        gas2.helium = data[11];
1396        //Byte13-14:
1397        //Gas 3 default (%O2=21, %He=0)
1398        gas gas3;
1399        gas3.oxygen = data[14];
1400        gas3.helium = data[15];
1401        //Byte17-18:
1402        //Gas 4 default (%O2=21, %He=0)
1403        gas gas4;
1404        gas4.oxygen = data[18];
1405        gas4.helium = data[19];
1406        //Byte21-22:
1407        //Gas 5 default (%O2=21, %He=0)
1408        gas gas5;
1409        gas5.oxygen = data[22];
1410        gas5.helium = data[23];
1411        //Byte25-26:
1412        //Gas 6 current (%O2, %He)
1413        m_deviceDetails->salinity = data[26];
1414        // Active Gas Flag Register
1415        gas1.type = data[27] & 0x01;
1416        gas2.type = (data[27] & 0x02) >> 1;
1417        gas3.type = (data[27] & 0x04) >> 2;
1418        gas4.type = (data[27] & 0x08) >> 3;
1419        gas5.type = (data[27] & 0x10) >> 4;
1420
1421        // Gas switch depths
1422        gas1.depth = data[28];
1423        gas2.depth = data[29];
1424        gas3.depth = data[30];
1425        gas4.depth = data[31];
1426        gas5.depth = data[32];
1427        // 33 which gas is Fist gas
1428        switch (data[33]) {
1429        case 1:
1430                gas1.type = 2;
1431                break;
1432        case 2:
1433                gas2.type = 2;
1434                break;
1435        case 3:
1436                gas3.type = 2;
1437                break;
1438        case 4:
1439                gas4.type = 2;
1440                break;
1441        case 5:
1442                gas5.type = 2;
1443                break;
1444        default:
1445                //Error?
1446                break;
1447        }
1448        // Data filled up, set the gases.
1449        m_deviceDetails->gas1 = gas1;
1450        m_deviceDetails->gas2 = gas2;
1451        m_deviceDetails->gas3 = gas3;
1452        m_deviceDetails->gas4 = gas4;
1453        m_deviceDetails->gas5 = gas5;
1454        m_deviceDetails->decoType = data[34];
1455        //Byte36:
1456        //Use O2 Sensor Module in CC Modes (0= OFF, 1= ON) (Only available in old OSTC1 - unused for OSTC Mk.2/2N)
1457        //m_deviceDetails->ccrMode = data[35];
1458        setpoint sp1;
1459        sp1.sp = data[36];
1460        sp1.depth = 0;
1461        setpoint sp2;
1462        sp2.sp = data[37];
1463        sp2.depth = 0;
1464        setpoint sp3;
1465        sp3.sp = data[38];
1466        sp3.depth = 0;
1467        m_deviceDetails->sp1 = sp1;
1468        m_deviceDetails->sp2 = sp2;
1469        m_deviceDetails->sp3 = sp3;
1470        // Byte41-42:
1471        // Lowest Battery voltage seen (in mV)
1472        // Byte43:
1473        // Lowest Battery voltage seen at (Month)
1474        // Byte44:
1475        // Lowest Battery voltage seen at (Day)
1476        // Byte45:
1477        // Lowest Battery voltage seen at (Year)
1478        // Byte46-47:
1479        // Lowest Battery voltage seen at (Temperature in 0.1 °C)
1480        // Byte48:
1481        // Last complete charge at (Month)
1482        // Byte49:
1483        // Last complete charge at (Day)
1484        // Byte50:
1485        // Last complete charge at (Year)
1486        // Byte51-52:
1487        // Total charge cycles
1488        // Byte53-54:
1489        // Total complete charge cycles
1490        // Byte55-56:
1491        // Temperature Extrema minimum (Temperature in 0.1 °C)
1492        // Byte57:
1493        // Temperature Extrema minimum at (Month)
1494        // Byte58:
1495        // Temperature Extrema minimum at (Day)
1496        // Byte59:
1497        // Temperature Extrema minimum at (Year)
1498        // Byte60-61:
1499        // Temperature Extrema maximum (Temperature in 0.1 °C)
1500        // Byte62:
1501        // Temperature Extrema maximum at (Month)
1502        // Byte63:
1503        // Temperature Extrema maximum at (Day)
1504        // Byte64:
1505        // Temperature Extrema maximum at (Year)
1506        // Byte65:
1507        // Custom Text active (=1), Custom Text Disabled (<>1)
1508        // Byte66-90:
1509        // TO FIX EDITOR SYNTAX/INDENT {
1510        // (25Bytes): Custom Text for Surfacemode (Real text must end with "}")
1511        // Example: OSTC Dive Computer} (19 Characters incl. "}") Bytes 85-90 will be ignored.
1512        if (data[64] == 1) {
1513                // Make shure the data is null-terminated
1514                data[89] = 0;
1515                // Find the internal termination and replace it with 0
1516                char *term = strchr((char *)data + 65, (int)'}');
1517                if (term)
1518                        *term = 0;
1519                m_deviceDetails->customText = (const char *)data + 65;
1520        }
1521        // Byte91:
1522        // Dim OLED in Divemode (>0), Normal mode (=0)
1523        // Byte92:
1524        // Date format for all outputs:
1525        // =0: MM/DD/YY
1526        // =1: DD/MM/YY
1527        // =2: YY/MM/DD
1528        m_deviceDetails->dateFormat = data[91];
1529// Byte93:
1530// Total number of CF used in installed firmware
1531#ifdef DEBUG_OSTC_CF
1532        max_CF = data[92];
1533#endif
1534        // Byte94:
1535        // Last selected view for customview area in surface mode
1536        // Byte95:
1537        // Last selected view for customview area in dive mode
1538        // Byte96-97:
1539        // Diluent 1 Default (%O2,%He)
1540        // Byte98-99:
1541        // Diluent 1 Current (%O2,%He)
1542        gas dil1(data[97], data[98]);
1543        // Byte100-101:
1544        // Gasuent 2 Default (%O2,%He)
1545        // Byte102-103:
1546        // Gasuent 2 Current (%O2,%He)
1547        gas dil2(data[101], data[102]);
1548        // Byte104-105:
1549        // Gasuent 3 Default (%O2,%He)
1550        // Byte106-107:
1551        // Gasuent 3 Current (%O2,%He)
1552        gas dil3(data[105], data[106]);
1553        // Byte108-109:
1554        // Gasuent 4 Default (%O2,%He)
1555        // Byte110-111:
1556        // Gasuent 4 Current (%O2,%He)
1557        gas dil4(data[109], data[110]);
1558        // Byte112-113:
1559        // Gasuent 5 Default (%O2,%He)
1560        // Byte114-115:
1561        // Gasuent 5 Current (%O2,%He)
1562        gas dil5(data[113], data[114]);
1563        // Byte116:
1564        // First Diluent (1-5)
1565        switch (data[115]) {
1566        case 1:
1567                dil1.type = 2;
1568                break;
1569        case 2:
1570                dil2.type = 2;
1571                break;
1572        case 3:
1573                dil3.type = 2;
1574                break;
1575        case 4:
1576                dil4.type = 2;
1577                break;
1578        case 5:
1579                dil5.type = 2;
1580                break;
1581        default:
1582                //Error?
1583                break;
1584        }
1585        m_deviceDetails->dil1 = dil1;
1586        m_deviceDetails->dil2 = dil2;
1587        m_deviceDetails->dil3 = dil3;
1588        m_deviceDetails->dil4 = dil4;
1589        m_deviceDetails->dil5 = dil5;
1590        // Byte117-128:
1591        // not used/reserved
1592        // Byte129-256:
1593        // 32 custom Functions (CF0-CF31)
1594
1595        // Decode the relevant ones
1596        // CF11: Factor for saturation processes
1597        m_deviceDetails->saturation = read_ostc_cf(data, 11);
1598        // CF12: Factor for desaturation processes
1599        m_deviceDetails->desaturation = read_ostc_cf(data, 12);
1600        // CF17: Lower threshold for ppO2 warning
1601        m_deviceDetails->ppO2Min = read_ostc_cf(data, 17);
1602        // CF18: Upper threshold for ppO2 warning
1603        m_deviceDetails->ppO2Max = read_ostc_cf(data, 18);
1604        // CF20: Depth sampling rate for Profile storage
1605        m_deviceDetails->samplingRate = read_ostc_cf(data, 20);
1606        // CF29: Depth of last decompression stop
1607        m_deviceDetails->lastDeco = read_ostc_cf(data, 29);
1608
1609#ifdef DEBUG_OSTC_CF
1610        for (int cf = 0; cf <= 31 && cf <= max_CF; cf++)
1611                printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
1612#endif
1613
1614        rc = hw_ostc_device_eeprom_read(device, 1, data, sizeof(data));
1615        if (rc != DC_STATUS_SUCCESS)
1616                return rc;
1617        EMIT_PROGRESS();
1618        // Byte1:
1619        // Logbook version indicator (Not writable!)
1620        // Byte2-3:
1621        // Last Firmware installed, 1st Byte.2nd Byte (e.g. „1.90“) (Not writable!)
1622        m_deviceDetails->firmwareVersion = QString::number(data[1]) + "." + QString::number(data[2]);
1623        // Byte4:
1624        // OLED brightness (=0: Eco, =1 High) (Not writable!)
1625        // Byte5-11:
1626        // Time/Date vault during firmware updates
1627        // Byte12-128
1628        // not used/reserved
1629        // Byte129-256:
1630        // 32 custom Functions (CF 32-63)
1631
1632        // Decode the relevant ones
1633        // CF32: Gradient Factor low
1634        m_deviceDetails->gfLow = read_ostc_cf(data, 32);
1635        // CF33: Gradient Factor high
1636        m_deviceDetails->gfHigh = read_ostc_cf(data, 33);
1637        // CF56: Bottom gas consumption
1638        m_deviceDetails->bottomGasConsumption = read_ostc_cf(data, 56);
1639        // CF57: Ascent gas consumption
1640        m_deviceDetails->decoGasConsumption = read_ostc_cf(data, 57);
1641        // CF58: Future time to surface setFutureTTS
1642        m_deviceDetails->futureTTS = read_ostc_cf(data, 58);
1643
1644#ifdef DEBUG_OSTC_CF
1645        for (int cf = 32; cf <= 63 && cf <= max_CF; cf++)
1646                printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
1647#endif
1648
1649        rc = hw_ostc_device_eeprom_read(device, 2, data, sizeof(data));
1650        if (rc != DC_STATUS_SUCCESS)
1651                return rc;
1652        EMIT_PROGRESS();
1653        // Byte1-4:
1654        // not used/reserved (Not writable!)
1655        // Byte5-128:
1656        // not used/reserved
1657        // Byte129-256:
1658        // 32 custom Functions (CF 64-95)
1659
1660        // Decode the relevant ones
1661        // CF60: Graphic velocity
1662        m_deviceDetails->graphicalSpeedIndicator = read_ostc_cf(data, 60);
1663        // CF65: Show safety stop
1664        m_deviceDetails->safetyStop = read_ostc_cf(data, 65);
1665        // CF67: Alternaitve Gradient Factor low
1666        m_deviceDetails->aGFLow = read_ostc_cf(data, 67);
1667        // CF68: Alternative Gradient Factor high
1668        m_deviceDetails->aGFHigh = read_ostc_cf(data, 68);
1669        // CF69: Allow Gradient Factor change
1670        m_deviceDetails->aGFSelectable = read_ostc_cf(data, 69);
1671        // CF70: Safety Stop Duration [s]
1672        m_deviceDetails->safetyStopLength = read_ostc_cf(data, 70);
1673        // CF71: Safety Stop Start Depth [m]
1674        m_deviceDetails->safetyStopStartDepth = read_ostc_cf(data, 71);
1675        // CF72: Safety Stop End Depth [m]
1676        m_deviceDetails->safetyStopEndDepth = read_ostc_cf(data, 72);
1677        // CF73: Safety Stop Reset Depth [m]
1678        m_deviceDetails->safetyStopResetDepth = read_ostc_cf(data, 73);
1679        // CF74: Battery Timeout [min]
1680
1681#ifdef DEBUG_OSTC_CF
1682        for (int cf = 64; cf <= 95 && cf <= max_CF; cf++)
1683                printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
1684#endif
1685
1686        return rc;
1687}
1688
1689static dc_status_t write_ostc_settings(dc_device_t *device, DeviceDetails *m_deviceDetails, dc_event_callback_t progress_cb, void *userdata)
1690{
1691        dc_status_t rc;
1692        dc_event_progress_t progress;
1693        progress.current = 0;
1694        progress.maximum = 7;
1695        unsigned char data[256] = {};
1696        unsigned char max_CF = 0;
1697
1698        // Because we write whole memory blocks, we read all the current
1699        // values out and then change then ones we should change.
1700        rc = hw_ostc_device_eeprom_read(device, 0, data, sizeof(data));
1701        if (rc != DC_STATUS_SUCCESS)
1702                return rc;
1703        EMIT_PROGRESS();
1704        //Byte5-6:
1705        //Gas 1 default (%O2=21, %He=0)
1706        gas gas1 = m_deviceDetails->gas1;
1707        data[6] = gas1.oxygen;
1708        data[7] = gas1.helium;
1709        //Byte9-10:
1710        //Gas 2 default (%O2=21, %He=0)
1711        gas gas2 = m_deviceDetails->gas2;
1712        data[10] = gas2.oxygen;
1713        data[11] = gas2.helium;
1714        //Byte13-14:
1715        //Gas 3 default (%O2=21, %He=0)
1716        gas gas3 = m_deviceDetails->gas3;
1717        data[14] = gas3.oxygen;
1718        data[15] = gas3.helium;
1719        //Byte17-18:
1720        //Gas 4 default (%O2=21, %He=0)
1721        gas gas4 = m_deviceDetails->gas4;
1722        data[18] = gas4.oxygen;
1723        data[19] = gas4.helium;
1724        //Byte21-22:
1725        //Gas 5 default (%O2=21, %He=0)
1726        gas gas5 = m_deviceDetails->gas5;
1727        data[22] = gas5.oxygen;
1728        data[23] = gas5.helium;
1729        //Byte25-26:
1730        //Gas 6 current (%O2, %He)
1731        data[26] = m_deviceDetails->salinity;
1732        // Gas types, 0=Disabled, 1=Active, 2=Fist
1733        // Active Gas Flag Register
1734        data[27] = 0;
1735        if (gas1.type)
1736                data[27] ^= 0x01;
1737        if (gas2.type)
1738                data[27] ^= 0x02;
1739        if (gas3.type)
1740                data[27] ^= 0x04;
1741        if (gas4.type)
1742                data[27] ^= 0x08;
1743        if (gas5.type)
1744                data[27] ^= 0x10;
1745
1746        // Gas switch depths
1747        data[28] = gas1.depth;
1748        data[29] = gas2.depth;
1749        data[30] = gas3.depth;
1750        data[31] = gas4.depth;
1751        data[32] = gas5.depth;
1752        // 33 which gas is Fist gas
1753        if (gas1.type == 2)
1754                data[33] = 1;
1755        else if (gas2.type == 2)
1756                data[33] = 2;
1757        else if (gas3.type == 2)
1758                data[33] = 3;
1759        else if (gas4.type == 2)
1760                data[33] = 4;
1761        else if (gas5.type == 2)
1762                data[33] = 5;
1763        else
1764                // FIXME: No gas was First?
1765                // Set gas 1 to first
1766                data[33] = 1;
1767
1768        data[34] = m_deviceDetails->decoType;
1769        //Byte36:
1770        //Use O2 Sensor Module in CC Modes (0= OFF, 1= ON) (Only available in old OSTC1 - unused for OSTC Mk.2/2N)
1771        //m_deviceDetails->ccrMode = data[35];
1772        data[36] = m_deviceDetails->sp1.sp;
1773        data[37] = m_deviceDetails->sp2.sp;
1774        data[38] = m_deviceDetails->sp3.sp;
1775        // Byte41-42:
1776        // Lowest Battery voltage seen (in mV)
1777        // Byte43:
1778        // Lowest Battery voltage seen at (Month)
1779        // Byte44:
1780        // Lowest Battery voltage seen at (Day)
1781        // Byte45:
1782        // Lowest Battery voltage seen at (Year)
1783        // Byte46-47:
1784        // Lowest Battery voltage seen at (Temperature in 0.1 °C)
1785        // Byte48:
1786        // Last complete charge at (Month)
1787        // Byte49:
1788        // Last complete charge at (Day)
1789        // Byte50:
1790        // Last complete charge at (Year)
1791        // Byte51-52:
1792        // Total charge cycles
1793        // Byte53-54:
1794        // Total complete charge cycles
1795        // Byte55-56:
1796        // Temperature Extrema minimum (Temperature in 0.1 °C)
1797        // Byte57:
1798        // Temperature Extrema minimum at (Month)
1799        // Byte58:
1800        // Temperature Extrema minimum at (Day)
1801        // Byte59:
1802        // Temperature Extrema minimum at (Year)
1803        // Byte60-61:
1804        // Temperature Extrema maximum (Temperature in 0.1 °C)
1805        // Byte62:
1806        // Temperature Extrema maximum at (Month)
1807        // Byte63:
1808        // Temperature Extrema maximum at (Day)
1809        // Byte64:
1810        // Temperature Extrema maximum at (Year)
1811        // Byte65:
1812        // Custom Text active (=1), Custom Text Disabled (<>1)
1813        // Byte66-90:
1814        // (25Bytes): Custom Text for Surfacemode (Real text must end with "}")
1815        // Example: "OSTC Dive Computer}" (19 Characters incl. "}") Bytes 85-90 will be ignored.
1816        if (m_deviceDetails->customText == "") {
1817                data[64] = 0;
1818        } else {
1819                data[64] = 1;
1820                // Copy the string to the right place in the memory, padded with 0x20 (" ")
1821                strncpy((char *)data + 65, QString("%1").arg(m_deviceDetails->customText, -23, QChar(' ')).toUtf8().data(), 23);
1822                // And terminate the string.
1823                if (m_deviceDetails->customText.length() <= 23)
1824                        data[65 + m_deviceDetails->customText.length()] = '}';
1825                else
1826                        data[90] = '}';
1827        }
1828        // Byte91:
1829        // Dim OLED in Divemode (>0), Normal mode (=0)
1830        // Byte92:
1831        // Date format for all outputs:
1832        // =0: MM/DD/YY
1833        // =1: DD/MM/YY
1834        // =2: YY/MM/DD
1835        data[91] = m_deviceDetails->dateFormat;
1836        // Byte93:
1837        // Total number of CF used in installed firmware
1838        max_CF = data[92];
1839        // Byte94:
1840        // Last selected view for customview area in surface mode
1841        // Byte95:
1842        // Last selected view for customview area in dive mode
1843        // Byte96-97:
1844        // Diluent 1 Default (%O2,%He)
1845        // Byte98-99:
1846        // Diluent 1 Current (%O2,%He)
1847        gas dil1 = m_deviceDetails->dil1;
1848        data[97] = dil1.oxygen;
1849        data[98] = dil1.helium;
1850        // Byte100-101:
1851        // Gasuent 2 Default (%O2,%He)
1852        // Byte102-103:
1853        // Gasuent 2 Current (%O2,%He)
1854        gas dil2 = m_deviceDetails->dil2;
1855        data[101] = dil2.oxygen;
1856        data[102] = dil2.helium;
1857        // Byte104-105:
1858        // Gasuent 3 Default (%O2,%He)
1859        // Byte106-107:
1860        // Gasuent 3 Current (%O2,%He)
1861        gas dil3 = m_deviceDetails->dil3;
1862        data[105] = dil3.oxygen;
1863        data[106] = dil3.helium;
1864        // Byte108-109:
1865        // Gasuent 4 Default (%O2,%He)
1866        // Byte110-111:
1867        // Gasuent 4 Current (%O2,%He)
1868        gas dil4 = m_deviceDetails->dil4;
1869        data[109] = dil4.oxygen;
1870        data[110] = dil4.helium;
1871        // Byte112-113:
1872        // Gasuent 5 Default (%O2,%He)
1873        // Byte114-115:
1874        // Gasuent 5 Current (%O2,%He)
1875        gas dil5 = m_deviceDetails->dil5;
1876        data[113] = dil5.oxygen;
1877        data[114] = dil5.helium;
1878        // Byte116:
1879        // First Diluent (1-5)
1880        if (dil1.type == 2)
1881                data[115] = 1;
1882        else if (dil2.type == 2)
1883                data[115] = 2;
1884        else if (dil3.type == 2)
1885                data[115] = 3;
1886        else if (dil4.type == 2)
1887                data[115] = 4;
1888        else if (dil5.type == 2)
1889                data[115] = 5;
1890        else
1891                // FIXME: No first diluent?
1892                // Set gas 1 to fist
1893                data[115] = 1;
1894
1895        // Byte117-128:
1896        // not used/reserved
1897        // Byte129-256:
1898        // 32 custom Functions (CF0-CF31)
1899
1900        // Write the relevant ones
1901        // CF11: Factor for saturation processes
1902        write_ostc_cf(data, 11, max_CF, m_deviceDetails->saturation);
1903        // CF12: Factor for desaturation processes
1904        write_ostc_cf(data, 12, max_CF, m_deviceDetails->desaturation);
1905        // CF17: Lower threshold for ppO2 warning
1906        write_ostc_cf(data, 17, max_CF, m_deviceDetails->ppO2Min);
1907        // CF18: Upper threshold for ppO2 warning
1908        write_ostc_cf(data, 18, max_CF, m_deviceDetails->ppO2Max);
1909        // CF20: Depth sampling rate for Profile storage
1910        write_ostc_cf(data, 20, max_CF, m_deviceDetails->samplingRate);
1911        // CF29: Depth of last decompression stop
1912        write_ostc_cf(data, 29, max_CF, m_deviceDetails->lastDeco);
1913
1914#ifdef DEBUG_OSTC_CF
1915        for (int cf = 0; cf <= 31 && cf <= max_CF; cf++)
1916                printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
1917#endif
1918        rc = hw_ostc_device_eeprom_write(device, 0, data, sizeof(data));
1919        if (rc != DC_STATUS_SUCCESS)
1920                return rc;
1921        EMIT_PROGRESS();
1922
1923        rc = hw_ostc_device_eeprom_read(device, 1, data, sizeof(data));
1924        if (rc != DC_STATUS_SUCCESS)
1925                return rc;
1926        EMIT_PROGRESS();
1927        // Byte1:
1928        // Logbook version indicator (Not writable!)
1929        // Byte2-3:
1930        // Last Firmware installed, 1st Byte.2nd Byte (e.g. „1.90“) (Not writable!)
1931        // Byte4:
1932        // OLED brightness (=0: Eco, =1 High) (Not writable!)
1933        // Byte5-11:
1934        // Time/Date vault during firmware updates
1935        // Byte12-128
1936        // not used/reserved
1937        // Byte129-256:
1938        // 32 custom Functions (CF 32-63)
1939
1940        // Decode the relevant ones
1941        // CF32: Gradient Factor low
1942        write_ostc_cf(data, 32, max_CF, m_deviceDetails->gfLow);
1943        // CF33: Gradient Factor high
1944        write_ostc_cf(data, 33, max_CF, m_deviceDetails->gfHigh);
1945        // CF56: Bottom gas consumption
1946        write_ostc_cf(data, 56, max_CF, m_deviceDetails->bottomGasConsumption);
1947        // CF57: Ascent gas consumption
1948        write_ostc_cf(data, 57, max_CF, m_deviceDetails->decoGasConsumption);
1949        // CF58: Future time to surface setFutureTTS
1950        write_ostc_cf(data, 58, max_CF, m_deviceDetails->futureTTS);
1951#ifdef DEBUG_OSTC_CF
1952        for (int cf = 32; cf <= 63 && cf <= max_CF; cf++)
1953                printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
1954#endif
1955        rc = hw_ostc_device_eeprom_write(device, 1, data, sizeof(data));
1956        if (rc != DC_STATUS_SUCCESS)
1957                return rc;
1958        EMIT_PROGRESS();
1959
1960        rc = hw_ostc_device_eeprom_read(device, 2, data, sizeof(data));
1961        if (rc != DC_STATUS_SUCCESS)
1962                return rc;
1963        EMIT_PROGRESS();
1964        // Byte1-4:
1965        // not used/reserved (Not writable!)
1966        // Byte5-128:
1967        // not used/reserved
1968        // Byte129-256:
1969        // 32 custom Functions (CF 64-95)
1970
1971        // Decode the relevant ones
1972        // CF60: Graphic velocity
1973        write_ostc_cf(data, 60, max_CF, m_deviceDetails->graphicalSpeedIndicator);
1974        // CF65: Show safety stop
1975        write_ostc_cf(data, 65, max_CF, m_deviceDetails->safetyStop);
1976        // CF67: Alternaitve Gradient Factor low
1977        write_ostc_cf(data, 67, max_CF, m_deviceDetails->aGFLow);
1978        // CF68: Alternative Gradient Factor high
1979        write_ostc_cf(data, 68, max_CF, m_deviceDetails->aGFHigh);
1980        // CF69: Allow Gradient Factor change
1981        write_ostc_cf(data, 69, max_CF, m_deviceDetails->aGFSelectable);
1982        // CF70: Safety Stop Duration [s]
1983        write_ostc_cf(data, 70, max_CF, m_deviceDetails->safetyStopLength);
1984        // CF71: Safety Stop Start Depth [m]
1985        write_ostc_cf(data, 71, max_CF, m_deviceDetails->safetyStopStartDepth);
1986        // CF72: Safety Stop End Depth [m]
1987        write_ostc_cf(data, 72, max_CF, m_deviceDetails->safetyStopEndDepth);
1988        // CF73: Safety Stop Reset Depth [m]
1989        write_ostc_cf(data, 73, max_CF, m_deviceDetails->safetyStopResetDepth);
1990        // CF74: Battery Timeout [min]
1991
1992#ifdef DEBUG_OSTC_CF
1993        for (int cf = 64; cf <= 95 && cf <= max_CF; cf++)
1994                printf("CF %d: %d\n", cf, read_ostc_cf(data, cf));
1995#endif
1996        rc = hw_ostc_device_eeprom_write(device, 2, data, sizeof(data));
1997        if (rc != DC_STATUS_SUCCESS)
1998                return rc;
1999        EMIT_PROGRESS();
2000
2001        //sync date and time
2002        if (m_deviceDetails->syncTime) {
2003                QDateTime timeToSet = QDateTime::currentDateTime();
2004                dc_datetime_t time;
2005                time.year = timeToSet.date().year();
2006                time.month = timeToSet.date().month();
2007                time.day = timeToSet.date().day();
2008                time.hour = timeToSet.time().hour();
2009                time.minute = timeToSet.time().minute();
2010                time.second = timeToSet.time().second();
2011                rc = hw_ostc_device_clock(device, &time);
2012        }
2013        EMIT_PROGRESS();
2014        return rc;
2015}
2016
2017#undef EMIT_PROGRESS
2018
2019DeviceThread::DeviceThread(QObject *parent, device_data_t *data) : QThread(parent), m_data(data)
2020{
2021}
2022
2023void DeviceThread::progressCB(int percent)
2024{
2025        emit progress(percent);
2026}
2027
2028void DeviceThread::event_cb(dc_device_t *device, dc_event_type_t event, const void *data, void *userdata)
2029{
2030        Q_UNUSED(device);
2031
2032        const dc_event_progress_t *progress = (dc_event_progress_t *) data;
2033        DeviceThread *dt = static_cast<DeviceThread*>(userdata);
2034
2035        switch (event) {
2036        case DC_EVENT_PROGRESS:
2037                dt->progressCB(lrint(100.0 * (double)progress->current / (double)progress->maximum));
2038                break;
2039        default:
2040                emit dt->error("Unexpected event recived");
2041                break;
2042        }
2043}
2044
2045ReadSettingsThread::ReadSettingsThread(QObject *parent, device_data_t *data) : DeviceThread(parent, data)
2046{
2047}
2048
2049void ReadSettingsThread::run()
2050{
2051        dc_status_t rc;
2052
2053        DeviceDetails *m_deviceDetails = new DeviceDetails(0);
2054        switch (dc_device_get_type(m_data->device)) {
2055        case DC_FAMILY_SUUNTO_VYPER:
2056                rc = read_suunto_vyper_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2057                if (rc == DC_STATUS_SUCCESS) {
2058                        emit devicedetails(m_deviceDetails);
2059                } else if (rc == DC_STATUS_UNSUPPORTED) {
2060                        emit error(tr("This feature is not yet available for the selected dive computer."));
2061                } else {
2062                        emit error("Failed!");
2063                }
2064                break;
2065#if DC_VERSION_CHECK(0, 5, 0)
2066        case DC_FAMILY_HW_OSTC3:
2067                rc = read_ostc3_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2068                if (rc == DC_STATUS_SUCCESS)
2069                        emit devicedetails(m_deviceDetails);
2070                else
2071                        emit error("Failed!");
2072                break;
2073#endif // divecomputer 0.5.0
2074#ifdef DEBUG_OSTC
2075        case DC_FAMILY_NULL:
2076#endif
2077        case DC_FAMILY_HW_OSTC:
2078                rc = read_ostc_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2079                if (rc == DC_STATUS_SUCCESS)
2080                        emit devicedetails(m_deviceDetails);
2081                else
2082                        emit error("Failed!");
2083                break;
2084        default:
2085                emit error(tr("This feature is not yet available for the selected dive computer."));
2086                break;
2087        }
2088}
2089
2090WriteSettingsThread::WriteSettingsThread(QObject *parent, device_data_t *data) :
2091        DeviceThread(parent, data),
2092        m_deviceDetails(NULL)
2093{
2094}
2095
2096void WriteSettingsThread::setDeviceDetails(DeviceDetails *details)
2097{
2098        m_deviceDetails = details;
2099}
2100
2101void WriteSettingsThread::run()
2102{
2103        dc_status_t rc;
2104
2105        switch (dc_device_get_type(m_data->device)) {
2106        case DC_FAMILY_SUUNTO_VYPER:
2107                rc = write_suunto_vyper_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2108                if (rc == DC_STATUS_UNSUPPORTED) {
2109                        emit error(tr("This feature is not yet available for the selected dive computer."));
2110                } else if (rc != DC_STATUS_SUCCESS) {
2111                        emit error(tr("Failed!"));
2112                }
2113                break;
2114#if DC_VERSION_CHECK(0, 5, 0)
2115        case DC_FAMILY_HW_OSTC3:
2116                // FIXME: Is this the best way?
2117                if (m_deviceDetails->model == "OSTC 4")
2118                        rc = write_ostc4_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2119                else
2120                        rc = write_ostc3_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2121                if (rc != DC_STATUS_SUCCESS)
2122                        emit error(tr("Failed!"));
2123                break;
2124#endif // divecomputer 0.5.0
2125#ifdef DEBUG_OSTC
2126        case DC_FAMILY_NULL:
2127#endif
2128        case DC_FAMILY_HW_OSTC:
2129                rc = write_ostc_settings(m_data->device, m_deviceDetails, DeviceThread::event_cb, this);
2130                if (rc != DC_STATUS_SUCCESS)
2131                        emit error(tr("Failed!"));
2132                break;
2133        default:
2134                emit error(tr("This feature is not yet available for the selected dive computer."));
2135                break;
2136        }
2137}
2138
2139
2140FirmwareUpdateThread::FirmwareUpdateThread(QObject *parent, device_data_t *data, QString fileName) : DeviceThread(parent, data), m_fileName(fileName)
2141{
2142}
2143
2144void FirmwareUpdateThread::run()
2145{
2146        dc_status_t rc;
2147
2148        rc = dc_device_set_events(m_data->device, DC_EVENT_PROGRESS, DeviceThread::event_cb, this);
2149        if (rc != DC_STATUS_SUCCESS) {
2150                emit error("Error registering the event handler.");
2151                return;
2152        }
2153        switch (dc_device_get_type(m_data->device)) {
2154#if DC_VERSION_CHECK(0, 5, 0)
2155        case DC_FAMILY_HW_OSTC3:
2156                rc = hw_ostc3_device_fwupdate(m_data->device, m_fileName.toUtf8().data());
2157                break;
2158        case DC_FAMILY_HW_OSTC:
2159                rc = hw_ostc_device_fwupdate(m_data->device, m_fileName.toUtf8().data());
2160                break;
2161#endif // divecomputer 0.5.0
2162        default:
2163                emit error(tr("This feature is not yet available for the selected dive computer."));
2164                return;
2165        }
2166
2167        if (rc != DC_STATUS_SUCCESS) {
2168                emit error(tr("Firmware update failed!"));
2169        }
2170}
2171
2172
2173ResetSettingsThread::ResetSettingsThread(QObject *parent, device_data_t *data) : DeviceThread(parent, data)
2174{
2175}
2176
2177void ResetSettingsThread::run()
2178{
2179        dc_status_t rc = DC_STATUS_SUCCESS;
2180
2181#if DC_VERSION_CHECK(0, 5, 0)
2182        if (dc_device_get_type(m_data->device) == DC_FAMILY_HW_OSTC3) {
2183                rc = hw_ostc3_device_config_reset(m_data->device);
2184                emit progress(100);
2185        }
2186#endif // divecomputer 0.5.0
2187        if (rc != DC_STATUS_SUCCESS) {
2188                emit error(tr("Reset settings failed!"));
2189        }
2190}
Note: See TracBrowser for help on using the repository browser.