1 /*
2 * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /************************************************************************************
8 *
9 * Filename: btc_hf.c
10 *
11 * Description: Handsfree Profile Bluetooth Interface
12 * *
13 ***********************************************************************************/
14 #include <stdint.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <assert.h>
19 #include "time.h"
20 #include "btc/btc_dm.h"
21 #include "btc_hf_ag.h"
22 #include "btc/btc_profile_queue.h"
23 #include "btc/btc_manage.h"
24 #include "btc/btc_util.h"
25 #include "btc/btc_common.h"
26 #include "bta/bta_ag_api.h"
27 #include "bt_common.h"
28 #include "common/bt_target.h"
29 #include "common/bt_trace.h"
30 #include "common/bt_defs.h"
31 #include "device/bdaddr.h"
32 #include "esp_bt.h"
33 #include "esp_hf_ag_api.h"
34 #include "osi/allocator.h"
35
36
37 #if (BTC_HF_INCLUDED == TRUE)
38 /************************************************************************************
39 ** Constants & Macros
40 ************************************************************************************/
41 #ifndef BTC_HSAG_SERVICE_NAME
42 #define BTC_HSAG_SERVICE_NAME ("Headset Gateway")
43 #endif
44
45 #ifndef BTC_HFAG_SERVICE_NAME
46 #define BTC_HFAG_SERVICE_NAME ("Handsfree Gateway")
47 #endif
48
49 #ifndef BTC_HF_SERVICES
50 #define BTC_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
51 #endif
52
53 #ifndef BTC_HF_SERVICE_NAMES
54 #define BTC_HF_SERVICE_NAMES {BTC_HSAG_SERVICE_NAME , BTC_HFAG_SERVICE_NAME}
55 #endif
56
57 #ifndef BTC_HF_SECURITY
58 #define BTC_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
59 #endif
60
61 #define BTC_HF_INVALID_IDX -1
62
63 /* Max HF Clients Supported From App */
64 static UINT16 btc_max_hf_clients = BTC_HF_NUM_CB;
65 /* HF Param Definition */
66 #if HFP_DYNAMIC_MEMORY == FALSE
67 static hf_local_param_t hf_local_param[BTC_HF_NUM_CB];
68 #else
69 hf_local_param_t *hf_local_param_ptr = NULL;
70 #endif
71
72 #if (BTM_WBS_INCLUDED == TRUE)
73 #ifndef BTC_HF_FEATURES
74 #define BTC_HF_FEATURES ( BTA_AG_FEAT_ECNR | \
75 BTA_AG_FEAT_REJECT | \
76 BTA_AG_FEAT_ECS | \
77 BTA_AG_FEAT_EXTERR | \
78 BTA_AG_FEAT_VREC | \
79 BTA_AG_FEAT_INBAND | \
80 BTA_AG_FEAT_CODEC | \
81 BTA_AG_FEAT_ESCO_S4 | \
82 BTA_AG_FEAT_UNAT )
83 #endif
84 #else
85 #ifndef BTC_HF_FEATURES
86 #if BT_HF_AG_BQB_INCLUDED
87 #define BTC_HF_FEATURES ( BTA_AG_FEAT_REJECT | \
88 BTA_AG_FEAT_ECS | \
89 BTA_AG_FEAT_EXTERR | \
90 BTA_AG_FEAT_VREC | \
91 BTA_AG_FEAT_INBAND | \
92 BTA_AG_FEAT_ESCO_S4 | \
93 BTA_AG_FEAT_UNAT )
94 #else
95 #define BTC_HF_FEATURES ( BTA_AG_FEAT_ECNR | \
96 BTA_AG_FEAT_REJECT | \
97 BTA_AG_FEAT_ECS | \
98 BTA_AG_FEAT_EXTERR | \
99 BTA_AG_FEAT_VREC | \
100 BTA_AG_FEAT_INBAND | \
101 BTA_AG_FEAT_ESCO_S4 | \
102 BTA_AG_FEAT_UNAT )
103 #endif /* BT_HF_AG_BQB_INCLUDED */
104 #endif
105 #endif
106
107 /* wide band synchronous */
108 #ifndef BTC_HF_WBS_PREFERRED
109 #define BTC_HF_WBS_PREFERRED TRUE
110 #endif
111 BOOLEAN btc_conf_hf_force_wbs = BTC_HF_WBS_PREFERRED;
112
113 #define CHECK_HF_INIT(idx) \
114 do { \
115 if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \
116 return BT_STATUS_FAIL; \
117 } \
118 if (!hf_local_param[idx].btc_hf_cb.initialized) { \
119 BTIF_TRACE_WARNING("CHECK_HF_INIT: %s: HF AG not initialized", __FUNCTION__); \
120 return BT_STATUS_NOT_READY; \
121 } else { \
122 BTIF_TRACE_EVENT("CHECK_HF_INIT: %s", __FUNCTION__); \
123 } \
124 } while (0)
125
126 #define CHECK_HF_SLC_CONNECTED(idx) \
127 do { \
128 if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \
129 return BT_STATUS_FAIL; \
130 } \
131 if (!hf_local_param[idx].btc_hf_cb.initialized || \
132 hf_local_param[idx].btc_hf_cb.connection_state != ESP_HF_CONNECTION_STATE_SLC_CONNECTED) { \
133 BTIF_TRACE_WARNING("CHECK_HF_SLC_CONNECTED: %s: HF AG SLC not connected", __FUNCTION__); \
134 return BT_STATUS_NOT_READY; \
135 } else { \
136 BTIF_TRACE_EVENT("CHECK_HF_SLC_CONNECTED: %s", __FUNCTION__); \
137 } \
138 } while (0)
139
140
141 #define clear_phone_state() \
142 hf_local_param[idx].btc_hf_cb.call_state = ESP_HF_CALL_STATUS_NO_CALLS; \
143 hf_local_param[idx].btc_hf_cb.call_setup_state = ESP_HF_CALL_SETUP_STATUS_IDLE;\
144 hf_local_param[idx].btc_hf_cb.num_active = 0; \
145 hf_local_param[idx].btc_hf_cb.num_held = 0;
146
147 #define CHECK_HF_IDX(idx) \
148 do { \
149 if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) { \
150 BTC_TRACE_ERROR("%s:%d Invalid index %d", __FUNCTION__, __LINE__, idx); \
151 return; \
152 } \
153 } while (0)
154
155 /************************************************************************************
156 ** Static Function
157 ************************************************************************************/
btc_hf_idx_by_bdaddr(bt_bdaddr_t * bd_addr)158 static int btc_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
159 {
160 for (int i = 0; i < btc_max_hf_clients; ++i) {
161 if (bdcmp(bd_addr->address, hf_local_param[i].btc_hf_cb.connected_bda.address) == 0) {
162 return i;
163 }
164 }
165 return BTC_HF_INVALID_IDX;
166 }
167
btc_hf_find_free_idx(void)168 static int btc_hf_find_free_idx(void)
169 {
170 for (int idx = 0; idx < btc_max_hf_clients; ++idx) {
171 if (hf_local_param[idx].btc_hf_cb.initialized &&
172 hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED) {
173 return idx;
174 }
175 }
176 return BTC_HF_INVALID_IDX;
177 }
178
is_connected(int idx,bt_bdaddr_t * bd_addr)179 static BOOLEAN is_connected(int idx, bt_bdaddr_t *bd_addr)
180 {
181 if ((bdcmp(bd_addr->address,hf_local_param[idx].btc_hf_cb.connected_bda.address) == 0) &&
182 ((hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_CONNECTED) ||
183 (hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED))) {
184 return TRUE;
185 }
186 return FALSE;
187 }
188
btc_hf_latest_connected_idx(void)189 static int btc_hf_latest_connected_idx(void)
190 {
191 struct timespec now, conn_time_delta;
192 int latest_conn_idx = BTC_HF_INVALID_IDX;
193 clock_gettime(CLOCK_MONOTONIC, &now);
194 conn_time_delta.tv_sec = now.tv_sec;
195
196 for (int i = 0; i < btc_max_hf_clients; i++) {
197 if (hf_local_param[i].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED) {
198 if ((now.tv_sec - hf_local_param[i].btc_hf_cb.connected_timestamp.tv_sec) < conn_time_delta.tv_sec) {
199 conn_time_delta.tv_sec = now.tv_sec - hf_local_param[i].btc_hf_cb.connected_timestamp.tv_sec;
200 latest_conn_idx = i;
201 }
202 }
203 }
204 return latest_conn_idx;
205 }
206
207 /************************************************************************************
208 ** Cb and Evt
209 ************************************************************************************/
btc_hf_cb_to_app(esp_hf_cb_event_t event,esp_hf_cb_param_t * param)210 static inline void btc_hf_cb_to_app(esp_hf_cb_event_t event, esp_hf_cb_param_t *param)
211 {
212 esp_hf_cb_t btc_hf_callbacks = (esp_hf_cb_t)btc_profile_cb_get(BTC_PID_HF);
213 if (btc_hf_callbacks) {
214 btc_hf_callbacks(event, param);
215 }
216 }
217
send_indicator_update(UINT16 indicator,UINT16 value)218 static void send_indicator_update(UINT16 indicator, UINT16 value)
219 {
220 tBTA_AG_RES_DATA ag_res;
221 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
222 ag_res.ind.type = indicator;
223 ag_res.ind.value = value;
224 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
225 }
226
bte_hf_evt(tBTA_AG_EVT event,tBTA_AG * param)227 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *param)
228 {
229 int param_len = 0;
230 /* TODO: BTA sends the union members and not tBTA_AG. If using param_len=sizeof(tBTA_AG), we get a crash on memcpy */
231 if (BTA_AG_REGISTER_EVT == event) {
232 param_len = sizeof(tBTA_AG_REGISTER);
233 }
234 else if (BTA_AG_OPEN_EVT == event) {
235 param_len = sizeof(tBTA_AG_OPEN);
236 }
237 else if ((BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event)) {
238 param_len = sizeof(tBTA_AG_HDR);
239 }
240 else if (BTA_AG_CONN_EVT == event) {
241 param_len = sizeof(tBTA_AG_CONN);
242 }
243 else if (param) {
244 param_len = sizeof(tBTA_AG_VAL);
245 }
246 btc_msg_t msg;
247 msg.sig = BTC_SIG_API_CB;
248 msg.pid = BTC_PID_HF;
249 msg.act = event;
250
251 /* Switch to BTC context */
252 bt_status_t status = btc_transfer_context(&msg, param, param_len, NULL, NULL);
253 /* catch any failed context transfers */
254 BTC_ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
255 }
256
257 /************************************************************************************
258 ** Data flow control & Service management.
259 ************************************************************************************/
btc_hf_reg_data_cb(esp_hf_incoming_data_cb_t recv,esp_hf_outgoing_data_cb_t send)260 void btc_hf_reg_data_cb(esp_hf_incoming_data_cb_t recv, esp_hf_outgoing_data_cb_t send)
261 {
262 hf_local_param[0].btc_hf_incoming_data_cb = recv;
263 hf_local_param[0].btc_hf_outgoing_data_cb = send;
264 }
265
btc_hf_incoming_data_cb_to_app(const uint8_t * data,uint32_t len)266 void btc_hf_incoming_data_cb_to_app(const uint8_t *data, uint32_t len)
267 {
268 int idx = 0;
269 // todo: critical section protection
270 if (hf_local_param[idx].btc_hf_incoming_data_cb) {
271 hf_local_param[idx].btc_hf_incoming_data_cb(data, len);
272 }
273 }
274
btc_hf_outgoing_data_cb_to_app(uint8_t * data,uint32_t len)275 uint32_t btc_hf_outgoing_data_cb_to_app(uint8_t *data, uint32_t len)
276 {
277 int idx = 0;
278 // todo: critical section protection
279 if (hf_local_param[idx].btc_hf_outgoing_data_cb) {
280 return hf_local_param[idx].btc_hf_outgoing_data_cb(data, len);
281 } else {
282 return 0;
283 }
284 }
285
btc_hf_execute_service(BOOLEAN b_enable)286 bt_status_t btc_hf_execute_service(BOOLEAN b_enable)
287 {
288 char * p_service_names[] = BTC_HF_SERVICE_NAMES;
289 int idx;
290 if (b_enable) {
291 /* Enable and register with BTA-AG */
292 BTA_AgEnable(BTA_AG_PARSE, bte_hf_evt);
293 for (idx = 0; idx < btc_max_hf_clients; idx++) {
294 BTA_AgRegister(BTC_HF_SERVICES, BTC_HF_SECURITY, BTC_HF_FEATURES, p_service_names, BTC_HF_ID_1);
295 }
296 } else {
297 /* De-register AG */
298 for (idx = 0; idx < btc_max_hf_clients; idx++) {
299 BTA_AgDeregister(hf_local_param[idx].btc_hf_cb.handle);
300 }
301 /* Disable AG */
302 BTA_AgDisable();
303 }
304 return BT_STATUS_SUCCESS;
305 }
306
307 /************************************************************************************
308 ** BTC HFP AG API FUNCTION
309 ************************************************************************************/
310 /************************************************************************************
311 ** Initialization and Connection Handle
312 ************************************************************************************/
btc_hf_init(void)313 bt_status_t btc_hf_init(void)
314 {
315 int idx = 0;
316
317 #if HFP_DYNAMIC_MEMORY == TRUE
318 if (hf_local_param)
319 #endif
320 {
321 if (hf_local_param[idx].btc_hf_cb.initialized) {
322 esp_hf_cb_param_t param = {
323 .prof_stat.state = ESP_HF_INIT_ALREADY,
324 };
325 btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, ¶m);
326 return BT_STATUS_SUCCESS;
327 }
328 }
329
330 BTC_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btc_max_hf_clients);
331
332 #if HFP_DYNAMIC_MEMORY == TRUE
333 if (hf_local_param == NULL) {
334 if ((hf_local_param = (hf_local_param_t *)osi_malloc(BTC_HF_NUM_CB * sizeof(hf_local_param_t))) == NULL) {
335 BTC_TRACE_ERROR("%s malloc failed!", __func__);
336 return BT_STATUS_NOMEM;
337 }
338 }
339 memset((void *)hf_local_param, 0, BTC_HF_NUM_CB * sizeof(hf_local_param_t));
340 #endif
341
342 /* Invoke the enable service API to the core to set the appropriate service_id
343 * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
344 * otherwise only HSP is enabled (tablet)*/
345 #if (defined(BTC_HF_SERVICES) && (BTC_HF_SERVICES & BTA_HFP_SERVICE_MASK))
346 btc_dm_enable_service(BTA_HFP_SERVICE_ID);
347 #else
348 btc_dm_enable_service(BTA_HSP_SERVICE_ID);
349 #endif
350 clear_phone_state();
351 memset(&hf_local_param[idx].btc_hf_cb, 0, sizeof(btc_hf_cb_t));
352 // set audio path
353 #if BTM_SCO_HCI_INCLUDED
354 uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
355 #else
356 uint8_t data_path = ESP_SCO_DATA_PATH_PCM;
357 #endif
358 esp_bredr_sco_datapath_set(data_path);
359
360 return BT_STATUS_SUCCESS;
361 }
362
btc_hf_deinit(void)363 void btc_hf_deinit(void)
364 {
365 BTC_TRACE_EVENT("%s", __FUNCTION__);
366
367 int idx = 0;
368
369 #if HFP_DYNAMIC_MEMORY == TRUE
370 if (hf_local_param)
371 #endif
372 {
373 if (!hf_local_param[idx].btc_hf_cb.initialized) {
374 esp_hf_cb_param_t param = {
375 .prof_stat.state = ESP_HF_DEINIT_ALREADY,
376 };
377 btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, ¶m);
378 return;
379 }
380 }
381
382 btc_dm_disable_service(BTA_HFP_SERVICE_ID);
383 }
384
btc_hf_cb_release(void)385 static void btc_hf_cb_release(void)
386 {
387 #if HFP_DYNAMIC_MEMORY == TRUE
388 if (hf_local_param) {
389 osi_free(hf_local_param);
390 hf_local_param = NULL;
391 }
392 #endif
393 }
394
connect_init(bt_bdaddr_t * bd_addr,uint16_t uuid)395 static bt_status_t connect_init(bt_bdaddr_t *bd_addr, uint16_t uuid)
396 {
397 int idx = btc_hf_find_free_idx();
398
399 if (idx == BTC_HF_INVALID_IDX) {
400 return BT_STATUS_BUSY;
401 }
402
403 if (!is_connected(idx, bd_addr)) {
404 hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_CONNECTING;
405 bdcpy(hf_local_param[idx].btc_hf_cb.connected_bda.address, bd_addr->address);
406 BTA_AgOpen(hf_local_param[idx].btc_hf_cb.handle, hf_local_param[idx].btc_hf_cb.connected_bda.address, BTC_HF_SECURITY, BTC_HF_SERVICES);
407 return BT_STATUS_SUCCESS;
408 }
409 return BT_STATUS_BUSY;
410 }
btc_hf_connect(bt_bdaddr_t * bd_addr)411 bt_status_t btc_hf_connect(bt_bdaddr_t *bd_addr)
412 {
413 return btc_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_init);
414 }
415
btc_hf_disconnect(bt_bdaddr_t * bd_addr)416 bt_status_t btc_hf_disconnect(bt_bdaddr_t *bd_addr)
417 {
418 int idx = btc_hf_idx_by_bdaddr(bd_addr);
419
420 if ((idx < 0) || (idx >= BTC_HF_NUM_CB)) {
421 BTC_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
422 return BT_STATUS_FAIL;
423 }
424
425 if (is_connected(idx, bd_addr)) {
426 BTA_AgClose(hf_local_param[idx].btc_hf_cb.handle);
427 return BT_STATUS_SUCCESS;
428 }
429 return BT_STATUS_FAIL;
430 }
431
btc_hf_connect_audio(bt_bdaddr_t * bd_addr)432 bt_status_t btc_hf_connect_audio(bt_bdaddr_t *bd_addr)
433 {
434 int idx = btc_hf_idx_by_bdaddr(bd_addr);
435 CHECK_HF_SLC_CONNECTED(idx);
436
437 if (is_connected(idx, bd_addr)) {
438 BTA_AgAudioOpen(hf_local_param[idx].btc_hf_cb.handle);
439 /* Inform the application that the audio connection has been initiated successfully */
440 do {
441 esp_hf_cb_param_t param;
442 memset(¶m, 0, sizeof(esp_hf_cb_param_t));
443 param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTING;
444 memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t));
445 btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m);
446 } while (0);
447 return BT_STATUS_SUCCESS;
448 }
449 return BT_STATUS_FAIL;
450 }
451
btc_hf_disconnect_audio(bt_bdaddr_t * bd_addr)452 bt_status_t btc_hf_disconnect_audio(bt_bdaddr_t *bd_addr)
453 {
454 int idx = btc_hf_idx_by_bdaddr(bd_addr);
455 CHECK_HF_SLC_CONNECTED(idx);
456
457 if (is_connected(idx, bd_addr)) {
458 BTA_AgAudioClose(hf_local_param[idx].btc_hf_cb.handle);
459 return BT_STATUS_SUCCESS;
460 }
461 return BT_STATUS_FAIL;
462 }
463
btc_hf_pkt_stat_nums_get(UINT16 sync_conn_handle)464 static bt_status_t btc_hf_pkt_stat_nums_get(UINT16 sync_conn_handle)
465 {
466 bt_status_t status = BT_STATUS_FAIL;
467 #if (BTM_SCO_HCI_INCLUDED == TRUE)
468 int idx = btc_hf_latest_connected_idx();
469 CHECK_HF_SLC_CONNECTED(idx);
470
471 if (idx != BTC_HF_INVALID_IDX) {
472 BTA_AgPktStatsNumsGet(hf_local_param[idx].btc_hf_cb.handle, sync_conn_handle);
473 status = BT_STATUS_SUCCESS;
474 }
475 #endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE) */
476 return status;
477 }
478
479 /************************************************************************************
480 ** AT cmd Handle
481 ************************************************************************************/
482 //AT+VRA
btc_hf_vra(bt_bdaddr_t * bd_addr,esp_hf_vr_state_t value)483 static bt_status_t btc_hf_vra(bt_bdaddr_t *bd_addr, esp_hf_vr_state_t value)
484 {
485 int idx = btc_hf_idx_by_bdaddr(bd_addr);
486 CHECK_HF_SLC_CONNECTED(idx);
487
488 if (is_connected(idx, bd_addr)) {
489 if (hf_local_param[idx].btc_hf_cb.peer_feat & BTA_AG_PEER_FEAT_VREC) {
490 tBTA_AG_RES_DATA ag_res;
491 memset(&ag_res, 0, sizeof(ag_res));
492 ag_res.state = value;
493 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_BVRA_RES, &ag_res);
494 return BT_STATUS_SUCCESS;
495 } else {
496 return BT_STATUS_UNSUPPORTED;
497 }
498 }
499 return BT_STATUS_NOT_READY;
500 }
501
btc_hf_volume_control(bt_bdaddr_t * bd_addr,esp_hf_volume_type_t type,int volume)502 static bt_status_t btc_hf_volume_control(bt_bdaddr_t *bd_addr, esp_hf_volume_type_t type, int volume)
503 {
504 int idx = btc_hf_idx_by_bdaddr(bd_addr);
505 CHECK_HF_SLC_CONNECTED(idx);
506 tBTA_AG_RES_DATA ag_res;
507 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
508
509 if (is_connected(idx, bd_addr)) {
510 ag_res.num = volume;
511 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, (type == ESP_HF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES, &ag_res);
512 return BT_STATUS_SUCCESS;
513 }
514 return BT_STATUS_FAIL;
515 }
516
517 // Pre-formatted AT response, typically in response to unknown AT cmd
btc_hf_unat_response(bt_bdaddr_t * bd_addr,const char * unat)518 static bt_status_t btc_hf_unat_response(bt_bdaddr_t *bd_addr, const char *unat)
519 {
520 int idx = btc_hf_idx_by_bdaddr(bd_addr);
521 CHECK_HF_INIT(idx);
522
523 if (is_connected(idx, bd_addr))
524 {
525 tBTA_AG_RES_DATA ag_res;
526 /* Format the response and send */
527 memset(&ag_res, 0, sizeof(ag_res));
528 if (unat != NULL) {
529 strncpy(ag_res.str, unat, BTA_AG_AT_MAX_LEN);
530 } else {
531 ag_res.ok_flag = BTA_AG_OK_ERROR;
532 ag_res.errcode = BTA_AG_ERR_OP_NOT_SUPPORTED;
533 }
534
535 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
536 return BT_STATUS_SUCCESS;
537 }
538 return BT_STATUS_FAIL;
539 }
540
541 // +CMEE:<response>
btc_hf_cmee_response(bt_bdaddr_t * bd_addr,esp_hf_at_response_code_t response_code,esp_hf_cme_err_t error_code)542 static bt_status_t btc_hf_cmee_response(bt_bdaddr_t *bd_addr, esp_hf_at_response_code_t response_code, esp_hf_cme_err_t error_code)
543 {
544 int idx = btc_hf_idx_by_bdaddr(bd_addr);
545 CHECK_HF_INIT(idx);
546
547 if (is_connected(idx, bd_addr)) {
548 tBTA_AG_RES_DATA ag_res;
549 memset(&ag_res, 0, sizeof(ag_res));
550 if (response_code == ESP_HF_AT_RESPONSE_CODE_OK) {
551 ag_res.ok_flag = BTA_AG_OK_DONE;
552 } else {
553 ag_res.ok_flag = BTA_AG_OK_ERROR;
554 ag_res.errcode = error_code;
555 }
556 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
557 return BT_STATUS_SUCCESS;
558 }
559 return BT_STATUS_FAIL;
560 }
561
562 // +CIEV<...> for device status update
btc_hf_indchange_notification(bt_bdaddr_t * bd_addr,esp_hf_call_status_t call_state,esp_hf_call_setup_status_t call_setup_state,esp_hf_network_state_t ntk_state,int signal)563 static bt_status_t btc_hf_indchange_notification(bt_bdaddr_t *bd_addr,
564 esp_hf_call_status_t call_state,
565 esp_hf_call_setup_status_t call_setup_state,
566 esp_hf_network_state_t ntk_state, int signal)
567 {
568 int idx = btc_hf_idx_by_bdaddr(bd_addr);
569 CHECK_HF_INIT(idx);
570 if (is_connected(idx, bd_addr)) {
571 /* Send all indicators to BTA.
572 * BTA will make sure no duplicates are sent out*/
573 send_indicator_update(BTA_AG_IND_CALL, call_state);
574 send_indicator_update(BTA_AG_IND_CALLSETUP, call_setup_state);
575 send_indicator_update(BTA_AG_IND_SERVICE, ntk_state);
576 send_indicator_update(BTA_AG_IND_SIGNAL, signal);
577 return BT_STATUS_SUCCESS;
578 }
579 return BT_STATUS_FAIL;
580 }
581
582 // +CIEV<...> for device status update, send other indicators, e.g. roaming, battery, call held and bearer
btc_hf_ciev_report(bt_bdaddr_t * bd_addr,tBTA_AG_IND_TYPE indicator,uint16_t value)583 bt_status_t btc_hf_ciev_report(bt_bdaddr_t *bd_addr, tBTA_AG_IND_TYPE indicator, uint16_t value)
584 {
585 int idx = btc_hf_idx_by_bdaddr(bd_addr);
586 CHECK_HF_INIT(idx);
587
588 if (is_connected(idx, bd_addr)) {
589 send_indicator_update(indicator, value);
590 return BT_STATUS_SUCCESS;
591 }
592 return BT_STATUS_FAIL;
593 }
594
595 //AT+CIND response
btc_hf_cind_response(bt_bdaddr_t * bd_addr,esp_hf_call_setup_status_t call_status,esp_hf_call_setup_status_t call_setup_status,esp_hf_network_state_t ntk_state,int signal,esp_hf_service_type_t roam,int batt_lev,esp_hf_call_held_status_t call_held_status)596 static bt_status_t btc_hf_cind_response(bt_bdaddr_t *bd_addr,
597 esp_hf_call_setup_status_t call_status,
598 esp_hf_call_setup_status_t call_setup_status,
599 esp_hf_network_state_t ntk_state, int signal, esp_hf_service_type_t roam, int batt_lev,
600 esp_hf_call_held_status_t call_held_status)
601 {
602 int idx = btc_hf_idx_by_bdaddr(bd_addr);
603 CHECK_HF_INIT(idx);
604
605 if (is_connected(idx, bd_addr)) {
606 tBTA_AG_RES_DATA ag_res;
607 memset(&ag_res, 0, sizeof (ag_res));
608 sprintf(ag_res.str, "%d,%d,%d,%d,%d,%d,%d",
609 call_status, /* Call state*/
610 call_setup_status, /* Callsetup state */
611 ntk_state, /* network service */
612 signal, /* Signal strength */
613 roam, /* Roaming indicator */
614 batt_lev, /* Battery level */
615 call_held_status /* Callheld state */
616 );
617 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_CIND_RES, &ag_res);
618 return BT_STATUS_SUCCESS;
619 }
620 return BT_STATUS_FAIL;
621 }
622
623 //AT+COPS response
btc_hf_cops_response(bt_bdaddr_t * bd_addr,const char * name)624 static bt_status_t btc_hf_cops_response(bt_bdaddr_t *bd_addr, const char *name)
625 {
626 int idx = btc_hf_idx_by_bdaddr(bd_addr);
627 CHECK_HF_SLC_CONNECTED(idx);
628
629 if (is_connected(idx, bd_addr)) {
630 tBTA_AG_RES_DATA ag_res;
631 memset (&ag_res, 0, sizeof (ag_res));
632 /* Format the response */
633 sprintf(ag_res.str, "0,0,\"%s\"", name);
634 ag_res.ok_flag = BTA_AG_OK_DONE;
635 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_COPS_RES, &ag_res);
636 return BT_STATUS_SUCCESS;
637 }
638 return BT_STATUS_FAIL;
639 }
640
641 //AT+CLCC response
btc_hf_clcc_response(bt_bdaddr_t * bd_addr,int index,esp_hf_current_call_direction_t dir,esp_hf_current_call_status_t current_call_state,esp_hf_current_call_mode_t mode,esp_hf_current_call_mpty_type_t mpty,const char * number,esp_hf_call_addr_type_t type)642 static bt_status_t btc_hf_clcc_response(bt_bdaddr_t *bd_addr, int index, esp_hf_current_call_direction_t dir,
643 esp_hf_current_call_status_t current_call_state,
644 esp_hf_current_call_mode_t mode, esp_hf_current_call_mpty_type_t mpty,
645 const char *number, esp_hf_call_addr_type_t type)
646 {
647 int idx = btc_hf_idx_by_bdaddr(bd_addr);
648 CHECK_HF_SLC_CONNECTED(idx);
649
650 if (is_connected(idx, bd_addr)) {
651 tBTA_AG_RES_DATA ag_res;
652 memset (&ag_res, 0, sizeof (ag_res));
653 if (index == 0) {
654 ag_res.ok_flag = BTA_AG_OK_DONE;
655 } else {
656 BTC_TRACE_EVENT("clcc_response: [%d] dir: %d current_call_state: %d mode: %d number: %s type: %d",
657 index, dir, current_call_state, mode, number, type);
658 int loc = sprintf (ag_res.str, "%d,%d,%d,%d,%d", index, dir, current_call_state, mode, mpty);
659 if (number) {
660 if ((type == ESP_HF_CALL_ADDR_TYPE_INTERNATIONAL) && (*number != '+')) {
661 sprintf(&ag_res.str[loc], ",\"+%s\",%d", number, type);
662 } else {
663 sprintf(&ag_res.str[loc], ",\"%s\",%d", number, type);
664 }
665 }
666 }
667 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_CLCC_RES, &ag_res);
668 return BT_STATUS_SUCCESS;
669 }
670 return BT_STATUS_FAIL;
671 }
672
673 //AT+CNUM
btc_hf_cnum_response(bt_bdaddr_t * bd_addr,const char * number,int number_type,esp_hf_subscriber_service_type_t service_type)674 static bt_status_t btc_hf_cnum_response(bt_bdaddr_t *bd_addr, const char *number, int number_type, esp_hf_subscriber_service_type_t service_type)
675 {
676 int idx = btc_hf_idx_by_bdaddr(bd_addr);
677 CHECK_HF_SLC_CONNECTED(idx);
678
679 if (is_connected(idx, bd_addr)) {
680 tBTA_AG_RES_DATA ag_res;
681 memset(&ag_res, 0, sizeof (ag_res));
682 BTC_TRACE_EVENT("cnum_response: number = %s, number type = %d, service type = %d", number, number_type, service_type);
683 if (service_type) {
684 sprintf(ag_res.str, ",\"%s\",%d,,%d",number, number_type, service_type);
685 } else {
686 sprintf(ag_res.str, ",\"%s\",%d,,",number, number_type);
687 }
688 ag_res.ok_flag = BTA_AG_OK_DONE;
689 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_CNUM_RES, &ag_res);
690 return BT_STATUS_SUCCESS;
691 }
692 return BT_STATUS_FAIL;
693 }
694
695 //+BSIR
btc_hf_inband_ring(bt_bdaddr_t * bd_addr,esp_hf_in_band_ring_state_t state)696 static bt_status_t btc_hf_inband_ring(bt_bdaddr_t *bd_addr, esp_hf_in_band_ring_state_t state)
697 {
698 int idx = btc_hf_idx_by_bdaddr(bd_addr);
699 CHECK_HF_SLC_CONNECTED(idx);
700
701 if (is_connected(idx, bd_addr)) {
702 tBTA_AG_RES_DATA ag_res;
703 memset (&ag_res, 0, sizeof (ag_res));
704 ag_res.state = state;
705 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_INBAND_RING_RES, &ag_res);
706 return BT_STATUS_SUCCESS;
707 }
708 return BT_STATUS_FAIL;
709 }
710
711 //Update phone status whether AG or HF act
btc_hf_phone_state_update(bt_bdaddr_t * bd_addr,int num_active,int num_held,esp_hf_call_status_t call_state,esp_hf_call_setup_status_t call_setup_state,char * number,esp_hf_call_addr_type_t type)712 static bt_status_t btc_hf_phone_state_update(bt_bdaddr_t *bd_addr,int num_active, int num_held,
713 esp_hf_call_status_t call_state, esp_hf_call_setup_status_t call_setup_state,
714 char *number, esp_hf_call_addr_type_t type)
715 {
716 tBTA_AG_RES res = 0xff;
717 tBTA_AG_RES_DATA ag_res;
718 bt_status_t status = BT_STATUS_SUCCESS;
719 BOOLEAN activeCallUpdated = FALSE;
720 int idx = btc_hf_idx_by_bdaddr(bd_addr), i;
721
722 /* hf_idx is index of connected HS that sent ATA/BLDN, otherwise index of latest connected HS */
723 if (hf_local_param->hf_idx != BTC_HF_INVALID_IDX) {
724 idx = hf_local_param->hf_idx;
725 } else {
726 idx = btc_hf_latest_connected_idx();
727 }
728
729 BTC_TRACE_DEBUG("phone_state_change: idx = %d", idx);
730 CHECK_HF_SLC_CONNECTED(idx);
731 BTC_TRACE_DEBUG("phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d] call =%s [prev: %s] call_setup=%s [prev: %s]",
732 num_active, hf_local_param[idx].btc_hf_cb.num_active,
733 num_held, hf_local_param[idx].btc_hf_cb.num_held,
734 dump_hf_call_state(call_state), dump_hf_call_state(hf_local_param[idx].btc_hf_cb.call_state),
735 dump_hf_call_setup_state(call_setup_state), dump_hf_call_setup_state(hf_local_param[idx].btc_hf_cb.call_setup_state));
736
737 /* If all indicators are 0, send end call and return */
738 if (num_active == 0 && num_held == 0 && call_state == ESP_HF_CALL_STATUS_NO_CALLS && call_setup_state == ESP_HF_CALL_SETUP_STATUS_IDLE) {
739 BTC_TRACE_DEBUG("%s: Phone on hook", __FUNCTION__);
740
741 /* Record call termination timestamp if there was an active/held call or call_setup_state > ESP_HF_CALL_SETUP_STATUS_IDLE */
742 if ((hf_local_param[idx].btc_hf_cb.call_state != ESP_HF_CALL_STATUS_NO_CALLS) ||
743 (hf_local_param[idx].btc_hf_cb.call_setup_state != ESP_HF_CALL_SETUP_STATUS_IDLE) ||
744 (hf_local_param[idx].btc_hf_cb.num_active) ||
745 (hf_local_param[idx].btc_hf_cb.num_held)) {
746 BTC_TRACE_DEBUG("%s: Record call termination timestamp", __FUNCTION__);
747 clock_gettime(CLOCK_MONOTONIC, &hf_local_param[0].btc_hf_cb.call_end_timestamp);
748 }
749 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
750 hf_local_param->hf_idx = BTC_HF_INVALID_IDX;
751
752 /* If held call was present, reset that as well. */
753 if (hf_local_param[idx].btc_hf_cb.num_held) {
754 send_indicator_update(BTA_AG_IND_CALLHELD, 0);
755 }
756 goto update_call_states;
757 }
758
759 /* Phone state can change when:
760 * 1. An outgoing/incoming call was answered.
761 * 2. A held was resumed.
762 * 3. Without callsetup notifications, call became active. (HF Unit links in during an Active call.)
763 */
764
765 /* Handle case(3) here prior to call setup handling.*/
766 if (((num_active + num_held) > 0) &&
767 (hf_local_param[idx].btc_hf_cb.num_active == 0) &&
768 (hf_local_param[idx].btc_hf_cb.num_held == 0) &&
769 (hf_local_param[idx].btc_hf_cb.call_setup_state == ESP_HF_CALL_SETUP_STATUS_IDLE)) {
770 BTC_TRACE_DEBUG("%s: Active/Held call notification received without call setup update", __FUNCTION__);
771
772 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
773 ag_res.audio_handle = hf_local_param[idx].btc_hf_cb.handle;
774
775 /* Addition callsetup with the Active call. */
776 if (call_setup_state != ESP_HF_CALL_SETUP_STATUS_IDLE) {
777 res = BTA_AG_MULTI_CALL_RES;
778 } else {
779 res = BTA_AG_OUT_CALL_CONN_RES;
780 }
781 /* CIND response should have been updated. */
782 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
783 /* Just open SCO connection. */
784 BTA_AgAudioOpen(ag_res.audio_handle);
785 activeCallUpdated = TRUE;
786 }
787
788 /* Handle call_setup indicator change. */
789 if (call_setup_state != hf_local_param[idx].btc_hf_cb.call_setup_state) {
790 BTC_TRACE_DEBUG("%s: Call setup states changed. old: %s new: %s", __FUNCTION__,
791 dump_hf_call_setup_state(hf_local_param[idx].btc_hf_cb.call_setup_state),
792 dump_hf_call_setup_state(call_setup_state));
793 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
794
795 switch(call_setup_state)
796 {
797 case ESP_HF_CALL_SETUP_STATUS_IDLE:
798 {
799 switch(hf_local_param[idx].btc_hf_cb.call_setup_state)
800 {
801 case ESP_HF_CALL_SETUP_STATUS_INCOMING:
802 {
803 if (num_active > hf_local_param[idx].btc_hf_cb.num_active) {
804 res = BTA_AG_IN_CALL_CONN_RES;
805 ag_res.audio_handle = hf_local_param[idx].btc_hf_cb.handle;
806 } else if (num_held > hf_local_param[idx].btc_hf_cb.num_held) {
807 res = BTA_AG_IN_CALL_HELD_RES;
808 } else {
809 res = BTA_AG_CALL_CANCEL_RES;
810 }
811 break;
812 }
813
814 case ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING:
815 case ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING:
816 {
817 if (num_active > hf_local_param[idx].btc_hf_cb.num_active) {
818 res = BTA_AG_OUT_CALL_CONN_RES;
819 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
820 } else {
821 res = BTA_AG_CALL_CANCEL_RES;
822 }
823 break;
824 }
825
826 default:
827 BTC_TRACE_ERROR("%s: Call setup state no change.", __FUNCTION__);
828 status = BT_STATUS_PARM_INVALID;
829 break;
830 }
831 break;
832 }
833
834 case ESP_HF_CALL_SETUP_STATUS_INCOMING:
835 {
836 if (num_active || num_held) {
837 res = BTA_AG_CALL_WAIT_RES;
838 } else {
839 res = BTA_AG_IN_CALL_RES;
840 }
841
842 if (number) {
843 int loc = 0;
844 if ((type == ESP_HF_CALL_ADDR_TYPE_INTERNATIONAL) && (*number != '+')) {
845 loc = sprintf (ag_res.str, "\"+%s\"", number);
846 } else {
847 loc = sprintf (ag_res.str, "\"%s\"", number);
848 }
849 ag_res.num = type;
850 if (res == BTA_AG_CALL_WAIT_RES) {
851 sprintf(&ag_res.str[loc], ",%d", type);
852 }
853 }
854 break;
855 }
856
857 case ESP_HF_CALL_SETUP_STATUS_OUTGOING_DIALING:
858 {
859 if (!(num_active + num_held)) {
860 ag_res.audio_handle = hf_local_param[idx].btc_hf_cb.handle;
861 }
862 res = BTA_AG_OUT_CALL_ORIG_RES;
863 break;
864 }
865
866 case ESP_HF_CALL_SETUP_STATUS_OUTGOING_ALERTING:
867 {
868 if ((hf_local_param[idx].btc_hf_cb.call_setup_state == ESP_HF_CALL_SETUP_STATUS_IDLE) &&
869 !(num_active + num_held)) {
870 ag_res.audio_handle = hf_local_param[idx].btc_hf_cb.handle;
871 /* Force SCO setup here.*/
872 BTA_AgAudioOpen(ag_res.audio_handle);
873 }
874 res = BTA_AG_OUT_CALL_ALERT_RES;
875 break;
876 }
877
878 default:
879 BTC_TRACE_ERROR("%s: Incorrect new ringing call state", __FUNCTION__);
880 status = BT_STATUS_PARM_INVALID;
881 break;
882 }
883 BTC_TRACE_DEBUG("%s: Call setup state changed. res=%d, audio_handle=%d", __FUNCTION__, res, ag_res.audio_handle);
884 if (res) {
885 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
886 }
887 /* If call setup is idle, we have already updated call indicator, jump out */
888 if (call_setup_state == ESP_HF_CALL_SETUP_STATUS_IDLE) {
889 /* Check & Update call_held_state */
890 if ((num_held > 0) && (num_active > 0))
891 send_indicator_update(BTA_AG_IND_CALLHELD, ESP_HF_CALL_HELD_STATUS_HELD_AND_ACTIVE);
892 goto update_call_states;
893 }
894 }
895
896 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
897
898 /* Handle call_state indicator change. */
899 if (!activeCallUpdated &&
900 ((num_active + num_held) != (hf_local_param[idx].btc_hf_cb.num_active + hf_local_param[idx].btc_hf_cb.num_held))) {
901 BTC_TRACE_DEBUG("%s: Active call states changed. old: %d new: %d", __FUNCTION__, hf_local_param[idx].btc_hf_cb.num_active, num_active);
902 send_indicator_update(BTA_AG_IND_CALL, ((num_active + num_held) > 0) ? 1 : 0);
903 }
904
905 /* Handle call_held_state indicator change. */
906 if (num_held != hf_local_param[idx].btc_hf_cb.num_held ||
907 ((num_active == 0) && ((num_held + hf_local_param[idx].btc_hf_cb.num_held) > 1))) {
908 BTC_TRACE_DEBUG("%s: Held call states changed. old: %d new: %d", __FUNCTION__, hf_local_param[idx].btc_hf_cb.num_held, num_held);
909 send_indicator_update(BTA_AG_IND_CALLHELD, ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
910 }
911
912 /* Handle Call Active/Held Swap indicator update.*/
913 if ((call_setup_state == hf_local_param[idx].btc_hf_cb.call_setup_state) &&
914 (num_active) &&
915 (num_held) &&
916 (num_active == hf_local_param[idx].btc_hf_cb.num_active) &&
917 (num_held == hf_local_param[idx].btc_hf_cb.num_held)) {
918 BTC_TRACE_DEBUG("%s: Calls swapped", __FUNCTION__);
919 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
920 }
921
922 update_call_states:
923 for (i = 0; i < btc_max_hf_clients; i++) {
924 hf_local_param[i].btc_hf_cb.num_active = num_active;
925 hf_local_param[i].btc_hf_cb.num_held = num_held;
926 hf_local_param[i].btc_hf_cb.call_state = call_state;
927 hf_local_param[i].btc_hf_cb.call_setup_state = call_setup_state;
928 }
929 return status;
930 }
931
btc_hf_ci_sco_data(void)932 bt_status_t btc_hf_ci_sco_data(void)
933 {
934 bt_status_t status = BT_STATUS_SUCCESS;
935 #if (BTM_SCO_HCI_INCLUDED == TRUE)
936 int idx = btc_hf_latest_connected_idx();
937 CHECK_HF_SLC_CONNECTED(idx);
938
939 if (idx != BTC_HF_INVALID_IDX) {
940 BTA_AgCiData(hf_local_param[idx].btc_hf_cb.handle);
941 return status;
942 }
943 status = BT_STATUS_FAIL;
944 #endif /*#if (BTM_SCO_HCI_INCLUDED == TRUE ) */
945 return status;
946 }
947
948 /************************************************************************************
949 ** Memory malloc and release
950 ************************************************************************************/
btc_hf_arg_deep_copy(btc_msg_t * msg,void * p_dest,void * p_src)951 void btc_hf_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
952 {
953 btc_hf_args_t *dst = (btc_hf_args_t *) p_dest;
954 btc_hf_args_t *src = (btc_hf_args_t *) p_src;
955
956 switch (msg->act) {
957 case BTC_HF_UNAT_RESPONSE_EVT:
958 {
959 if (src->unat_rep.unat == NULL) {
960 break;
961 }
962
963 dst->unat_rep.unat = (char *)osi_malloc(strlen(src->unat_rep.unat)+1);
964 if(dst->unat_rep.unat) {
965 memcpy(dst->unat_rep.unat, src->unat_rep.unat, strlen(src->unat_rep.unat)+1);
966 } else if (strlen(src->unat_rep.unat) == 0) {
967 BTC_TRACE_DEBUG("%s %d no mem\n", __func__, msg->act);
968 } else {
969 BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
970 }
971 break;
972 }
973
974 case BTC_HF_COPS_RESPONSE_EVT:
975 {
976 if (src->cops_rep.name == NULL) {
977 break;
978 }
979
980 dst->cops_rep.name = (char *)osi_malloc(strlen(src->cops_rep.name)+1);
981 if(dst->cops_rep.name) {
982 memcpy(dst->cops_rep.name, src->cops_rep.name, strlen(src->cops_rep.name)+1);
983 } else if (strlen(src->cops_rep.name) == 0) {
984 BTC_TRACE_DEBUG("%s %d no mem\n", __func__, msg->act);
985 } else {
986 BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
987 }
988 break;
989 }
990
991 case BTC_HF_CLCC_RESPONSE_EVT:
992 {
993 if (src->clcc_rep.number == NULL) {
994 break;
995 }
996
997 dst->clcc_rep.number = (char *)osi_malloc(strlen(src->clcc_rep.number)+1);
998 if(dst->clcc_rep.number) {
999 memcpy(dst->clcc_rep.number, src->clcc_rep.number, strlen(src->clcc_rep.number)+1);
1000 } else if (strlen(src->clcc_rep.number) == 0) {
1001 BTC_TRACE_DEBUG("%s %d no mem\n", __func__, msg->act);
1002 } else {
1003 BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
1004 }
1005 break;
1006 }
1007
1008 case BTC_HF_CNUM_RESPONSE_EVT:
1009 {
1010 if (src->cnum_rep.number == NULL) {
1011 break;
1012 }
1013
1014 dst->cnum_rep.number = (char *)osi_malloc(strlen(src->cnum_rep.number)+1);
1015 if(dst->cnum_rep.number) {
1016 memcpy(dst->cnum_rep.number, src->cnum_rep.number, strlen(src->cnum_rep.number)+1);
1017 } else if (strlen(src->cnum_rep.number) == 0) {
1018 BTC_TRACE_DEBUG("%s %d no mem\n", __func__, msg->act);
1019 } else {
1020 BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
1021 }
1022 break;
1023 }
1024
1025 case BTC_HF_AC_INCALL_EVT:
1026 case BTC_HF_RJ_INCALL_EVT:
1027 case BTC_HF_OUT_CALL_EVT:
1028 case BTC_HF_END_CALL_EVT:
1029 {
1030 if (src->phone.number == NULL) {
1031 break;
1032 }
1033
1034 dst->phone.number = (char *)osi_malloc(strlen(src->phone.number)+1);
1035 if(dst->phone.number) {
1036 memcpy(dst->phone.number, src->phone.number, strlen(src->phone.number)+1);
1037 } else if (strlen(src->phone.number) == 0) {
1038 BTC_TRACE_DEBUG("%s %d no mem\n", __func__, msg->act);
1039 } else {
1040 BTC_TRACE_ERROR("%s %d osi_malloc failed\n", __func__, msg->act);
1041 }
1042 break;
1043 }
1044
1045 default:
1046 break;
1047 }
1048 }
1049
btc_hf_arg_deep_free(btc_msg_t * msg)1050 void btc_hf_arg_deep_free(btc_msg_t *msg)
1051 {
1052 btc_hf_args_t *arg = (btc_hf_args_t *)msg->arg;
1053
1054 switch (msg->act) {
1055 case BTC_HF_UNAT_RESPONSE_EVT:
1056 {
1057 if (arg->unat_rep.unat) {
1058 osi_free(arg->unat_rep.unat);
1059 }
1060 break;
1061 }
1062
1063 case BTC_HF_COPS_RESPONSE_EVT:
1064 {
1065 if (arg->cops_rep.name) {
1066 osi_free(arg->cops_rep.name);
1067 }
1068 break;
1069 }
1070
1071 case BTC_HF_CLCC_RESPONSE_EVT:
1072 {
1073 if (arg->clcc_rep.number) {
1074 osi_free(arg->clcc_rep.number);
1075 }
1076 break;
1077 }
1078
1079 case BTC_HF_CNUM_RESPONSE_EVT:
1080 {
1081 if (arg->cnum_rep.number) {
1082 osi_free(arg->cnum_rep.number);
1083 }
1084 break;
1085 }
1086
1087 case BTC_HF_AC_INCALL_EVT:
1088 case BTC_HF_RJ_INCALL_EVT:
1089 case BTC_HF_OUT_CALL_EVT:
1090 case BTC_HF_END_CALL_EVT:
1091 {
1092 if (arg->phone.number) {
1093 osi_free(arg->phone.number);
1094 }
1095 break;
1096 }
1097
1098 default:
1099 break;
1100 }
1101 }
1102
1103 /************************************************************************************
1104 ** Handler Functions (handle the cmd from app)
1105 ************************************************************************************/
btc_hf_call_handler(btc_msg_t * msg)1106 void btc_hf_call_handler(btc_msg_t *msg)
1107 {
1108 btc_hf_args_t *arg = (btc_hf_args_t *)(msg->arg);
1109
1110 switch (msg->act) {
1111 case BTC_HF_INIT_EVT:
1112 {
1113 btc_hf_init();
1114 break;
1115 }
1116
1117 case BTC_HF_DEINIT_EVT:
1118 {
1119 btc_hf_deinit();
1120 break;
1121 }
1122
1123 case BTC_HF_CONNECT_EVT:
1124 {
1125 btc_hf_connect(&arg->connect);
1126 break;
1127 }
1128
1129 case BTC_HF_DISCONNECT_EVT:
1130 {
1131 btc_hf_disconnect(&arg->disconnect);
1132 break;
1133 }
1134
1135 case BTC_HF_CONNECT_AUDIO_EVT:
1136 {
1137 btc_hf_connect_audio(&arg->connect_audio);
1138 break;
1139 }
1140
1141 case BTC_HF_DISCONNECT_AUDIO_EVT:
1142 {
1143 btc_hf_disconnect_audio(&arg->disconnect_audio);
1144 break;
1145 }
1146
1147 case BTC_HF_VRA_EVT:
1148 {
1149 btc_hf_vra(&arg->vra_rep.remote_addr, arg->vra_rep.value);
1150 if (arg->vra_rep.value) {
1151 btc_hf_connect_audio(&arg->vra_rep.remote_addr);
1152 } else {
1153 btc_hf_disconnect_audio(&arg->vra_rep.remote_addr);
1154 }
1155 break;
1156 }
1157
1158 case BTC_HF_VOLUME_CONTROL_EVT:
1159 {
1160 btc_hf_volume_control(&arg->volcon.remote_addr, arg->volcon.target_type, arg->volcon.volume);
1161 break;
1162 }
1163
1164 case BTC_HF_UNAT_RESPONSE_EVT:
1165 {
1166 btc_hf_unat_response(&arg->unat_rep.remote_addr, arg->unat_rep.unat);
1167 break;
1168 }
1169
1170 case BTC_HF_CME_ERR_EVT:
1171 {
1172 btc_hf_cmee_response(&arg->ext_at.remote_addr, arg->ext_at.response_code, arg->ext_at.error_code);
1173 break;
1174 }
1175
1176 case BTC_HF_IND_NOTIFICATION_EVT:
1177 {
1178 btc_hf_indchange_notification(&arg->ind_change.remote_addr,
1179 arg->ind_change.call_state, arg->ind_change.call_setup_state,
1180 arg->ind_change.ntk_state, arg->ind_change.signal);
1181 break;
1182 }
1183
1184 case BTC_HF_CIEV_REPORT_EVT:
1185 {
1186 btc_hf_ciev_report(&arg->ciev_rep.remote_addr, arg->ciev_rep.ind.type, arg->ciev_rep.ind.value);
1187 break;
1188 }
1189
1190 case BTC_HF_CIND_RESPONSE_EVT:
1191 {
1192 btc_hf_cind_response(&arg->cind_rep.remote_addr,
1193 arg->cind_rep.call_state, arg->cind_rep.call_setup_state,
1194 arg->cind_rep.ntk_state, arg->cind_rep.signal, arg->cind_rep.roam, arg->cind_rep.batt_lev,
1195 arg->cind_rep.call_held_state);
1196 break;
1197 }
1198
1199 case BTC_HF_COPS_RESPONSE_EVT:
1200 {
1201 btc_hf_cops_response(&arg->cops_rep.remote_addr, arg->cops_rep.name);
1202 break;
1203 }
1204
1205 case BTC_HF_CLCC_RESPONSE_EVT:
1206 {
1207 btc_hf_clcc_response(&arg->clcc_rep.remote_addr, arg->clcc_rep.index,
1208 arg->clcc_rep.dir, arg->clcc_rep.current_call_state,
1209 arg->clcc_rep.mode, arg->clcc_rep.mpty, arg->clcc_rep.number, arg->clcc_rep.type);
1210 break;
1211 }
1212
1213 case BTC_HF_CNUM_RESPONSE_EVT:
1214 {
1215 btc_hf_cnum_response(&arg->cnum_rep.remote_addr, arg->cnum_rep.number, arg->cnum_rep.number_type, arg->cnum_rep.service_type);
1216 break;
1217 }
1218
1219 case BTC_HF_INBAND_RING_EVT:
1220 {
1221 btc_hf_inband_ring(&arg->bsir.remote_addr, arg->bsir.state);
1222 break;
1223 }
1224
1225 case BTC_HF_AC_INCALL_EVT:
1226 {
1227 btc_hf_phone_state_update(&arg->phone.remote_addr, arg->phone.num_active, arg->phone.num_held,
1228 arg->phone.call_state, arg->phone.call_setup_state, arg->phone.number,
1229 arg->phone.call_addr_type);
1230 break;
1231 }
1232
1233 case BTC_HF_RJ_INCALL_EVT:
1234 {
1235 btc_hf_phone_state_update(&arg->phone.remote_addr, arg->phone.num_active, arg->phone.num_held,
1236 arg->phone.call_state, arg->phone.call_setup_state, arg->phone.number,
1237 arg->phone.call_addr_type);
1238 btc_hf_disconnect_audio(&arg->phone.remote_addr);
1239 break;
1240 }
1241
1242 case BTC_HF_OUT_CALL_EVT:
1243 {
1244 btc_hf_connect_audio(&arg->phone.remote_addr);
1245 btc_hf_phone_state_update(&arg->phone.remote_addr, arg->phone.num_active, arg->phone.num_held,
1246 arg->phone.call_state, arg->phone.call_setup_state, arg->phone.number,
1247 arg->phone.call_addr_type);
1248 break;
1249 }
1250
1251 case BTC_HF_END_CALL_EVT:
1252 {
1253 btc_hf_phone_state_update(&arg->phone.remote_addr, arg->phone.num_active, arg->phone.num_held,
1254 arg->phone.call_state, arg->phone.call_setup_state, arg->phone.number,
1255 arg->phone.call_addr_type);
1256 btc_hf_disconnect_audio(&arg->phone.remote_addr);
1257 break;
1258 }
1259
1260 case BTC_HF_REGISTER_DATA_CALLBACK_EVT:
1261 {
1262 btc_hf_reg_data_cb(arg->reg_data_cb.recv, arg->reg_data_cb.send);
1263 break;
1264 }
1265 case BTC_HF_REQUEST_PKT_STAT_EVT:
1266 {
1267 btc_hf_pkt_stat_nums_get(arg->pkt_sync_hd.sync_conn_handle);
1268 break;
1269 }
1270
1271 default:
1272 BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
1273 }
1274 btc_hf_arg_deep_free(msg);
1275 }
1276
btc_hf_cb_handler(btc_msg_t * msg)1277 void btc_hf_cb_handler(btc_msg_t *msg)
1278 {
1279 uint16_t event = msg->act;
1280 tBTA_AG *p_data = (tBTA_AG *)msg->arg;
1281 esp_hf_cb_param_t param;
1282 bdstr_t bdstr;
1283 int idx = BTC_HF_INVALID_IDX;
1284
1285 BTC_TRACE_DEBUG("%s: event = %s", __FUNCTION__, dump_hf_event(event));
1286
1287 memset(¶m, 0, sizeof(esp_hf_cb_param_t));
1288
1289 switch (event) {
1290 case BTA_AG_ENABLE_EVT:
1291 break;
1292 case BTA_AG_DISABLE_EVT:
1293 {
1294 idx = 0;
1295 #if HFP_DYNAMIC_MEMORY == TRUE
1296 if (hf_local_param)
1297 #endif
1298 {
1299 if (hf_local_param[idx].btc_hf_cb.initialized) {
1300 hf_local_param[idx].btc_hf_cb.initialized = false;
1301 btc_hf_cb_release();
1302 param.prof_stat.state = ESP_HF_DEINIT_SUCCESS;
1303 btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, ¶m);
1304 }
1305 }
1306 break;
1307 }
1308 case BTA_AG_REGISTER_EVT:
1309 {
1310 idx = p_data->hdr.handle - 1;
1311 CHECK_HF_IDX(idx);
1312 hf_local_param[idx].btc_hf_cb.handle = p_data->reg.hdr.handle;
1313 BTC_TRACE_DEBUG("%s: BTA_AG_REGISTER_EVT," "hf_local_param[%d].btc_hf_cb.handle = %d",
1314 __FUNCTION__, idx, hf_local_param[idx].btc_hf_cb.handle);
1315 if (!hf_local_param[idx].btc_hf_cb.initialized) {
1316 param.prof_stat.state = ESP_HF_INIT_SUCCESS;
1317 btc_hf_cb_to_app(ESP_HF_PROF_STATE_EVT, ¶m);
1318 }
1319 hf_local_param[idx].btc_hf_cb.initialized = true;
1320 break;
1321 }
1322
1323 case BTA_AG_OPEN_EVT:
1324 {
1325 idx = p_data->hdr.handle - 1;
1326 CHECK_HF_IDX(idx);
1327 if (p_data->open.hdr.status == BTA_AG_SUCCESS)
1328 {
1329 bdcpy(hf_local_param[idx].btc_hf_cb.connected_bda.address, p_data->open.bd_addr);
1330 hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_CONNECTED;
1331 hf_local_param[idx].btc_hf_cb.peer_feat = 0;
1332 hf_local_param[idx].btc_hf_cb.chld_feat = 0;
1333 //clear_phone_state();
1334 } else if (hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_CONNECTING) {
1335 hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_DISCONNECTED;
1336 } else {
1337 BTC_TRACE_WARNING("%s: AG open failed, but another device connected. status=%d state=%d connected device=%s", __FUNCTION__,
1338 p_data->open.hdr.status, hf_local_param[idx].btc_hf_cb.connection_state,
1339 bdaddr_to_string(&hf_local_param[idx].btc_hf_cb.connected_bda, bdstr, sizeof(bdstr)));
1340 break;
1341 }
1342
1343 do {
1344 memcpy(param.conn_stat.remote_bda, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t));
1345 param.conn_stat.state = hf_local_param[idx].btc_hf_cb.connection_state;
1346 param.conn_stat.peer_feat = 0;
1347 param.conn_stat.chld_feat = 0;
1348 btc_hf_cb_to_app(ESP_HF_CONNECTION_STATE_EVT, ¶m);
1349 } while (0);
1350
1351 if (hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_DISCONNECTED)
1352 bdsetany(hf_local_param[idx].btc_hf_cb.connected_bda.address);
1353
1354 if (p_data->open.hdr.status != BTA_AG_SUCCESS)
1355 btc_queue_advance();
1356 break;
1357 }
1358
1359 case BTA_AG_CONN_EVT:
1360 {
1361 idx = p_data->hdr.handle - 1;
1362 CHECK_HF_IDX(idx);
1363 clock_gettime(CLOCK_MONOTONIC, &(hf_local_param[idx].btc_hf_cb.connected_timestamp));
1364 BTC_TRACE_DEBUG("%s: BTA_AG_CONN_EVT, idx = %d ", __FUNCTION__, idx);
1365 hf_local_param[idx].btc_hf_cb.peer_feat = p_data->conn.peer_feat;
1366 hf_local_param[idx].btc_hf_cb.chld_feat = p_data->conn.chld_feat;
1367 hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_SLC_CONNECTED;
1368
1369 do {
1370 param.conn_stat.state = hf_local_param[idx].btc_hf_cb.connection_state;
1371 param.conn_stat.peer_feat = hf_local_param[idx].btc_hf_cb.peer_feat;
1372 param.conn_stat.chld_feat = hf_local_param[idx].btc_hf_cb.chld_feat;
1373 memcpy(param.conn_stat.remote_bda, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t));
1374 btc_hf_cb_to_app(ESP_HF_CONNECTION_STATE_EVT, ¶m);
1375 } while(0);
1376 hf_local_param[idx].hf_idx = btc_hf_latest_connected_idx();
1377 btc_queue_advance();
1378 break;
1379 }
1380
1381 case BTA_AG_CLOSE_EVT:
1382 {
1383 idx = p_data->hdr.handle - 1;
1384 CHECK_HF_IDX(idx);
1385 hf_local_param[idx].btc_hf_cb.connected_timestamp.tv_sec = 0;
1386 hf_local_param[idx].btc_hf_cb.connection_state = ESP_HF_CONNECTION_STATE_DISCONNECTED;
1387 BTC_TRACE_DEBUG("%s: BTA_AG_CLOSE_EVT," "hf_local_param[%d].btc_hf_cb.handle = %d", __FUNCTION__,
1388 idx, hf_local_param[idx].btc_hf_cb.handle);
1389 do {
1390 param.conn_stat.state = ESP_HF_CONNECTION_STATE_DISCONNECTED;
1391 param.conn_stat.peer_feat = 0;
1392 param.conn_stat.chld_feat = 0;
1393 memcpy(param.conn_stat.remote_bda, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t));
1394 btc_hf_cb_to_app(ESP_HF_CONNECTION_STATE_EVT, ¶m);
1395 } while(0);
1396 bdsetany(hf_local_param[idx].btc_hf_cb.connected_bda.address);
1397 clear_phone_state();
1398 hf_local_param[idx].hf_idx = btc_hf_latest_connected_idx();
1399 btc_queue_advance();
1400 break;
1401 }
1402
1403 case BTA_AG_AUDIO_OPEN_EVT:
1404 {
1405 idx = p_data->hdr.handle - 1;
1406 CHECK_HF_IDX(idx);
1407 do {
1408 param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED;
1409 memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1410 param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
1411 btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m);
1412 } while(0);
1413 break;
1414 }
1415
1416 case BTA_AG_AUDIO_MSBC_OPEN_EVT:
1417 {
1418 idx = p_data->hdr.handle - 1;
1419 CHECK_HF_IDX(idx);
1420 do {
1421 param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED_MSBC;
1422 memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1423 param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
1424 btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m);
1425 } while (0);
1426 break;
1427 }
1428 case BTA_AG_AUDIO_CLOSE_EVT:
1429 {
1430 idx = p_data->hdr.handle - 1;
1431 CHECK_HF_IDX(idx);
1432 do {
1433 param.audio_stat.state = ESP_HF_AUDIO_STATE_DISCONNECTED;
1434 memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t));
1435 param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle;
1436 btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m);
1437 } while(0);
1438 break;
1439 }
1440
1441 case BTA_AG_AT_BVRA_EVT:
1442 {
1443 idx = p_data->hdr.handle - 1;
1444 CHECK_HF_IDX(idx);
1445 do {
1446 param.vra_rep.value = p_data->val.num;
1447 memcpy(param.vra_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1448 btc_hf_cb_to_app(ESP_HF_BVRA_RESPONSE_EVT, ¶m);
1449 if (p_data->val.num) {
1450 btc_hf_connect_audio(&hf_local_param[idx].btc_hf_cb.connected_bda);
1451 } else {
1452 btc_hf_disconnect_audio(&hf_local_param[idx].btc_hf_cb.connected_bda);
1453 }
1454 } while (0);
1455 break;
1456 }
1457
1458 case BTA_AG_SPK_EVT:
1459 case BTA_AG_MIC_EVT:
1460 {
1461 idx = p_data->hdr.handle - 1;
1462 CHECK_HF_IDX(idx);
1463 do {
1464 memcpy(param.volume_control.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1465 param.volume_control.type = (event == BTA_AG_SPK_EVT) ? ESP_HF_VOLUME_CONTROL_TARGET_SPK : ESP_HF_VOLUME_CONTROL_TARGET_MIC;
1466 param.volume_control.volume = p_data->val.num;
1467 btc_hf_cb_to_app(ESP_HF_VOLUME_CONTROL_EVT, ¶m);
1468 } while (0);
1469 break;
1470 }
1471
1472 case BTA_AG_AT_UNAT_EVT:
1473 {
1474 idx = p_data->hdr.handle - 1;
1475 CHECK_HF_IDX(idx);
1476 do {
1477 memcpy(param.unat_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1478 param.unat_rep.unat = p_data->val.str;
1479 btc_hf_cb_to_app(ESP_HF_UNAT_RESPONSE_EVT, ¶m);
1480 } while (0);
1481 break;
1482 }
1483
1484 case BTA_AG_AT_CBC_EVT:
1485 {
1486 idx = p_data->hdr.handle - 1;
1487 CHECK_HF_IDX(idx);
1488 memcpy(param.ind_upd.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1489 btc_hf_cb_to_app(ESP_HF_IND_UPDATE_EVT, ¶m);
1490 break;
1491 }
1492
1493 case BTA_AG_AT_CIND_EVT:
1494 {
1495 idx = p_data->hdr.handle - 1;
1496 CHECK_HF_IDX(idx);
1497 memcpy(param.cind_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1498 btc_hf_cb_to_app(ESP_HF_CIND_RESPONSE_EVT, ¶m);
1499 break;
1500 }
1501
1502 case BTA_AG_AT_COPS_EVT:
1503 {
1504 idx = p_data->hdr.handle - 1;
1505 CHECK_HF_IDX(idx);
1506 memcpy(param.cops_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1507 btc_hf_cb_to_app(ESP_HF_COPS_RESPONSE_EVT, ¶m);
1508 break;
1509 }
1510
1511 case BTA_AG_AT_CLCC_EVT:
1512 {
1513 idx = p_data->hdr.handle - 1;
1514 CHECK_HF_IDX(idx);
1515 memcpy(param.clcc_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1516 btc_hf_cb_to_app(ESP_HF_CLCC_RESPONSE_EVT, ¶m);
1517 break;
1518 }
1519
1520 case BTA_AG_AT_CNUM_EVT:
1521 {
1522 idx = p_data->hdr.handle - 1;
1523 CHECK_HF_IDX(idx);
1524 memcpy(param.cnum_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1525 btc_hf_cb_to_app(ESP_HF_CNUM_RESPONSE_EVT, ¶m);
1526 break;
1527 }
1528
1529 case BTA_AG_AT_VTS_EVT:
1530 {
1531 idx = p_data->hdr.handle - 1;
1532 CHECK_HF_IDX(idx);
1533 do {
1534 memcpy(param.vts_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1535 param.vts_rep.code = p_data->val.str;
1536 btc_hf_cb_to_app(ESP_HF_VTS_RESPONSE_EVT, ¶m);
1537 } while(0);
1538 break;
1539 }
1540
1541 case BTA_AG_AT_NREC_EVT:
1542 {
1543 idx = p_data->hdr.handle - 1;
1544 CHECK_HF_IDX(idx);
1545 do {
1546 memcpy(param.nrec.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1547 param.nrec.state = p_data->val.num;
1548 btc_hf_cb_to_app(ESP_HF_NREC_RESPONSE_EVT, ¶m);
1549 } while(0);
1550 break;
1551 }
1552
1553 case BTA_AG_AT_A_EVT:
1554 {
1555 idx = p_data->hdr.handle - 1;
1556 CHECK_HF_IDX(idx);
1557 memcpy(param.ata_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1558 btc_hf_cb_to_app(ESP_HF_ATA_RESPONSE_EVT, ¶m);
1559 break;
1560 }
1561
1562 case BTA_AG_AT_CHUP_EVT:
1563 {
1564 idx = p_data->hdr.handle - 1;
1565 CHECK_HF_IDX(idx);
1566 memcpy(param.chup_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1567 btc_hf_cb_to_app(ESP_HF_CHUP_RESPONSE_EVT, ¶m);
1568 break;
1569 }
1570
1571 case BTA_AG_AT_BLDN_EVT:
1572 case BTA_AG_AT_D_EVT:
1573 {
1574 idx = p_data->hdr.handle - 1;
1575 CHECK_HF_IDX(idx);
1576 do {
1577 if (event == BTA_AG_AT_D_EVT) { // dial_number_or_memory
1578 memcpy(param.out_call.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1579 param.out_call.type = p_data->val.value;
1580 param.out_call.num_or_loc = osi_malloc((strlen(p_data->val.str) + 1) * sizeof(char));
1581 sprintf(param.out_call.num_or_loc, "%s", p_data->val.str);
1582 btc_hf_cb_to_app(ESP_HF_DIAL_EVT, ¶m);
1583 osi_free(param.out_call.num_or_loc);
1584 } else if (event == BTA_AG_AT_BLDN_EVT) { //dial_last
1585 memcpy(param.out_call.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1586 param.out_call.num_or_loc = NULL;
1587 btc_hf_cb_to_app(ESP_HF_DIAL_EVT, ¶m);
1588 }
1589 } while(0);
1590 break;
1591 }
1592
1593 case BTA_AG_AT_BINP_EVT:
1594 case BTA_AG_AT_BTRH_EVT:
1595 {
1596 idx = p_data->hdr.handle - 1;
1597 CHECK_HF_IDX(idx);
1598 tBTA_AG_RES_DATA ag_res;
1599 memset(&ag_res, 0, sizeof(ag_res));
1600 ag_res.ok_flag = BTA_AG_OK_ERROR;
1601 ag_res.errcode = BTA_AG_ERR_OP_NOT_SUPPORTED;
1602 BTA_AgResult(hf_local_param[idx].btc_hf_cb.handle, BTA_AG_UNAT_RES, &ag_res);
1603 break;
1604 }
1605
1606 case BTA_AG_AT_BAC_EVT:
1607 {
1608 idx = p_data->hdr.handle - 1;
1609 CHECK_HF_IDX(idx);
1610 BTC_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
1611 #if (BTM_WBS_INCLUDED == TRUE)
1612 /* If the peer supports mSBC and the BTC preferred codec is also mSBC, then
1613 ** we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC at the time
1614 ** of SCO connection establishment */
1615 if ((btc_conf_hf_force_wbs == TRUE) && (p_data->val.num & BTA_AG_CODEC_MSBC)) {
1616 BTC_TRACE_DEBUG("%s btc_hf override-Preferred Codec to MSBC", __FUNCTION__);
1617 BTA_AgSetCodec(hf_local_param[idx].btc_hf_cb.handle,BTA_AG_CODEC_MSBC);
1618 }
1619 else {
1620 BTC_TRACE_DEBUG("%s btc_hf override-Preferred Codec to CVSD", __FUNCTION__);
1621 BTA_AgSetCodec(hf_local_param[idx].btc_hf_cb.handle,BTA_AG_CODEC_CVSD);
1622 }
1623 #endif
1624 break;
1625 }
1626 #if (BTM_WBS_INCLUDED == TRUE)
1627 case BTA_AG_WBS_EVT:
1628 {
1629 idx = p_data->hdr.handle - 1;
1630 CHECK_HF_IDX(idx);
1631 do {
1632 BTC_TRACE_DEBUG("Set codec status %d codec %d 1=CVSD 2=MSBC", p_data->val.hdr.status, p_data->val.num);
1633 memcpy(param.wbs_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1634 param.wbs_rep.codec = p_data->val.num;
1635 btc_hf_cb_to_app(ESP_HF_WBS_RESPONSE_EVT, ¶m);
1636 } while (0);
1637 break;
1638 }
1639
1640 case BTA_AG_AT_BCS_EVT:
1641 {
1642 idx = p_data->hdr.handle - 1;
1643 CHECK_HF_IDX(idx);
1644 do {
1645 BTC_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num);
1646 memcpy(param.bcs_rep.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t));
1647 param.bcs_rep.mode = p_data->val.num;
1648 /* No ESP_HF_WBS_NONE case, because HFP 1.6 supported device can send BCS */
1649 btc_hf_cb_to_app(ESP_HF_BCS_RESPONSE_EVT, ¶m);
1650 } while (0);
1651 break;
1652 }
1653 #endif
1654 case BTA_AG_PKT_NUMS_GET_EVT:
1655 {
1656 memcpy(¶m.pkt_nums, &p_data->pkt_num, sizeof(struct ag_pkt_status_nums));
1657 btc_hf_cb_to_app(ESP_HF_PKT_STAT_NUMS_GET_EVT, ¶m);
1658 break;
1659 }
1660 default:
1661 BTC_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
1662 break;
1663 }
1664 }
1665 #endif // #if (BTC_HF_INCLUDED == TRUE)
1666