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, &param);
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, &param);
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(&param, 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, &param);
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(&param, 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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
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, &param);
1650             } while (0);
1651             break;
1652         }
1653 #endif
1654         case BTA_AG_PKT_NUMS_GET_EVT:
1655         {
1656             memcpy(&param.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, &param);
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