@@ -1016,77 +1016,28 @@ static int bt_hfp_ag_bac_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1016
1016
return 0 ;
1017
1017
}
1018
1018
1019
- static void bt_hfp_ag_get_ongoing_calls (struct bt_hfp_ag * ag )
1019
+ static int bt_hfp_ag_get_ongoing_calls (struct bt_hfp_ag * ag )
1020
1020
{
1021
- struct bt_hfp_ag_ongoing_call * call ;
1022
1021
int err ;
1023
- bool valid ;
1024
- size_t len ;
1025
1022
1026
1023
ag -> ongoing_call_count = 0 ;
1027
1024
1028
1025
if ((bt_ag == NULL ) || (bt_ag -> get_ongoing_call == NULL )) {
1029
1026
LOG_DBG ("No ongoing call retrieval method available" );
1030
- return ;
1027
+ return - EINVAL ;
1031
1028
}
1032
1029
1033
- do {
1034
- call = & ag -> ongoing_calls [ag -> ongoing_call_count ];
1035
- memset (call , 0 , sizeof (* call ));
1036
-
1037
- valid = true;
1038
-
1039
- err = bt_ag -> get_ongoing_call (ag , call );
1040
- if (err != 0 ) {
1041
- LOG_DBG ("No ongoing call retrieved" );
1042
- break ;
1043
- }
1044
-
1045
- len = strlen (call -> number );
1046
- if ((len == 0 ) || (len >= ARRAY_SIZE (call -> number ))) {
1047
- LOG_WRN ("Invalid call number" );
1048
- break ;
1049
- }
1050
-
1051
- switch (call -> status ) {
1052
- case BT_HFP_AG_CALL_STATUS_DIALING :
1053
- case BT_HFP_AG_CALL_STATUS_ALERTING :
1054
- if (call -> dir == BT_HFP_AG_CALL_DIR_INCOMING ) {
1055
- LOG_ERR ("Dialing call cannot be incoming" );
1056
- valid = false;
1057
- }
1058
- break ;
1059
- case BT_HFP_AG_CALL_STATUS_INCOMING :
1060
- case BT_HFP_AG_CALL_STATUS_WAITING :
1061
- case BT_HFP_AG_CALL_STATUS_INCOMING_HELD :
1062
- if (call -> dir == BT_HFP_AG_CALL_DIR_OUTGOING ) {
1063
- LOG_ERR ("Incoming call cannot be outgoing" );
1064
- valid = false;
1065
- }
1066
- break ;
1067
- default :
1068
- break ;
1069
- }
1070
-
1071
- if (!valid ) {
1072
- continue ;
1073
- }
1074
-
1075
- ag -> ongoing_call_count ++ ;
1076
- } while (ag -> ongoing_call_count < ARRAY_SIZE (ag -> ongoing_calls ));
1030
+ if (ag -> state == BT_HFP_CONNECTED ) {
1031
+ LOG_ERR ("Only works during SLC establishment phase" );
1032
+ return - EINVAL ;
1033
+ }
1077
1034
1078
- if (ag -> ongoing_call_count > 1 ) {
1079
- switch (ag -> ongoing_calls [0 ].status ) {
1080
- case BT_HFP_AG_CALL_STATUS_ACTIVE :
1081
- case BT_HFP_AG_CALL_STATUS_HELD :
1082
- case BT_HFP_AG_CALL_STATUS_INCOMING_HELD :
1083
- break ;
1084
- default :
1085
- LOG_ERR ("Unexpected call status for multiple calls" );
1086
- ag -> ongoing_call_count = 1 ;
1087
- break ;
1088
- }
1035
+ err = bt_ag -> get_ongoing_call (ag );
1036
+ if (err != 0 ) {
1037
+ LOG_DBG ("No ongoing call retrieved" );
1089
1038
}
1039
+
1040
+ return err ;
1090
1041
}
1091
1042
1092
1043
static int bt_hfp_ag_notify_cind_value (struct bt_hfp_ag * ag )
@@ -1195,10 +1146,16 @@ static int bt_hfp_ag_cind_handler(struct bt_hfp_ag *ag, struct net_buf *buf)
1195
1146
ag_ind [BT_HFP_AG_ROAM_IND ].max , ag_ind [BT_HFP_AG_BATTERY_IND ].name ,
1196
1147
ag_ind [BT_HFP_AG_BATTERY_IND ].min , ag_ind [BT_HFP_AG_BATTERY_IND ].connector ,
1197
1148
ag_ind [BT_HFP_AG_BATTERY_IND ].max );
1198
-
1199
- bt_hfp_ag_get_ongoing_calls (ag );
1200
1149
} else {
1201
- err = bt_hfp_ag_notify_cind_value (ag );
1150
+ err = bt_hfp_ag_get_ongoing_calls (ag );
1151
+ if (err != 0 ) {
1152
+ err = bt_hfp_ag_notify_cind_value (ag );
1153
+ } else {
1154
+ err = - EINPROGRESS ;
1155
+ atomic_set_bit (ag -> flags , BT_HGP_AG_ONGOING_CALLS );
1156
+ k_work_reschedule (& ag -> ongoing_call_work ,
1157
+ K_MSEC (CONFIG_BT_HFP_AG_GET_ONGOING_CALL_TIMEOUT ));
1158
+ }
1202
1159
}
1203
1160
1204
1161
return err ;
@@ -3534,6 +3491,11 @@ static void hfp_ag_recv(struct bt_rfcomm_dlc *dlc, struct net_buf *buf)
3534
3491
}
3535
3492
}
3536
3493
3494
+ if (err == - EINPROGRESS ) {
3495
+ LOG_DBG ("OK code will be replied later" );
3496
+ return ;
3497
+ }
3498
+
3537
3499
if ((err != 0 ) && atomic_test_bit (ag -> flags , BT_HFP_AG_CMEE_ENABLE )) {
3538
3500
cme_err = bt_hfp_ag_get_cme_err (err );
3539
3501
err = hfp_ag_send_data (ag , NULL , NULL , "\r\n+CME ERROR:%d\r\n" , (uint32_t )cme_err );
@@ -3784,6 +3746,29 @@ static void bt_ag_ringing_work(struct k_work *work)
3784
3746
(void )hfp_ag_next_step (call -> ag , bt_ag_ringing_work_cb , call );
3785
3747
}
3786
3748
3749
+ static void bt_ag_send_ok_code (struct bt_hfp_ag * ag )
3750
+ {
3751
+ if (hfp_ag_send_data (ag , NULL , NULL , "\r\nOK\r\n" ) != 0 ) {
3752
+ LOG_ERR ("Failed to send OK code" );
3753
+ }
3754
+ }
3755
+
3756
+ static void bt_ag_ongoing_call_work (struct k_work * work )
3757
+ {
3758
+ struct k_work_delayable * dwork = k_work_delayable_from_work (work );
3759
+ struct bt_hfp_ag * ag = CONTAINER_OF (dwork , struct bt_hfp_ag , ongoing_call_work );
3760
+
3761
+ LOG_DBG ("" );
3762
+
3763
+ if (!atomic_test_and_clear_bit (ag -> flags , BT_HGP_AG_ONGOING_CALLS )) {
3764
+ return ;
3765
+ }
3766
+
3767
+ ag -> ongoing_call_count = 0 ;
3768
+ bt_hfp_ag_notify_cind_value (ag );
3769
+ bt_ag_send_ok_code (ag );
3770
+ }
3771
+
3787
3772
static K_KERNEL_STACK_MEMBER (ag_thread_stack , CONFIG_BT_HFP_AG_THREAD_STACK_SIZE ) ;
3788
3773
3789
3774
static struct bt_hfp_ag * hfp_ag_create (struct bt_conn * conn )
@@ -3883,6 +3868,8 @@ static struct bt_hfp_ag *hfp_ag_create(struct bt_conn *conn)
3883
3868
3884
3869
/* Init delay work */
3885
3870
k_work_init_delayable (& ag -> tx_work , bt_ag_tx_work );
3871
+ /* Init delay work */
3872
+ k_work_init_delayable (& ag -> ongoing_call_work , bt_ag_ongoing_call_work );
3886
3873
3887
3874
return ag ;
3888
3875
}
@@ -5208,3 +5195,98 @@ int bt_hfp_ag_hf_indicator(struct bt_hfp_ag *ag, enum hfp_ag_hf_indicators indic
5208
5195
return - ENOTSUP ;
5209
5196
#endif /* CONFIG_BT_HFP_HF_HF_INDICATORS */
5210
5197
}
5198
+
5199
+ int bt_hfp_ag_ongoing_calls (struct bt_hfp_ag * ag , struct bt_hfp_ag_ongoing_call * calls ,
5200
+ size_t count )
5201
+ {
5202
+ struct bt_hfp_ag_ongoing_call * call ;
5203
+ bool valid ;
5204
+ size_t len ;
5205
+ int err = - EINVAL ;
5206
+
5207
+ LOG_DBG ("" );
5208
+
5209
+ if (ag == NULL ) {
5210
+ LOG_ERR ("Invalid AG object" );
5211
+ return - EINVAL ;
5212
+ }
5213
+
5214
+ if (count > ARRAY_SIZE (ag -> ongoing_calls )) {
5215
+ LOG_ERR ("Out of buffer (%u > %u)" , count , ARRAY_SIZE (ag -> ongoing_calls ));
5216
+ return - ENOMEM ;
5217
+ }
5218
+
5219
+ if (!atomic_test_and_clear_bit (ag -> flags , BT_HGP_AG_ONGOING_CALLS )) {
5220
+ LOG_ERR ("Cannot set ongoing calls" );
5221
+ return - ESRCH ;
5222
+ }
5223
+
5224
+ for (ag -> ongoing_call_count = 0 ; ag -> ongoing_call_count < count ; ag -> ongoing_call_count ++ ) {
5225
+ call = & calls [ag -> ongoing_call_count ];
5226
+ valid = true;
5227
+
5228
+ len = strlen (call -> number );
5229
+ if ((len == 0 ) || (len >= ARRAY_SIZE (call -> number ))) {
5230
+ LOG_WRN ("Invalid call number" );
5231
+ /* Clear all calls */
5232
+ ag -> ongoing_call_count = 0 ;
5233
+ goto failed ;
5234
+ }
5235
+
5236
+ switch (call -> status ) {
5237
+ case BT_HFP_AG_CALL_STATUS_DIALING :
5238
+ case BT_HFP_AG_CALL_STATUS_ALERTING :
5239
+ if (call -> dir == BT_HFP_AG_CALL_DIR_INCOMING ) {
5240
+ LOG_ERR ("Dialing call cannot be incoming" );
5241
+ valid = false;
5242
+ }
5243
+ break ;
5244
+ case BT_HFP_AG_CALL_STATUS_INCOMING :
5245
+ case BT_HFP_AG_CALL_STATUS_WAITING :
5246
+ case BT_HFP_AG_CALL_STATUS_INCOMING_HELD :
5247
+ if (call -> dir == BT_HFP_AG_CALL_DIR_OUTGOING ) {
5248
+ LOG_ERR ("Incoming call cannot be outgoing" );
5249
+ valid = false;
5250
+ }
5251
+ break ;
5252
+ case BT_HFP_AG_CALL_STATUS_ACTIVE :
5253
+ case BT_HFP_AG_CALL_STATUS_HELD :
5254
+ break ;
5255
+ default :
5256
+ LOG_ERR ("Invalid status" );
5257
+ valid = false;
5258
+ break ;
5259
+ }
5260
+
5261
+ if (!valid ) {
5262
+ /* Clear all calls */
5263
+ ag -> ongoing_call_count = 0 ;
5264
+ goto failed ;
5265
+ }
5266
+
5267
+ memcpy (& ag -> ongoing_calls [ag -> ongoing_call_count ], call ,
5268
+ sizeof (ag -> ongoing_calls [ag -> ongoing_call_count ]));
5269
+ }
5270
+
5271
+ if (ag -> ongoing_call_count > 1 ) {
5272
+ switch (ag -> ongoing_calls [0 ].status ) {
5273
+ case BT_HFP_AG_CALL_STATUS_ACTIVE :
5274
+ case BT_HFP_AG_CALL_STATUS_HELD :
5275
+ case BT_HFP_AG_CALL_STATUS_INCOMING_HELD :
5276
+ break ;
5277
+ default :
5278
+ LOG_ERR ("Unexpected call status for multiple calls" );
5279
+ /* Clear all calls */
5280
+ ag -> ongoing_call_count = 0 ;
5281
+ goto failed ;
5282
+ }
5283
+ }
5284
+
5285
+ err = 0 ;
5286
+
5287
+ failed :
5288
+ k_work_cancel_delayable (& ag -> ongoing_call_work );
5289
+ bt_hfp_ag_notify_cind_value (ag );
5290
+ bt_ag_send_ok_code (ag );
5291
+ return err ;
5292
+ }
0 commit comments