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