@@ -665,6 +665,20 @@ static void ag_notify_call_held_ind(struct bt_hfp_ag *ag, void *user_data)
665
665
}
666
666
}
667
667
668
+ static void release_call (struct bt_hfp_ag_call * call )
669
+ {
670
+ atomic_clear_bit (call -> flags , BT_HFP_AG_CALL_IN_USING );
671
+ k_work_cancel_delayable (& call -> ringing_work );
672
+ k_work_cancel_delayable (& call -> deferred_work );
673
+ /*
674
+ * Because it is uncertain whether `ringing_work` and `deferred_work` have been cancelled,
675
+ * do not clear ringing_work and deferred_work.
676
+ * Use `offsetof()` to get the offset of `ringing_work` to avoid access the fields
677
+ * `ringing_work` and `deferred_work`.
678
+ */
679
+ (void )memset (call , 0 , offsetof(struct bt_hfp_ag_call , ringing_work ));
680
+ }
681
+
668
682
static void free_call (struct bt_hfp_ag_call * call )
669
683
{
670
684
int call_count ;
@@ -673,9 +687,7 @@ static void free_call(struct bt_hfp_ag_call *call)
673
687
674
688
ag = call -> ag ;
675
689
676
- k_work_cancel_delayable (& call -> ringing_work );
677
- k_work_cancel_delayable (& call -> deferred_work );
678
- memset (call , 0 , sizeof (* call ));
690
+ release_call (call );
679
691
680
692
call_count = get_none_released_calls (ag );
681
693
@@ -3195,7 +3207,6 @@ static void hfp_ag_connected(struct bt_rfcomm_dlc *dlc)
3195
3207
static void hfp_ag_disconnected (struct bt_rfcomm_dlc * dlc )
3196
3208
{
3197
3209
struct bt_hfp_ag * ag = CONTAINER_OF (dlc , struct bt_hfp_ag , rfcomm_dlc );
3198
- bt_hfp_call_state_t call_state ;
3199
3210
sys_snode_t * node ;
3200
3211
struct bt_ag_tx * tx ;
3201
3212
struct bt_hfp_ag_call * call ;
@@ -3227,15 +3238,11 @@ static void hfp_ag_disconnected(struct bt_rfcomm_dlc *dlc)
3227
3238
continue ;
3228
3239
}
3229
3240
3230
- hfp_ag_lock (ag );
3231
- call_state = call -> call_state ;
3232
- hfp_ag_unlock (ag );
3233
- if ((call_state == BT_HFP_CALL_ALERTING ) || (call_state == BT_HFP_CALL_ACTIVE ) ||
3234
- (call_state == BT_HFP_CALL_HOLD )) {
3235
- bt_hfp_ag_terminate_cb (ag , call );
3236
- }
3241
+ release_call (call );
3237
3242
}
3238
3243
3244
+ hfp_ag_close_sco (ag );
3245
+
3239
3246
ag -> acl_conn = NULL ;
3240
3247
3241
3248
LOG_DBG ("AG %p" , ag );
@@ -3465,6 +3472,12 @@ static void bt_ag_deferred_work(struct k_work *work)
3465
3472
struct bt_hfp_ag_call * call = CONTAINER_OF (dwork , struct bt_hfp_ag_call , deferred_work );
3466
3473
struct bt_hfp_ag * ag = call -> ag ;
3467
3474
3475
+ LOG_DBG ("" );
3476
+
3477
+ if (!atomic_test_bit (call -> flags , BT_HFP_AG_CALL_IN_USING )) {
3478
+ return ;
3479
+ }
3480
+
3468
3481
(void )hfp_ag_next_step (ag , bt_ag_deferred_work_cb , call );
3469
3482
}
3470
3483
@@ -3508,6 +3521,12 @@ static void bt_ag_ringing_work(struct k_work *work)
3508
3521
struct k_work_delayable * dwork = k_work_delayable_from_work (work );
3509
3522
struct bt_hfp_ag_call * call = CONTAINER_OF (dwork , struct bt_hfp_ag_call , ringing_work );
3510
3523
3524
+ LOG_DBG ("" );
3525
+
3526
+ if (!atomic_test_bit (call -> flags , BT_HFP_AG_CALL_IN_USING )) {
3527
+ return ;
3528
+ }
3529
+
3511
3530
(void )hfp_ag_next_step (call -> ag , bt_ag_ringing_work_cb , call );
3512
3531
}
3513
3532
0 commit comments