8383#define INVALID 0xFFFFFFFF
8484#define UNKNOWN 0x00
8585#define OSTC3 0x0A
86- #define OSTC4 0x3B
86+ #define OSTC4_5_PREFIX 0x3B
8787#define SPORT 0x12
8888#define CR 0x05
89+ #define MODEL_OSTC4 0x43
90+ #define MODEL_OSTC5 0x44
8991
9092#define NODELAY 0
9193#define TIMEOUT 400
103105#define HDR_FULL_POINTERS 2 // 6 bytes
104106#define HDR_FULL_FIRMWARE 48 // 2 bytes
105107
108+
106109typedef enum hw_ostc3_state_t {
107110 OPEN ,
108111 DOWNLOAD ,
@@ -201,6 +204,12 @@ hw_ostc3_strncpy (unsigned char *data, unsigned int size, const char *text)
201204 return 0 ;
202205}
203206
207+ static bool is_ostc4_family (unsigned int hardware )
208+ {
209+ // Check if the hardware is an OSTC 4 or 5.
210+ return (hardware >> 8 ) == OSTC4_5_PREFIX ;
211+ }
212+
204213static dc_status_t
205214hw_ostc3_read (hw_ostc3_device_t * device , dc_event_progress_t * progress , unsigned char data [], size_t size )
206215{
@@ -240,7 +249,7 @@ hw_ostc3_write (hw_ostc3_device_t *device, dc_event_progress_t *progress, const
240249 size_t nbytes = 0 ;
241250 while (nbytes < size ) {
242251 // Set the maximum packet size.
243- size_t length = (device -> hardware == OSTC4 ) ? 64 : 1024 ;
252+ size_t length = is_ostc4_family (device -> hardware ) ? 64 : 1024 ;
244253
245254 // Limit the packet size to the total size.
246255 if (nbytes + length > size )
@@ -488,17 +497,13 @@ hw_ostc3_device_id (hw_ostc3_device_t *device, unsigned char data[], unsigned in
488497 if (size != SZ_HARDWARE && size != SZ_HARDWARE2 )
489498 return DC_STATUS_INVALIDARGS ;
490499
491- // We need to try the HARDWARE command first, as HARDWARE2 results
492- // in a bluetooth disconnect when the OSTC4 is in bootloader mode.
493500 unsigned char hardware [SZ_HARDWARE2 ] = {0 };
494- status = hw_ostc3_transfer (device , NULL , HARDWARE , NULL , 0 , hardware + 1 , SZ_HARDWARE , NULL , NODELAY );
495- if (size == SZ_HARDWARE2 && array_uint16_be (hardware ) != OSTC4 ) {
496- // HARDWARE2 returns additional information
497- unsigned char hardware2 [SZ_HARDWARE2 ] = {0 };
498- status = hw_ostc3_transfer (device , NULL , HARDWARE2 , NULL , 0 , hardware2 , SZ_HARDWARE2 , NULL , NODELAY );
499- if (status == DC_STATUS_SUCCESS ) {
500- memcpy (hardware , hardware2 , SZ_HARDWARE2 );
501- }
501+ if (size == SZ_HARDWARE2 ) {
502+ status = hw_ostc3_transfer (device , NULL , HARDWARE2 , NULL , 0 , hardware , SZ_HARDWARE2 , NULL , NODELAY );
503+ }
504+
505+ if (size == SZ_HARDWARE || status == DC_STATUS_UNSUPPORTED ) {
506+ status = hw_ostc3_transfer (device , NULL , HARDWARE , NULL , 0 , hardware + 1 , SZ_HARDWARE , NULL , NODELAY );
502507 }
503508
504509 if (status != DC_STATUS_SUCCESS )
@@ -605,14 +610,34 @@ hw_ostc3_device_init (hw_ostc3_device_t *device, hw_ostc3_state_t state)
605610 return DC_STATUS_SUCCESS ;
606611
607612 // Read the hardware descriptor.
608- unsigned char hardware [SZ_HARDWARE2 ] = {0 , UNKNOWN };
609- rc = hw_ostc3_device_id (device , hardware , sizeof (hardware ));
610- if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED ) {
611- ERROR (abstract -> context , "Failed to read the hardware descriptor." );
612- return rc ;
613+ unsigned int hardware_prefix ;
614+ if (device -> state == SERVICE ) {
615+ // We need to try the HARDWARE command first, as HARDWARE2 results
616+ // in a bluetooth disconnect when the OSTC 4/5 is in bootloader mode.
617+ unsigned char hardware [SZ_HARDWARE ] = {UNKNOWN };
618+ rc = hw_ostc3_device_id (device , hardware , sizeof (hardware ));
619+ if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED ) {
620+ ERROR (abstract -> context , "Failed to read the hardware descriptor." );
621+ return rc ;
622+ }
623+
624+ HEXDUMP (abstract -> context , DC_LOGLEVEL_DEBUG , "Hardware" , hardware , sizeof (hardware ));
625+
626+ hardware_prefix = hardware [0 ];
613627 }
614628
615- HEXDUMP (abstract -> context , DC_LOGLEVEL_DEBUG , "Hardware" , hardware , sizeof (hardware ));
629+ unsigned char hardware2 [SZ_HARDWARE2 ] = {0 , UNKNOWN , 0 , 0 , MODEL_OSTC4 };
630+ if (device -> state != SERVICE || hardware_prefix != OSTC4_5_PREFIX ) {
631+ rc = hw_ostc3_device_id (device , hardware2 , sizeof (hardware2 ));
632+ if (rc != DC_STATUS_SUCCESS && rc != DC_STATUS_UNSUPPORTED ) {
633+ ERROR (abstract -> context , "Failed to read the hardware2 descriptor." );
634+ return rc ;
635+ }
636+
637+ HEXDUMP (abstract -> context , DC_LOGLEVEL_DEBUG , "Hardware2" , hardware2 , sizeof (hardware2 ));
638+
639+ hardware_prefix = array_uint16_be (hardware2 + 0 );
640+ }
616641
617642 // Read the version information.
618643 unsigned char version [SZ_VERSION ] = {0 };
@@ -625,17 +650,16 @@ hw_ostc3_device_init (hw_ostc3_device_t *device, hw_ostc3_state_t state)
625650 HEXDUMP (abstract -> context , DC_LOGLEVEL_DEBUG , "Version" , version , sizeof (version ));
626651
627652 // Cache the descriptor.
628- device -> hardware = array_uint16_be (hardware + 0 );
629- if (device -> hardware != OSTC4 ) {
630- device -> feature = array_uint16_be (hardware + 2 );
631- device -> model = hardware [4 ];
632- }
633- device -> serial = array_uint16_le (version + 0 );
634- if (device -> hardware == OSTC4 ) {
635- device -> firmware = array_uint16_le (version + 2 );
636- } else {
653+ if (hardware_prefix != OSTC4_5_PREFIX ) {
654+ device -> hardware = hardware_prefix ;
655+ device -> feature = array_uint16_be (hardware2 + 2 );
637656 device -> firmware = array_uint16_be (version + 2 );
657+ } else {
658+ device -> hardware = (hardware_prefix << 8 ) | hardware2 [4 ];
659+ device -> firmware = array_uint16_le (version + 2 );
638660 }
661+ device -> model = hardware2 [4 ];
662+ device -> serial = array_uint16_le (version + 0 );
639663
640664 return DC_STATUS_SUCCESS ;
641665}
@@ -811,7 +835,7 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
811835
812836 // Get the internal dive number.
813837 unsigned int current = array_uint16_le (header + offset + logbook -> number );
814- if (current > maximum || device -> hardware == OSTC4 ) {
838+ if (current > maximum || is_ostc4_family ( device -> hardware ) ) {
815839 maximum = current ;
816840 latest = i ;
817841 }
@@ -913,7 +937,7 @@ hw_ostc3_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, voi
913937 }
914938
915939 // Detect invalid profile data.
916- unsigned int delta = device -> hardware == OSTC4 ? 3 : 0 ;
940+ unsigned int delta = is_ostc4_family ( device -> hardware ) ? 3 : 0 ;
917941 if (length < RB_LOGBOOK_SIZE_FULL + 2 ||
918942 profile [length - 2 ] != 0xFD || profile [length - 1 ] != 0xFD ) {
919943 // A valid profile should have at least a correct 2 byte
@@ -1031,7 +1055,7 @@ hw_ostc3_device_config_read (dc_device_t *abstract, unsigned int config, unsigne
10311055 if (rc != DC_STATUS_SUCCESS )
10321056 return rc ;
10331057
1034- if (device -> hardware == OSTC4 ? size != SZ_CONFIG : size > SZ_CONFIG ) {
1058+ if (is_ostc4_family ( device -> hardware ) ? size != SZ_CONFIG : size > SZ_CONFIG ) {
10351059 ERROR (abstract -> context , "Invalid parameter specified." );
10361060 return DC_STATUS_INVALIDARGS ;
10371061 }
@@ -1057,7 +1081,7 @@ hw_ostc3_device_config_write (dc_device_t *abstract, unsigned int config, const
10571081 if (rc != DC_STATUS_SUCCESS )
10581082 return rc ;
10591083
1060- if (device -> hardware == OSTC4 ? size != SZ_CONFIG : size > SZ_CONFIG ) {
1084+ if (is_ostc4_family ( device -> hardware ) ? size != SZ_CONFIG : size > SZ_CONFIG ) {
10611085 ERROR (abstract -> context , "Invalid parameter specified." );
10621086 return DC_STATUS_INVALIDARGS ;
10631087 }
@@ -1624,7 +1648,7 @@ hw_ostc3_device_fwupdate (dc_device_t *abstract, const char *filename, bool forc
16241648 return status ;
16251649 }
16261650
1627- if (device -> hardware == OSTC4 ) {
1651+ if (is_ostc4_family ( device -> hardware ) ) {
16281652 return hw_ostc3_device_fwupdate4 (abstract , filename , forceUpdate );
16291653 } else {
16301654 if (forceUpdate ) {
@@ -1653,7 +1677,7 @@ hw_ostc3_device_read (dc_device_t *abstract, unsigned int address, unsigned char
16531677 return status ;
16541678 }
16551679
1656- if (device -> hardware == OSTC4 ) {
1680+ if (is_ostc4_family ( device -> hardware ) ) {
16571681 return DC_STATUS_UNSUPPORTED ;
16581682 }
16591683
@@ -1690,7 +1714,7 @@ hw_ostc3_device_write (dc_device_t *abstract, unsigned int address, const unsign
16901714 return status ;
16911715 }
16921716
1693- if (device -> hardware == OSTC4 ) {
1717+ if (is_ostc4_family ( device -> hardware ) ) {
16941718 return DC_STATUS_UNSUPPORTED ;
16951719 }
16961720
@@ -1732,7 +1756,7 @@ hw_ostc3_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
17321756 return rc ;
17331757 }
17341758
1735- if (device -> hardware == OSTC4 ) {
1759+ if (is_ostc4_family ( device -> hardware ) ) {
17361760 return DC_STATUS_UNSUPPORTED ;
17371761 }
17381762
0 commit comments