@@ -868,6 +868,103 @@ static ssize_t sf_read(struct bt_conn *conn, const struct bt_gatt_attr *attr,
868868#endif /* CONFIG_BT_EATT */
869869#endif /* CONFIG_BT_GATT_CACHING */
870870
871+ static int bt_gatt_store_cf (struct bt_conn * conn )
872+ {
873+ #if defined(CONFIG_BT_GATT_CACHING )
874+ struct gatt_cf_cfg * cfg ;
875+ char key [BT_SETTINGS_KEY_MAX ];
876+ char * str ;
877+ size_t len ;
878+ int err ;
879+
880+ cfg = find_cf_cfg (conn );
881+ if (!cfg ) {
882+ /* No cfg found, just clear it */
883+ BT_DBG ("No config for CF" );
884+ str = NULL ;
885+ len = 0 ;
886+ } else {
887+ str = (char * )cfg -> data ;
888+ len = sizeof (cfg -> data );
889+
890+ if (conn -> id ) {
891+ char id_str [4 ];
892+
893+ u8_to_dec (id_str , sizeof (id_str ), conn -> id );
894+ bt_settings_encode_key (key , sizeof (key ), "cf" ,
895+ & conn -> le .dst , id_str );
896+ }
897+ }
898+
899+ if (!cfg || !conn -> id ) {
900+ bt_settings_encode_key (key , sizeof (key ), "cf" ,
901+ & conn -> le .dst , NULL );
902+ }
903+
904+ err = settings_save_one (key , str , len );
905+ if (err ) {
906+ BT_ERR ("Failed to store Client Features (err %d)" , err );
907+ return err ;
908+ }
909+
910+ BT_DBG ("Stored CF for %s (%s)" , bt_addr_le_str (& conn -> le .dst ), log_strdup (key ));
911+ #endif /* CONFIG_BT_GATT_CACHING */
912+ return 0 ;
913+
914+ }
915+
916+ #if defined(CONFIG_BT_SETTINGS ) && defined(CONFIG_BT_SMP ) && defined(CONFIG_BT_GATT_CLIENT )
917+ /** Struct used to store both the id and the random address of a device when replacing
918+ * random addresses in the ccc attribute's cfg array with the device's id address after
919+ * pairing complete.
920+ */
921+ struct addr_match {
922+ const bt_addr_le_t * private_addr ;
923+ const bt_addr_le_t * id_addr ;
924+ };
925+
926+ static uint8_t convert_to_id_on_match (const struct bt_gatt_attr * attr ,
927+ uint16_t handle , void * user_data )
928+ {
929+ struct _bt_gatt_ccc * ccc ;
930+ struct addr_match * match = user_data ;
931+
932+ /* Check if attribute is a CCC */
933+ if (attr -> write != bt_gatt_attr_write_ccc ) {
934+ return BT_GATT_ITER_CONTINUE ;
935+ }
936+
937+ ccc = attr -> user_data ;
938+
939+ /* Copy the device's id address to the config's address if the config's address is the
940+ * same as the device's private address
941+ */
942+ for (size_t i = 0 ; i < ARRAY_SIZE (ccc -> cfg ); i ++ ) {
943+ if (bt_addr_le_cmp (& ccc -> cfg [i ].peer , match -> private_addr ) == 0 ) {
944+ bt_addr_le_copy (& ccc -> cfg [i ].peer , match -> id_addr );
945+ }
946+ }
947+
948+ return BT_GATT_ITER_CONTINUE ;
949+ }
950+
951+ static void bt_gatt_identity_resolved (struct bt_conn * conn , const bt_addr_le_t * private_addr ,
952+ const bt_addr_le_t * id_addr )
953+ {
954+ /* Update the ccc cfg addresses */
955+ struct addr_match user_data = {
956+ .private_addr = private_addr ,
957+ .id_addr = id_addr
958+ };
959+
960+ bt_gatt_foreach_attr (0x0001 , 0xffff , convert_to_id_on_match , & user_data );
961+
962+ /* Store the ccc and cf data */
963+ bt_gatt_store_ccc (conn -> id , & (conn -> le .dst ));
964+ bt_gatt_store_cf (conn );
965+ }
966+ #endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP && CONFIG_BT_GATT_CLIENT */
967+
871968BT_GATT_SERVICE_DEFINE (_1_gatt_svc ,
872969 BT_GATT_PRIMARY_SERVICE (BT_UUID_GATT ),
873970#if defined(CONFIG_BT_GATT_SERVICE_CHANGED )
@@ -4991,6 +5088,18 @@ void bt_gatt_connected(struct bt_conn *conn)
49915088
49925089#if defined(CONFIG_BT_GATT_CLIENT )
49935090 add_subscriptions (conn );
5091+
5092+ #if defined(CONFIG_BT_SETTINGS ) && defined(CONFIG_BT_SMP )
5093+ static struct bt_conn_cb gatt_conn_cb = {
5094+ .identity_resolved = bt_gatt_identity_resolved ,
5095+ };
5096+
5097+ /* Register the gatt module for connection callbacks so it can be
5098+ * notified when pairing has completed. This is used to enable CCC and
5099+ * CF storage on pairing complete.
5100+ */
5101+ bt_conn_cb_register (& gatt_conn_cb );
5102+ #endif /* CONFIG_BT_SETTINGS && CONFIG_BT_SMP */
49945103#endif /* CONFIG_BT_GATT_CLIENT */
49955104}
49965105
@@ -5061,51 +5170,6 @@ bool bt_gatt_change_aware(struct bt_conn *conn, bool req)
50615170#endif
50625171}
50635172
5064- static int bt_gatt_store_cf (struct bt_conn * conn )
5065- {
5066- #if defined(CONFIG_BT_GATT_CACHING )
5067- struct gatt_cf_cfg * cfg ;
5068- char key [BT_SETTINGS_KEY_MAX ];
5069- char * str ;
5070- size_t len ;
5071- int err ;
5072-
5073- cfg = find_cf_cfg (conn );
5074- if (!cfg ) {
5075- /* No cfg found, just clear it */
5076- BT_DBG ("No config for CF" );
5077- str = NULL ;
5078- len = 0 ;
5079- } else {
5080- str = (char * )cfg -> data ;
5081- len = sizeof (cfg -> data );
5082-
5083- if (conn -> id ) {
5084- char id_str [4 ];
5085-
5086- u8_to_dec (id_str , sizeof (id_str ), conn -> id );
5087- bt_settings_encode_key (key , sizeof (key ), "cf" ,
5088- & conn -> le .dst , id_str );
5089- }
5090- }
5091-
5092- if (!cfg || !conn -> id ) {
5093- bt_settings_encode_key (key , sizeof (key ), "cf" ,
5094- & conn -> le .dst , NULL );
5095- }
5096-
5097- err = settings_save_one (key , str , len );
5098- if (err ) {
5099- BT_ERR ("Failed to store Client Features (err %d)" , err );
5100- return err ;
5101- }
5102-
5103- BT_DBG ("Stored CF for %s (%s)" , bt_addr_le_str (& conn -> le .dst ), log_strdup (key ));
5104- #endif /* CONFIG_BT_GATT_CACHING */
5105- return 0 ;
5106-
5107- }
5108-
51095173static struct gatt_cf_cfg * find_cf_cfg_by_addr (uint8_t id ,
51105174 const bt_addr_le_t * addr )
51115175{
0 commit comments