@@ -426,6 +426,13 @@ static ssize_t db_hash_read(struct bt_conn *conn,
426
426
sizeof (db_hash ));
427
427
}
428
428
429
+ static void clear_cf_cfg (struct gatt_cf_cfg * cfg )
430
+ {
431
+ bt_addr_le_copy (& cfg -> peer , BT_ADDR_LE_ANY );
432
+ memset (cfg -> data , 0 , sizeof (cfg -> data ));
433
+ atomic_set (cfg -> flags , 0 );
434
+ }
435
+
429
436
static void remove_cf_cfg (struct bt_conn * conn )
430
437
{
431
438
struct gatt_cf_cfg * cfg ;
@@ -442,8 +449,7 @@ static void remove_cf_cfg(struct bt_conn *conn)
442
449
* default value at each connection.
443
450
*/
444
451
if (!bt_addr_le_is_bonded (conn -> id , & conn -> le .dst )) {
445
- bt_addr_le_copy (& cfg -> peer , BT_ADDR_LE_ANY );
446
- memset (cfg -> data , 0 , sizeof (cfg -> data ));
452
+ clear_cf_cfg (cfg );
447
453
} else {
448
454
/* Update address in case it has changed */
449
455
bt_addr_le_copy (& cfg -> peer , & conn -> le .dst );
@@ -2815,6 +2821,50 @@ bool bt_gatt_change_aware(struct bt_conn *conn, bool req)
2815
2821
#endif
2816
2822
}
2817
2823
2824
+ static int bt_gatt_store_cf (struct bt_conn * conn )
2825
+ {
2826
+ #if defined(CONFIG_BT_GATT_CACHING )
2827
+ struct gatt_cf_cfg * cfg ;
2828
+ char key [BT_SETTINGS_KEY_MAX ];
2829
+ char * str ;
2830
+ size_t len ;
2831
+ int err ;
2832
+
2833
+ cfg = find_cf_cfg (conn );
2834
+ if (!cfg ) {
2835
+ /* No cfg found just cleare it */
2836
+ str = NULL ;
2837
+ len = 0 ;
2838
+ goto save ;
2839
+ }
2840
+
2841
+ if (conn -> id ) {
2842
+ char id_str [4 ];
2843
+
2844
+ snprintk (id_str , sizeof (id_str ), "%u" , conn -> id );
2845
+ bt_settings_encode_key (key , sizeof (key ), "cf" ,
2846
+ & conn -> le .dst , id_str );
2847
+ } else {
2848
+ bt_settings_encode_key (key , sizeof (key ), "cf" ,
2849
+ & conn -> le .dst , NULL );
2850
+ }
2851
+
2852
+ str = (char * )cfg -> data ;
2853
+ len = sizeof (cfg -> data );
2854
+
2855
+ save :
2856
+ err = settings_save_one (key , str , len );
2857
+ if (err ) {
2858
+ BT_ERR ("Failed to store Client Features (err %d)" , err );
2859
+ return err ;
2860
+ }
2861
+
2862
+ BT_DBG ("Stored CF for %s (%s)" , bt_addr_le_str (& conn -> le .dst ), key );
2863
+ #endif /* CONFIG_BT_GATT_CACHING */
2864
+ return 0 ;
2865
+
2866
+ }
2867
+
2818
2868
void bt_gatt_disconnected (struct bt_conn * conn )
2819
2869
{
2820
2870
BT_DBG ("conn %p" , conn );
@@ -2831,6 +2881,7 @@ void bt_gatt_disconnected(struct bt_conn *conn)
2831
2881
if (IS_ENABLED (CONFIG_BT_SETTINGS ) &&
2832
2882
bt_addr_le_is_bonded (conn -> id , & conn -> le .dst )) {
2833
2883
bt_gatt_store_ccc (conn -> id , & conn -> le .dst );
2884
+ bt_gatt_store_cf (conn );
2834
2885
}
2835
2886
2836
2887
#if defined(CONFIG_BT_GATT_CLIENT )
@@ -3121,4 +3172,66 @@ static int ccc_set(int argc, char **argv, void *val_ctx)
3121
3172
}
3122
3173
3123
3174
BT_SETTINGS_DEFINE (ccc , ccc_set , NULL , NULL );
3175
+
3176
+ #if defined(CONFIG_BT_GATT_CACHING )
3177
+ static struct gatt_cf_cfg * find_cf_cfg_by_addr (const bt_addr_le_t * addr )
3178
+ {
3179
+ int i ;
3180
+
3181
+ for (i = 0 ; i < ARRAY_SIZE (cf_cfg ); i ++ ) {
3182
+ if (!bt_addr_le_cmp (addr , & cf_cfg [i ].peer )) {
3183
+ return & cf_cfg [i ];
3184
+ }
3185
+ }
3186
+
3187
+ return NULL ;
3188
+ }
3189
+
3190
+ static int cf_set (int argc , char * * argv , void * val_ctx )
3191
+ {
3192
+ struct gatt_cf_cfg * cfg ;
3193
+ bt_addr_le_t addr ;
3194
+ int len , err ;
3195
+
3196
+ if (argc < 1 ) {
3197
+ BT_ERR ("Insufficient number of arguments" );
3198
+ return - EINVAL ;
3199
+ }
3200
+
3201
+ err = bt_settings_decode_key (argv [0 ], & addr );
3202
+ if (err ) {
3203
+ BT_ERR ("Unable to decode address %s" , argv [0 ]);
3204
+ return - EINVAL ;
3205
+ }
3206
+
3207
+ cfg = find_cf_cfg_by_addr (& addr );
3208
+ if (!cfg ) {
3209
+ cfg = find_cf_cfg (NULL );
3210
+ if (!cfg ) {
3211
+ BT_ERR ("Unable to restore CF: no cfg left" );
3212
+ return 0 ;
3213
+ }
3214
+ }
3215
+
3216
+ if (settings_val_get_len_cb (val_ctx )) {
3217
+ len = settings_val_read_cb (val_ctx , cfg -> data ,
3218
+ sizeof (cfg -> data ));
3219
+ if (len < 0 ) {
3220
+ BT_ERR ("Failed to decode value (err %d)" , len );
3221
+ return len ;
3222
+ }
3223
+
3224
+ BT_DBG ("Read CF: len %d" , len );
3225
+ } else {
3226
+ bt_addr_le_copy (& cfg -> peer , BT_ADDR_LE_ANY );
3227
+ memset (cfg -> data , 0 , sizeof (cfg -> data ));
3228
+ }
3229
+
3230
+ BT_DBG ("Restored CF for %s" , bt_addr_le_str (& addr ));
3231
+
3232
+ return 0 ;
3233
+ }
3234
+
3235
+ BT_SETTINGS_DEFINE (cf , cf_set , NULL , NULL );
3236
+ #endif /*CONFIG_BT_GATT_CACHING */
3124
3237
#endif /* CONFIG_BT_SETTINGS */
0 commit comments