5050// Let the unittest define this using a header override:
5151# include "services/normal/bluetooth/bluetooth_persistent_storage_unittest_impl.h"
5252#else
53- // TODO: perhaps revert this back to v1 for cc2564x if we can figure out how to handle the old format
54- // right now, you have to make sure you've erased all bondings before upgrading else you'll crash
55- // because the v2 code chokes on the v1 format
5653# if BT_CONTROLLER_DA14681 || BT_CONTROLLER_QEMU || BT_CONTROLLER_NRF52 || BT_CONTROLLER_CC2564X
5754# include "services/normal/bluetooth/bluetooth_persistent_storage_v2_impl.h"
5855# else
5956# error "Unknown BT_CONTROLLER_... define?"
6057# endif
6158#endif
6259
63- //! The BtPersistBonding*Data structs can never shrink, only grow
64-
6560//! Stores data about a remote BT classic device
6661typedef struct PACKED {
6762 BTDeviceAddress addr ;
@@ -126,6 +121,26 @@ static PebbleMutex *s_db_mutex = NULL;
126121//! @note prv_lock() must be held when accessing this variable.
127122static PebbleProtocolCapabilities s_cached_system_capabilities ;
128123
124+ // TODO: extend these to be able to load a legacy BtPersistBondingData from
125+ // v1 and migrate it, if we wish to. The old format requires regenerating
126+ // CSRK / LTK from div/ediv directly, which seems not to be an API that's
127+ // readily exposed from NimBLE. For now, we throw away old pairings.
128+
129+ //! Is this val_len any kind of BtPersistBondingData that we support loading?
130+ static bool prv_val_len_is_bonding (size_t val_len ) {
131+ // In theory, it was permissible on old PebbleOS to have a smaller
132+ // BtPersistBondingData v2 that needed to get zero-padded out to a larger
133+ // one, and that was the "versioning"; this check does not check for that.
134+ // In practice, this never happened, so we are OK!
135+ return val_len == sizeof (BtPersistBondingData );
136+ }
137+
138+ //! Load whatever is in this SettingsRecordInfo into a modern BtPersistBondingData structure.
139+ static void prv_load_pairing_data_from_val (SettingsFile * file , SettingsRecordInfo * info , BtPersistBondingData * data ) {
140+ PBL_ASSERTN (info -> val_len == sizeof (BtPersistBondingData ));
141+ info -> get_val (file , (uint8_t * )data , info -> val_len );
142+ }
143+
129144static void prv_lock (void ) {
130145 mutex_lock (s_db_mutex );
131146}
@@ -320,12 +335,12 @@ static bool prv_any_pinned_ble_pairings_itr(SettingsFile *file,
320335 if (info -> key_len != sizeof (BTBondingID )) {
321336 return true;
322337 }
323- if (info -> val_len == 0 ) {
338+ if (! prv_val_len_is_bonding ( info -> val_len ) ) {
324339 return true;
325340 }
326341
327342 BtPersistBondingData data ;
328- info -> get_val (file , & data , sizeof ( data ) );
343+ prv_load_pairing_data_from_val (file , info , & data );
329344 if (data .ble_data .requires_address_pinning ) {
330345 bool * has_pinned_ble_pairings = context ;
331346 * has_pinned_ble_pairings = true;
@@ -518,14 +533,14 @@ typedef struct {
518533static bool prv_get_num_pairings_by_type_itr (SettingsFile * file ,
519534 SettingsRecordInfo * info , void * context ) {
520535 // check entry is valid
521- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
536+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
522537 return true; // continue iterating
523538 }
524539
525540 PairingCountItrData * itr_data = (PairingCountItrData * )context ;
526541
527542 BtPersistBondingData stored_data ;
528- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
543+ prv_load_pairing_data_from_val (file , info , & stored_data );
529544
530545 if (stored_data .type == itr_data -> type ) {
531546 itr_data -> count ++ ;
@@ -577,7 +592,7 @@ static bool prv_is_pairing_info_equal_identity(const BtPersistLEPairingInfo *a,
577592static bool prv_get_key_for_sm_pairing_info_itr (SettingsFile * file ,
578593 SettingsRecordInfo * info , void * context ) {
579594 // check entry is valid
580- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
595+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
581596 return true; // continue iterating
582597 }
583598
@@ -586,7 +601,7 @@ static bool prv_get_key_for_sm_pairing_info_itr(SettingsFile *file,
586601 BTBondingID key ;
587602 BtPersistBondingData stored_data ;
588603 info -> get_key (file , (uint8_t * ) & key , info -> key_len );
589- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
604+ prv_load_pairing_data_from_val (file , info , & stored_data );
590605
591606 if (stored_data .type == BtPersistBondingTypeBLE &&
592607 prv_is_pairing_info_equal_identity (& stored_data .ble_data .pairing_info ,
@@ -752,7 +767,7 @@ typedef struct {
752767static bool prv_find_by_addr_itr (SettingsFile * file ,
753768 SettingsRecordInfo * info , void * context ) {
754769 // check entry is valid
755- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
770+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
756771 return true; // continue iterating
757772 }
758773
@@ -761,7 +776,7 @@ static bool prv_find_by_addr_itr(SettingsFile *file,
761776 BTBondingID key ;
762777 BtPersistBondingData stored_data ;
763778 info -> get_key (file , (uint8_t * ) & key , info -> key_len );
764- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
779+ prv_load_pairing_data_from_val (file , info , & stored_data );
765780
766781 if (stored_data .type == BtPersistBondingTypeBLE &&
767782 bt_device_equal (& itr_data -> device .opaque ,
@@ -889,14 +904,14 @@ bool bt_persistent_storage_get_ble_pinned_address(BTDeviceAddress *address_out)
889904static bool prv_get_first_ancs_bonding_itr (SettingsFile * file ,
890905 SettingsRecordInfo * info , void * context ) {
891906 // check entry is valid
892- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
907+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
893908 return true; // continue iterating
894909 }
895910
896911 BTBondingID * first_ancs_supported_bonding_found = (BTBondingID * ) context ;
897912
898913 BtPersistBondingData stored_data ;
899- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
914+ prv_load_pairing_data_from_val (file , info , & stored_data );
900915
901916
902917 if (stored_data .type == BtPersistBondingTypeBLE && stored_data .ble_data .supports_ancs ) {
@@ -957,7 +972,7 @@ static void prv_public_for_each_ble_cb(BTBondingID key,
957972static bool prv_ble_pairing_internal_for_each_itr (SettingsFile * file ,
958973 SettingsRecordInfo * info , void * context ) {
959974 // check entry is valid
960- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
975+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
961976 return true; // continue iterating
962977 }
963978
@@ -966,7 +981,7 @@ static bool prv_ble_pairing_internal_for_each_itr(SettingsFile *file,
966981 BTBondingID key ;
967982 BtPersistBondingData stored_data ;
968983 info -> get_key (file , (uint8_t * ) & key , info -> key_len );
969- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
984+ prv_load_pairing_data_from_val (file , info , & stored_data );
970985
971986 if (stored_data .type == BtPersistBondingTypeBLE ) {
972987 internal_itr_data -> cb (key , & stored_data , internal_itr_data -> cb_data );
@@ -1037,7 +1052,7 @@ typedef struct {
10371052static bool prv_get_key_for_bt_classic_addr_itr (SettingsFile * file ,
10381053 SettingsRecordInfo * info , void * context ) {
10391054 // check entry is valid
1040- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
1055+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
10411056 return true; // continue iterating
10421057 }
10431058
@@ -1046,7 +1061,7 @@ static bool prv_get_key_for_bt_classic_addr_itr(SettingsFile *file,
10461061 BTBondingID key ;
10471062 BtPersistBondingData stored_data ;
10481063 info -> get_key (file , (uint8_t * ) & key , info -> key_len );
1049- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
1064+ prv_load_pairing_data_from_val (file , info , & stored_data );
10501065
10511066 if (stored_data .type == BtPersistBondingTypeBTClassic &&
10521067 !memcmp (& itr_data -> address , & stored_data .bt_classic_data .addr , sizeof (itr_data -> address ))) {
@@ -1222,7 +1237,7 @@ typedef struct {
12221237static bool bt_persistent_storage_bt_classic_pairing_for_each_itr (SettingsFile * file ,
12231238 SettingsRecordInfo * info , void * context ) {
12241239 // check entry is valid
1225- if (info -> val_len == 0 || info -> key_len != sizeof (BTBondingID )) {
1240+ if (! prv_val_len_is_bonding ( info -> val_len ) || info -> key_len != sizeof (BTBondingID )) {
12261241 return true; // continue iterating
12271242 }
12281243
@@ -1231,7 +1246,7 @@ static bool bt_persistent_storage_bt_classic_pairing_for_each_itr(SettingsFile *
12311246 BTBondingID key ;
12321247 BtPersistBondingData stored_data ;
12331248 info -> get_key (file , (uint8_t * ) & key , info -> key_len );
1234- info -> get_val (file , ( uint8_t * ) & stored_data , MIN (( unsigned ) info -> val_len , sizeof ( stored_data )) );
1249+ prv_load_pairing_data_from_val (file , info , & stored_data );
12351250
12361251 if (stored_data .type == BtPersistBondingTypeBTClassic ) {
12371252 itr_data -> cb (& stored_data .bt_classic_data .addr , & stored_data .bt_classic_data .link_key ,
0 commit comments