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: btif_hf.c
22 *
23 * Description: Handsfree Profile Bluetooth Interface
24 *
25 *
26 ***********************************************************************************/
27
28 #include <hardware/bluetooth.h>
29 #include <hardware/bt_hf.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #define LOG_TAG "bt_btif_hf"
34 #include "btif_common.h"
35 #include "btif_util.h"
36 #include "btif_profile_queue.h"
37
38 #include "btcore/include/bdaddr.h"
39 #include "bta_ag_api.h"
40
41 /************************************************************************************
42 ** Constants & Macros
43 ************************************************************************************/
44 #ifndef BTIF_HSAG_SERVICE_NAME
45 #define BTIF_HSAG_SERVICE_NAME ("Headset Gateway")
46 #endif
47
48 #ifndef BTIF_HFAG_SERVICE_NAME
49 #define BTIF_HFAG_SERVICE_NAME ("Handsfree Gateway")
50 #endif
51
52 #ifndef BTIF_HF_SERVICES
53 #define BTIF_HF_SERVICES (BTA_HSP_SERVICE_MASK | BTA_HFP_SERVICE_MASK )
54 #endif
55
56 #ifndef BTIF_HF_SERVICE_NAMES
57 #define BTIF_HF_SERVICE_NAMES {BTIF_HSAG_SERVICE_NAME , BTIF_HFAG_SERVICE_NAME}
58 #endif
59
60 #ifndef BTIF_HF_SECURITY
61 #define BTIF_HF_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
62 #endif
63
64 #if (BTM_WBS_INCLUDED == TRUE )
65 #ifndef BTIF_HF_FEATURES
66 #define BTIF_HF_FEATURES ( BTA_AG_FEAT_3WAY | \
67 BTA_AG_FEAT_ECNR | \
68 BTA_AG_FEAT_REJECT | \
69 BTA_AG_FEAT_ECS | \
70 BTA_AG_FEAT_EXTERR | \
71 BTA_AG_FEAT_BTRH | \
72 BTA_AG_FEAT_VREC | \
73 BTA_AG_FEAT_CODEC |\
74 BTA_AG_FEAT_UNAT)
75 #endif
76 #else
77 #ifndef BTIF_HF_FEATURES
78 #define BTIF_HF_FEATURES ( BTA_AG_FEAT_3WAY | \
79 BTA_AG_FEAT_ECNR | \
80 BTA_AG_FEAT_REJECT | \
81 BTA_AG_FEAT_ECS | \
82 BTA_AG_FEAT_EXTERR | \
83 BTA_AG_FEAT_BTRH | \
84 BTA_AG_FEAT_VREC | \
85 BTA_AG_FEAT_UNAT)
86 #endif
87 #endif
88
89 #define BTIF_HF_CALL_END_TIMEOUT 6
90
91 #define BTIF_HF_INVALID_IDX -1
92
93 /* Number of BTIF-HF control blocks */
94 #define BTIF_HF_NUM_CB 2
95
96 /* Max HF clients supported from App */
97 UINT16 btif_max_hf_clients = 1;
98
99 /* HF app ids for service registration */
100 typedef enum {
101 BTIF_HF_ID_1 = 0,
102 BTIF_HF_ID_2,
103 #if (BTIF_HF_NUM_CB == 3)
104 BTIF_HF_ID_3
105 #endif
106 } bthf_hf_id_t;
107
108 UINT16 bthf_hf_id[BTIF_HF_NUM_CB] = {BTIF_HF_ID_1, BTIF_HF_ID_2,
109 #if (BTIF_HF_NUM_CB == 3)
110 BTIF_HF_ID_3
111 #endif
112 };
113
114 /************************************************************************************
115 ** Local type definitions
116 ************************************************************************************/
117
118 /************************************************************************************
119 ** Static variables
120 ************************************************************************************/
121 static bthf_callbacks_t *bt_hf_callbacks = NULL;
122 static int hf_idx = BTIF_HF_INVALID_IDX;
123
124 #define CHECK_BTHF_INIT() if (bt_hf_callbacks == NULL)\
125 {\
126 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);\
127 return BT_STATUS_NOT_READY;\
128 }\
129 else\
130 {\
131 BTIF_TRACE_EVENT("BTHF: %s", __FUNCTION__);\
132 }
133
134 #define CHECK_BTHF_SLC_CONNECTED() if (bt_hf_callbacks == NULL)\
135 {\
136 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);\
137 return BT_STATUS_NOT_READY;\
138 }\
139 else if (btif_hf_cb.state != BTHF_CONNECTION_STATE_SLC_CONNECTED)\
140 {\
141 BTIF_TRACE_WARNING("BTHF: %s: SLC connection not up. state=%s", __FUNCTION__, dump_hf_conn_state(btif_hf_cb.state));\
142 return BT_STATUS_NOT_READY;\
143 }\
144 else\
145 {\
146 BTIF_TRACE_EVENT("BTHF: %s", __FUNCTION__);\
147 }
148
149 /* BTIF-HF control block to map bdaddr to BTA handle */
150 typedef struct _btif_hf_cb
151 {
152 UINT16 handle;
153 bt_bdaddr_t connected_bda;
154 bthf_connection_state_t state;
155 bthf_vr_state_t vr_state;
156 tBTA_AG_PEER_FEAT peer_feat;
157 int num_active;
158 int num_held;
159 struct timespec call_end_timestamp;
160 struct timespec connected_timestamp;
161 bthf_call_state_t call_setup_state;
162 } btif_hf_cb_t;
163
164 static btif_hf_cb_t btif_hf_cb[BTIF_HF_NUM_CB];
165
166
167 /************************************************************************************
168 ** Static functions
169 ************************************************************************************/
170
171 /************************************************************************************
172 ** Externs
173 ************************************************************************************/
174 /* By default, even though codec negotiation is enabled, we will not use WBS as the default
175 * codec unless this variable is set to TRUE.
176 */
177 #ifndef BTIF_HF_WBS_PREFERRED
178 #define BTIF_HF_WBS_PREFERRED FALSE
179 #endif
180
181 BOOLEAN btif_conf_hf_force_wbs = BTIF_HF_WBS_PREFERRED;
182
183 /************************************************************************************
184 ** Functions
185 ************************************************************************************/
186
187 /*******************************************************************************
188 **
189 ** Function is_connected
190 **
191 ** Description Internal function to check if HF is connected
192 **
193 ** Returns TRUE if connected
194 **
195 *******************************************************************************/
is_connected(bt_bdaddr_t * bd_addr)196 static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
197 {
198 int i;
199 for (i = 0; i < btif_max_hf_clients; ++i)
200 {
201 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
202 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)) &&
203 ((bd_addr == NULL) || (bdcmp(bd_addr->address,
204 btif_hf_cb[i].connected_bda.address) == 0)))
205 return TRUE;
206 }
207 return FALSE;
208 }
209
210 /*******************************************************************************
211 **
212 ** Function btif_hf_idx_by_bdaddr
213 **
214 ** Description Internal function to get idx by bdaddr
215 **
216 ** Returns idx
217 **
218 *******************************************************************************/
btif_hf_idx_by_bdaddr(bt_bdaddr_t * bd_addr)219 static int btif_hf_idx_by_bdaddr(bt_bdaddr_t *bd_addr)
220 {
221 int i;
222 for (i = 0; i < btif_max_hf_clients; ++i)
223 {
224 if ((bdcmp(bd_addr->address,
225 btif_hf_cb[i].connected_bda.address) == 0))
226 return i;
227 }
228 return BTIF_HF_INVALID_IDX;
229 }
230
231 /*******************************************************************************
232 **
233 ** Function callstate_to_callsetup
234 **
235 ** Description Converts HAL call state to BTA call setup indicator value
236 **
237 ** Returns BTA call indicator value
238 **
239 *******************************************************************************/
callstate_to_callsetup(bthf_call_state_t call_state)240 static UINT8 callstate_to_callsetup(bthf_call_state_t call_state)
241 {
242 UINT8 call_setup = 0;
243 if (call_state == BTHF_CALL_STATE_INCOMING)
244 call_setup = 1;
245 if (call_state == BTHF_CALL_STATE_DIALING)
246 call_setup = 2;
247 if (call_state == BTHF_CALL_STATE_ALERTING)
248 call_setup = 3;
249
250 return call_setup;
251 }
252
253 /*******************************************************************************
254 **
255 ** Function send_at_result
256 **
257 ** Description Send AT result code (OK/ERROR)
258 **
259 ** Returns void
260 **
261 *******************************************************************************/
send_at_result(UINT8 ok_flag,UINT16 errcode,int idx)262 static void send_at_result(UINT8 ok_flag, UINT16 errcode, int idx)
263 {
264 tBTA_AG_RES_DATA ag_res;
265 memset (&ag_res, 0, sizeof (ag_res));
266
267 ag_res.ok_flag = ok_flag;
268 if (ok_flag == BTA_AG_OK_ERROR)
269 {
270 ag_res.errcode = errcode;
271 }
272
273 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
274 }
275
276 /*******************************************************************************
277 **
278 ** Function send_indicator_update
279 **
280 ** Description Send indicator update (CIEV)
281 **
282 ** Returns void
283 **
284 *******************************************************************************/
send_indicator_update(UINT16 indicator,UINT16 value)285 static void send_indicator_update (UINT16 indicator, UINT16 value)
286 {
287 tBTA_AG_RES_DATA ag_res;
288
289 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
290 ag_res.ind.id = indicator;
291 ag_res.ind.value = value;
292
293 BTA_AgResult(BTA_AG_HANDLE_ALL, BTA_AG_IND_RES, &ag_res);
294 }
295
clear_phone_state_multihf(int idx)296 void clear_phone_state_multihf(int idx)
297 {
298 btif_hf_cb[idx].call_setup_state = BTHF_CALL_STATE_IDLE;
299 btif_hf_cb[idx].num_active = btif_hf_cb[idx].num_held = 0;
300 }
301
302 /*******************************************************************************
303 **
304 ** Function btif_hf_latest_connected_idx
305 **
306 ** Description Returns idx for latest connected HF
307 **
308 ** Returns int
309 **
310 *******************************************************************************/
btif_hf_latest_connected_idx()311 static int btif_hf_latest_connected_idx()
312 {
313 struct timespec now, conn_time_delta;
314 int latest_conn_idx = BTIF_HF_INVALID_IDX, i;
315
316 clock_gettime(CLOCK_MONOTONIC, &now);
317 conn_time_delta.tv_sec = now.tv_sec;
318
319 for (i = 0; i < btif_max_hf_clients; i++)
320 {
321 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)
322 {
323 if ((now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec)
324 < conn_time_delta.tv_sec)
325 {
326 conn_time_delta.tv_sec =
327 now.tv_sec - btif_hf_cb[i].connected_timestamp.tv_sec;
328 latest_conn_idx = i;
329 }
330 }
331 }
332 return latest_conn_idx;
333 }
334
335 /*******************************************************************************
336 **
337 ** Function btif_hf_check_if_slc_connected
338 **
339 ** Description Returns BT_STATUS_SUCCESS if SLC is up for any HF
340 **
341 ** Returns bt_status_t
342 **
343 *******************************************************************************/
btif_hf_check_if_slc_connected()344 static bt_status_t btif_hf_check_if_slc_connected()
345 {
346 if (bt_hf_callbacks == NULL)
347 {
348 BTIF_TRACE_WARNING("BTHF: %s: BTHF not initialized", __FUNCTION__);
349 return BT_STATUS_NOT_READY;
350 }
351 else
352 {
353 int i;
354 for (i = 0; i < btif_max_hf_clients; i++)
355 {
356 if (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)
357 {
358 BTIF_TRACE_EVENT("BTHF: %s: slc connected for idx = %d",
359 __FUNCTION__, i);
360 return BT_STATUS_SUCCESS;
361 }
362 }
363 BTIF_TRACE_WARNING("BTHF: %s: No SLC connection up", __FUNCTION__);
364 return BT_STATUS_NOT_READY;
365 }
366 }
367
368 /*****************************************************************************
369 ** Section name (Group of functions)
370 *****************************************************************************/
371
372 /*****************************************************************************
373 **
374 ** btif hf api functions (no context switch)
375 **
376 *****************************************************************************/
377
378
379 /*******************************************************************************
380 **
381 ** Function btif_hf_upstreams_evt
382 **
383 ** Description Executes HF UPSTREAMS events in btif context
384 **
385 ** Returns void
386 **
387 *******************************************************************************/
btif_hf_upstreams_evt(UINT16 event,char * p_param)388 static void btif_hf_upstreams_evt(UINT16 event, char* p_param)
389 {
390 tBTA_AG *p_data = (tBTA_AG *)p_param;
391 bdstr_t bdstr;
392 int idx = p_data->hdr.handle - 1;
393
394 BTIF_TRACE_DEBUG("%s: event=%s", __FUNCTION__, dump_hf_event(event));
395
396 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
397 {
398 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
399 return;
400 }
401
402 switch (event)
403 {
404 case BTA_AG_ENABLE_EVT:
405 case BTA_AG_DISABLE_EVT:
406 break;
407
408 case BTA_AG_REGISTER_EVT:
409 btif_hf_cb[idx].handle = p_data->reg.hdr.handle;
410 BTIF_TRACE_DEBUG("%s: BTA_AG_REGISTER_EVT,"
411 "btif_hf_cb.handle = %d", __FUNCTION__, btif_hf_cb[idx].handle);
412 break;
413
414 case BTA_AG_OPEN_EVT:
415 if (p_data->open.status == BTA_AG_SUCCESS)
416 {
417 bdcpy(btif_hf_cb[idx].connected_bda.address,
418 p_data->open.bd_addr);
419 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_CONNECTED;
420 btif_hf_cb[idx].peer_feat = 0;
421 clear_phone_state_multihf(idx);
422 }
423 else if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_CONNECTING)
424 {
425 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
426 }
427 else
428 {
429 BTIF_TRACE_WARNING("%s: AG open failed, but another device connected. status=%d state=%d connected device=%s",
430 __FUNCTION__, p_data->open.status, btif_hf_cb[idx].state,
431 bdaddr_to_string(&btif_hf_cb[idx].connected_bda, bdstr, sizeof(bdstr)));
432 break;
433 }
434
435 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
436 &btif_hf_cb[idx].connected_bda);
437
438 if (btif_hf_cb[idx].state == BTHF_CONNECTION_STATE_DISCONNECTED)
439 bdsetany(btif_hf_cb[idx].connected_bda.address);
440
441 if (p_data->open.status != BTA_AG_SUCCESS)
442 btif_queue_advance();
443 break;
444
445 case BTA_AG_CLOSE_EVT:
446 btif_hf_cb[idx].connected_timestamp.tv_sec = 0;
447 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_DISCONNECTED;
448 BTIF_TRACE_DEBUG("%s: BTA_AG_CLOSE_EVT,"
449 "idx = %d, btif_hf_cb.handle = %d", __FUNCTION__, idx,
450 btif_hf_cb[idx].handle);
451 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
452 &btif_hf_cb[idx].connected_bda);
453 bdsetany(btif_hf_cb[idx].connected_bda.address);
454 btif_hf_cb[idx].peer_feat = 0;
455 clear_phone_state_multihf(idx);
456 hf_idx = btif_hf_latest_connected_idx();
457 /* If AG_OPEN was received but SLC was not setup in a specified time (10 seconds),
458 ** then AG_CLOSE may be received. We need to advance the queue here
459 */
460 btif_queue_advance();
461 break;
462
463 case BTA_AG_CONN_EVT:
464 clock_gettime(CLOCK_MONOTONIC,
465 &btif_hf_cb[idx].connected_timestamp);
466 BTIF_TRACE_DEBUG("%s: BTA_AG_CONN_EVT, idx = %d ",
467 __FUNCTION__, idx);
468 btif_hf_cb[idx].peer_feat = p_data->conn.peer_feat;
469 btif_hf_cb[idx].state = BTHF_CONNECTION_STATE_SLC_CONNECTED;
470 hf_idx = btif_hf_latest_connected_idx();
471
472 HAL_CBACK(bt_hf_callbacks, connection_state_cb, btif_hf_cb[idx].state,
473 &btif_hf_cb[idx].connected_bda);
474 btif_queue_advance();
475 break;
476
477 case BTA_AG_AUDIO_OPEN_EVT:
478 hf_idx = idx;
479 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTED,
480 &btif_hf_cb[idx].connected_bda);
481 break;
482
483 case BTA_AG_AUDIO_CLOSE_EVT:
484 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_DISCONNECTED,
485 &btif_hf_cb[idx].connected_bda);
486 break;
487
488 /* BTA auto-responds, silently discard */
489 case BTA_AG_SPK_EVT:
490 case BTA_AG_MIC_EVT:
491 HAL_CBACK(bt_hf_callbacks, volume_cmd_cb,
492 (event == BTA_AG_SPK_EVT) ? BTHF_VOLUME_TYPE_SPK :
493 BTHF_VOLUME_TYPE_MIC, p_data->val.num,
494 &btif_hf_cb[idx].connected_bda);
495 break;
496
497 case BTA_AG_AT_A_EVT:
498 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
499 hf_idx = idx;
500 else
501 BTIF_TRACE_DEBUG("Donot set hf_idx for ATA since already in a call");
502
503 HAL_CBACK(bt_hf_callbacks, answer_call_cmd_cb,
504 &btif_hf_cb[idx].connected_bda);
505 break;
506
507 /* Java needs to send OK/ERROR for these commands */
508 case BTA_AG_AT_BLDN_EVT:
509 case BTA_AG_AT_D_EVT:
510 if ((btif_hf_cb[0].num_held + btif_hf_cb[0].num_active) == 0)
511 hf_idx = idx;
512 else
513 BTIF_TRACE_DEBUG("Donot set hf_idx for BLDN/D since already in a call");
514
515 HAL_CBACK(bt_hf_callbacks, dial_call_cmd_cb,
516 (event == BTA_AG_AT_D_EVT) ? p_data->val.str : NULL,
517 &btif_hf_cb[idx].connected_bda);
518 break;
519
520 case BTA_AG_AT_CHUP_EVT:
521 HAL_CBACK(bt_hf_callbacks, hangup_call_cmd_cb,
522 &btif_hf_cb[idx].connected_bda);
523 break;
524
525 case BTA_AG_AT_CIND_EVT:
526 HAL_CBACK(bt_hf_callbacks, cind_cmd_cb,
527 &btif_hf_cb[idx].connected_bda);
528 break;
529
530 case BTA_AG_AT_VTS_EVT:
531 HAL_CBACK(bt_hf_callbacks, dtmf_cmd_cb, p_data->val.str[0],
532 &btif_hf_cb[idx].connected_bda);
533 break;
534
535 case BTA_AG_AT_BVRA_EVT:
536 HAL_CBACK(bt_hf_callbacks, vr_cmd_cb,
537 (p_data->val.num == 1) ? BTHF_VR_STATE_STARTED :
538 BTHF_VR_STATE_STOPPED, &btif_hf_cb[idx].connected_bda);
539 break;
540
541 case BTA_AG_AT_NREC_EVT:
542 HAL_CBACK(bt_hf_callbacks, nrec_cmd_cb,
543 (p_data->val.num == 1) ? BTHF_NREC_START : BTHF_NREC_STOP,
544 &btif_hf_cb[idx].connected_bda);
545 break;
546
547 /* TODO: Add a callback for CBC */
548 case BTA_AG_AT_CBC_EVT:
549 break;
550
551 case BTA_AG_AT_CKPD_EVT:
552 HAL_CBACK(bt_hf_callbacks, key_pressed_cmd_cb,
553 &btif_hf_cb[idx].connected_bda);
554 break;
555
556 #if (BTM_WBS_INCLUDED == TRUE )
557 case BTA_AG_WBS_EVT:
558 BTIF_TRACE_DEBUG("BTA_AG_WBS_EVT Set codec status %d codec %d 1=CVSD 2=MSBC", \
559 p_data->val.hdr.status, p_data->val.num);
560 if(p_data->val.num == BTA_AG_CODEC_CVSD)
561 { HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);}
562 else if(p_data->val.num == BTA_AG_CODEC_MSBC)
563 {HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_YES, &btif_hf_cb[idx].connected_bda);}
564 else
565 {HAL_CBACK(bt_hf_callbacks, wbs_cb, BTHF_WBS_NONE, &btif_hf_cb[idx].connected_bda);}
566 break;
567 #endif
568 /* Java needs to send OK/ERROR for these commands */
569 case BTA_AG_AT_CHLD_EVT:
570 HAL_CBACK(bt_hf_callbacks, chld_cmd_cb, atoi(p_data->val.str),
571 &btif_hf_cb[idx].connected_bda);
572 break;
573
574 case BTA_AG_AT_CLCC_EVT:
575 HAL_CBACK(bt_hf_callbacks, clcc_cmd_cb,
576 &btif_hf_cb[idx].connected_bda);
577 break;
578
579 case BTA_AG_AT_COPS_EVT:
580 HAL_CBACK(bt_hf_callbacks, cops_cmd_cb,
581 &btif_hf_cb[idx].connected_bda);
582 break;
583
584 case BTA_AG_AT_UNAT_EVT:
585 HAL_CBACK(bt_hf_callbacks, unknown_at_cmd_cb, p_data->val.str,
586 &btif_hf_cb[idx].connected_bda);
587 break;
588
589 case BTA_AG_AT_CNUM_EVT:
590 HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb,
591 &btif_hf_cb[idx].connected_bda);
592 break;
593
594 /* TODO: Some of these commands may need to be sent to app. For now respond with error */
595 case BTA_AG_AT_BINP_EVT:
596 case BTA_AG_AT_BTRH_EVT:
597 send_at_result(BTA_AG_OK_ERROR, BTA_AG_ERR_OP_NOT_SUPPORTED, idx);
598 break;
599 case BTA_AG_AT_BAC_EVT:
600 BTIF_TRACE_DEBUG("AG Bitmap of peer-codecs %d", p_data->val.num);
601 #if (BTM_WBS_INCLUDED == TRUE )
602 /* If the peer supports mSBC and the BTIF prefferred codec is also mSBC, then
603 we should set the BTA AG Codec to mSBC. This would trigger a +BCS to mSBC at the time
604 of SCO connection establishment */
605 if ((btif_conf_hf_force_wbs == TRUE) && (p_data->val.num & BTA_AG_CODEC_MSBC))
606 {
607 BTIF_TRACE_EVENT("%s btif_hf override-Preferred Codec to MSBC", __FUNCTION__);
608 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_MSBC);
609 }
610 else
611 {
612 BTIF_TRACE_EVENT("%s btif_hf override-Preferred Codec to CVSD", __FUNCTION__);
613 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_CVSD);
614 }
615 #endif
616 break;
617 case BTA_AG_AT_BCS_EVT:
618 BTIF_TRACE_DEBUG("AG final seleded codec is %d 1=CVSD 2=MSBC", p_data->val.num);
619 /* no BTHF_WBS_NONE case, becuase HF1.6 supported device can send BCS */
620 HAL_CBACK(bt_hf_callbacks, wbs_cb,(p_data->val.num == BTA_AG_CODEC_MSBC) ? \
621 BTHF_WBS_YES : BTHF_WBS_NO, &btif_hf_cb[idx].connected_bda);
622 break;
623
624 default:
625 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
626 break;
627 }
628 }
629
630 /*******************************************************************************
631 **
632 ** Function bte_hf_evt
633 **
634 ** Description Switches context from BTE to BTIF for all HF events
635 **
636 ** Returns void
637 **
638 *******************************************************************************/
639
bte_hf_evt(tBTA_AG_EVT event,tBTA_AG * p_data)640 static void bte_hf_evt(tBTA_AG_EVT event, tBTA_AG *p_data)
641 {
642 bt_status_t status;
643 int param_len = 0;
644
645 /* TODO: BTA sends the union members and not tBTA_AG. If using param_len=sizeof(tBTA_AG), we get a crash on memcpy */
646 if (BTA_AG_REGISTER_EVT == event)
647 param_len = sizeof(tBTA_AG_REGISTER);
648 else if (BTA_AG_OPEN_EVT == event)
649 param_len = sizeof(tBTA_AG_OPEN);
650 else if (BTA_AG_CONN_EVT == event)
651 param_len = sizeof(tBTA_AG_CONN);
652 else if ( (BTA_AG_CLOSE_EVT == event) || (BTA_AG_AUDIO_OPEN_EVT == event) || (BTA_AG_AUDIO_CLOSE_EVT == event))
653 param_len = sizeof(tBTA_AG_HDR);
654 else if (p_data)
655 param_len = sizeof(tBTA_AG_VAL);
656
657 /* switch context to btif task context (copy full union size for convenience) */
658 status = btif_transfer_context(btif_hf_upstreams_evt, (uint16_t)event, (void*)p_data, param_len, NULL);
659
660 /* catch any failed context transfers */
661 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
662 }
663
664
665 /*******************************************************************************
666 **
667 ** Function btif_in_hf_generic_evt
668 **
669 ** Description Processes generic events to be sent to JNI that are not triggered from the BTA.
670 ** Always runs in BTIF context
671 **
672 ** Returns void
673 **
674 *******************************************************************************/
btif_in_hf_generic_evt(UINT16 event,char * p_param)675 static void btif_in_hf_generic_evt(UINT16 event, char *p_param)
676 {
677 int idx = btif_hf_idx_by_bdaddr((bt_bdaddr_t *)p_param);
678
679 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
680
681 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
682 {
683 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
684 return;
685 }
686
687 switch (event) {
688 case BTIF_HFP_CB_AUDIO_CONNECTING:
689 {
690 HAL_CBACK(bt_hf_callbacks, audio_state_cb, BTHF_AUDIO_STATE_CONNECTING,
691 &btif_hf_cb[idx].connected_bda);
692 } break;
693 default:
694 {
695 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
696 }
697 break;
698 }
699 }
700
701
702 /*******************************************************************************
703 **
704 ** Function btif_hf_init
705 **
706 ** Description initializes the hf interface
707 **
708 ** Returns bt_status_t
709 **
710 *******************************************************************************/
init(bthf_callbacks_t * callbacks,int max_hf_clients)711 static bt_status_t init( bthf_callbacks_t* callbacks, int max_hf_clients)
712 {
713 btif_max_hf_clients = max_hf_clients;
714 BTIF_TRACE_DEBUG("%s - max_hf_clients=%d", __func__, btif_max_hf_clients);
715
716 bt_hf_callbacks = callbacks;
717 memset(&btif_hf_cb, 0, sizeof(btif_hf_cb));
718
719 memset(&btif_hf_cb, 0, sizeof(btif_hf_cb));
720 btif_max_hf_clients = max_hf_clients;
721 BTIF_TRACE_DEBUG("btif_max_hf_clients = %d", btif_max_hf_clients);
722
723 /* Invoke the enable service API to the core to set the appropriate service_id
724 * Internally, the HSP_SERVICE_ID shall also be enabled if HFP is enabled (phone)
725 * othwerwise only HSP is enabled (tablet)
726 */
727 #if (defined(BTIF_HF_SERVICES) && (BTIF_HF_SERVICES & BTA_HFP_SERVICE_MASK))
728 btif_enable_service(BTA_HFP_SERVICE_ID);
729 #else
730 btif_enable_service(BTA_HSP_SERVICE_ID);
731 #endif
732
733 for (int i = 0; i < btif_max_hf_clients; i++)
734 clear_phone_state_multihf(i);
735
736 return BT_STATUS_SUCCESS;
737 }
738
739 /*******************************************************************************
740 **
741 ** Function connect
742 **
743 ** Description connect to headset
744 **
745 ** Returns bt_status_t
746 **
747 *******************************************************************************/
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)748 static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
749 {
750 CHECK_BTHF_INIT();
751 int i;
752 for (i = 0; i < btif_max_hf_clients;)
753 {
754 if (((btif_hf_cb[i].state == BTHF_CONNECTION_STATE_CONNECTED) ||
755 (btif_hf_cb[i].state == BTHF_CONNECTION_STATE_SLC_CONNECTED)))
756 i++;
757 else
758 break;
759 }
760
761 if (i == btif_max_hf_clients)
762 return BT_STATUS_BUSY;
763
764 if (!is_connected(bd_addr))
765 {
766 btif_hf_cb[i].state = BTHF_CONNECTION_STATE_CONNECTING;
767 bdcpy(btif_hf_cb[i].connected_bda.address, bd_addr->address);
768
769 BTA_AgOpen(btif_hf_cb[i].handle, btif_hf_cb[i].connected_bda.address,
770 BTIF_HF_SECURITY, BTIF_HF_SERVICES);
771 return BT_STATUS_SUCCESS;
772 }
773
774 return BT_STATUS_BUSY;
775 }
776
connect(bt_bdaddr_t * bd_addr)777 static bt_status_t connect( bt_bdaddr_t *bd_addr )
778 {
779 CHECK_BTHF_INIT();
780 return btif_queue_connect(UUID_SERVCLASS_AG_HANDSFREE, bd_addr, connect_int);
781 }
782
783 /*******************************************************************************
784 **
785 ** Function disconnect
786 **
787 ** Description disconnect from headset
788 **
789 ** Returns bt_status_t
790 **
791 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)792 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
793 {
794 CHECK_BTHF_INIT();
795
796 int idx = btif_hf_idx_by_bdaddr(bd_addr);
797
798 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
799 {
800 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
801 return BT_STATUS_FAIL;
802 }
803
804 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
805 {
806 BTA_AgClose(btif_hf_cb[idx].handle);
807 return BT_STATUS_SUCCESS;
808 }
809
810 return BT_STATUS_FAIL;
811 }
812
813 /*******************************************************************************
814 **
815 ** Function connect_audio
816 **
817 ** Description create an audio connection
818 **
819 ** Returns bt_status_t
820 **
821 *******************************************************************************/
connect_audio(bt_bdaddr_t * bd_addr)822 static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
823 {
824 CHECK_BTHF_INIT();
825
826 int idx = btif_hf_idx_by_bdaddr(bd_addr);
827
828 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
829 {
830 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
831 return BT_STATUS_FAIL;
832 }
833
834 /* Check if SLC is connected */
835 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
836 return BT_STATUS_NOT_READY;
837
838 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
839 {
840 BTA_AgAudioOpen(btif_hf_cb[idx].handle);
841
842 /* Inform the application that the audio connection has been initiated successfully */
843 btif_transfer_context(btif_in_hf_generic_evt, BTIF_HFP_CB_AUDIO_CONNECTING,
844 (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
845 return BT_STATUS_SUCCESS;
846 }
847
848 return BT_STATUS_FAIL;
849 }
850
851 /*******************************************************************************
852 **
853 ** Function disconnect_audio
854 **
855 ** Description close the audio connection
856 **
857 ** Returns bt_status_t
858 **
859 *******************************************************************************/
disconnect_audio(bt_bdaddr_t * bd_addr)860 static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
861 {
862 CHECK_BTHF_INIT();
863
864 int idx = btif_hf_idx_by_bdaddr(bd_addr);
865
866 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
867 {
868 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
869 return BT_STATUS_FAIL;
870 }
871
872 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
873 {
874 BTA_AgAudioClose(btif_hf_cb[idx].handle);
875 return BT_STATUS_SUCCESS;
876 }
877
878 return BT_STATUS_FAIL;
879 }
880
881 /*******************************************************************************
882 **
883 ** Function start_voice_recognition
884 **
885 ** Description start voice recognition
886 **
887 ** Returns bt_status_t
888 **
889 *******************************************************************************/
start_voice_recognition(bt_bdaddr_t * bd_addr)890 static bt_status_t start_voice_recognition(bt_bdaddr_t *bd_addr)
891 {
892 CHECK_BTHF_INIT();
893
894 int idx = btif_hf_idx_by_bdaddr(bd_addr);
895
896 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
897 {
898 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
899 return BT_STATUS_FAIL;
900 }
901
902 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
903 {
904 if (btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)
905 {
906 tBTA_AG_RES_DATA ag_res;
907 memset(&ag_res, 0, sizeof(ag_res));
908 ag_res.state = 1;
909 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, &ag_res);
910
911 return BT_STATUS_SUCCESS;
912 }
913 else
914 {
915 return BT_STATUS_UNSUPPORTED;
916 }
917 }
918
919 return BT_STATUS_NOT_READY;
920 }
921
922 /*******************************************************************************
923 **
924 ** Function stop_voice_recognition
925 **
926 ** Description stop voice recognition
927 **
928 ** Returns bt_status_t
929 **
930 *******************************************************************************/
stop_voice_recognition(bt_bdaddr_t * bd_addr)931 static bt_status_t stop_voice_recognition(bt_bdaddr_t *bd_addr)
932 {
933 CHECK_BTHF_INIT();
934
935 int idx = btif_hf_idx_by_bdaddr(bd_addr);
936
937 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
938 {
939 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
940 return BT_STATUS_FAIL;
941 }
942
943 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
944 {
945 if (btif_hf_cb[idx].peer_feat & BTA_AG_PEER_FEAT_VREC)
946 {
947 tBTA_AG_RES_DATA ag_res;
948 memset(&ag_res, 0, sizeof(ag_res));
949 ag_res.state = 0;
950 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_BVRA_RES, &ag_res);
951
952 return BT_STATUS_SUCCESS;
953 }
954 else
955 {
956 return BT_STATUS_UNSUPPORTED;
957 }
958 }
959
960 return BT_STATUS_NOT_READY;
961 }
962
963 /*******************************************************************************
964 **
965 ** Function volume_control
966 **
967 ** Description volume control
968 **
969 ** Returns bt_status_t
970 **
971 *******************************************************************************/
volume_control(bthf_volume_type_t type,int volume,bt_bdaddr_t * bd_addr)972 static bt_status_t volume_control(bthf_volume_type_t type, int volume,
973 bt_bdaddr_t *bd_addr)
974 {
975 CHECK_BTHF_INIT();
976
977 int idx = btif_hf_idx_by_bdaddr(bd_addr);
978
979 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
980 {
981 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
982 return BT_STATUS_FAIL;
983 }
984
985 tBTA_AG_RES_DATA ag_res;
986 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
987 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
988 {
989 ag_res.num = volume;
990 BTA_AgResult(btif_hf_cb[idx].handle,
991 (type == BTHF_VOLUME_TYPE_SPK) ? BTA_AG_SPK_RES : BTA_AG_MIC_RES,
992 &ag_res);
993 return BT_STATUS_SUCCESS;
994 }
995
996 return BT_STATUS_FAIL;
997 }
998
999 /*******************************************************************************
1000 **
1001 ** Function device_status_notification
1002 **
1003 ** Description Combined device status change notification
1004 **
1005 ** Returns bt_status_t
1006 **
1007 *******************************************************************************/
device_status_notification(bthf_network_state_t ntk_state,bthf_service_type_t svc_type,int signal,int batt_chg)1008 static bt_status_t device_status_notification(bthf_network_state_t ntk_state,
1009 bthf_service_type_t svc_type, int signal, int batt_chg)
1010 {
1011 CHECK_BTHF_INIT();
1012
1013 if (is_connected(NULL))
1014 {
1015 /* send all indicators to BTA.
1016 ** BTA will make sure no duplicates are sent out
1017 */
1018 send_indicator_update(BTA_AG_IND_SERVICE,
1019 (ntk_state == BTHF_NETWORK_STATE_AVAILABLE) ? 1 : 0);
1020 send_indicator_update(BTA_AG_IND_ROAM,
1021 (svc_type == BTHF_SERVICE_TYPE_HOME) ? 0 : 1);
1022 send_indicator_update(BTA_AG_IND_SIGNAL, signal);
1023 send_indicator_update(BTA_AG_IND_BATTCHG, batt_chg);
1024 return BT_STATUS_SUCCESS;
1025 }
1026
1027 return BT_STATUS_SUCCESS;
1028 }
1029
1030 /*******************************************************************************
1031 **
1032 ** Function cops_response
1033 **
1034 ** Description Response for COPS command
1035 **
1036 ** Returns bt_status_t
1037 **
1038 *******************************************************************************/
cops_response(const char * cops,bt_bdaddr_t * bd_addr)1039 static bt_status_t cops_response(const char *cops, bt_bdaddr_t *bd_addr)
1040 {
1041 CHECK_BTHF_INIT();
1042
1043 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1044
1045 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1046 {
1047 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1048 return BT_STATUS_FAIL;
1049 }
1050
1051 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
1052 {
1053 tBTA_AG_RES_DATA ag_res;
1054
1055 /* Format the response */
1056 sprintf (ag_res.str, "0,0,\"%s\"", cops);
1057 ag_res.ok_flag = BTA_AG_OK_DONE;
1058
1059 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_COPS_RES, &ag_res);
1060 return BT_STATUS_SUCCESS;
1061 }
1062 return BT_STATUS_FAIL;
1063 }
1064
1065 /*******************************************************************************
1066 **
1067 ** Function cind_response
1068 **
1069 ** Description Response for CIND command
1070 **
1071 ** Returns bt_status_t
1072 **
1073 *******************************************************************************/
cind_response(int svc,int num_active,int num_held,bthf_call_state_t call_setup_state,int signal,int roam,int batt_chg,bt_bdaddr_t * bd_addr)1074 static bt_status_t cind_response(int svc, int num_active, int num_held,
1075 bthf_call_state_t call_setup_state,
1076 int signal, int roam, int batt_chg,
1077 bt_bdaddr_t *bd_addr)
1078 {
1079 CHECK_BTHF_INIT();
1080
1081 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1082
1083 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1084 {
1085 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1086 return BT_STATUS_FAIL;
1087 }
1088
1089 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
1090 {
1091 tBTA_AG_RES_DATA ag_res;
1092
1093 memset (&ag_res, 0, sizeof (ag_res));
1094 /* per the errata 2043, call=1 implies atleast one call is in progress (active/held)
1095 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1096 **/
1097 sprintf (ag_res.str, "%d,%d,%d,%d,%d,%d,%d",
1098 (num_active + num_held) ? 1 : 0, /* Call state */
1099 callstate_to_callsetup(call_setup_state), /* Callsetup state */
1100 svc, /* network service */
1101 signal, /* Signal strength */
1102 roam, /* Roaming indicator */
1103 batt_chg, /* Battery level */
1104 ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1))); /* Call held */
1105
1106 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_CIND_RES, &ag_res);
1107
1108 return BT_STATUS_SUCCESS;
1109 }
1110
1111 return BT_STATUS_FAIL;
1112 }
1113
1114 /*******************************************************************************
1115 **
1116 ** Function formatted_at_response
1117 **
1118 ** Description Pre-formatted AT response, typically in response to unknown AT cmd
1119 **
1120 ** Returns bt_status_t
1121 **
1122 *******************************************************************************/
formatted_at_response(const char * rsp,bt_bdaddr_t * bd_addr)1123 static bt_status_t formatted_at_response(const char *rsp, bt_bdaddr_t *bd_addr)
1124 {
1125 CHECK_BTHF_INIT();
1126 tBTA_AG_RES_DATA ag_res;
1127 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1128
1129 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1130 {
1131 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1132 return BT_STATUS_FAIL;
1133 }
1134
1135 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
1136 {
1137 /* Format the response and send */
1138 memset (&ag_res, 0, sizeof (ag_res));
1139 strncpy(ag_res.str, rsp, BTA_AG_AT_MAX_LEN);
1140 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_UNAT_RES, &ag_res);
1141
1142 return BT_STATUS_SUCCESS;
1143 }
1144
1145 return BT_STATUS_FAIL;
1146 }
1147
1148 /*******************************************************************************
1149 **
1150 ** Function at_response
1151 **
1152 ** Description ok/error response
1153 **
1154 ** Returns bt_status_t
1155 **
1156 *******************************************************************************/
at_response(bthf_at_response_t response_code,int error_code,bt_bdaddr_t * bd_addr)1157 static bt_status_t at_response(bthf_at_response_t response_code,
1158 int error_code, bt_bdaddr_t *bd_addr)
1159 {
1160 CHECK_BTHF_INIT();
1161
1162 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1163
1164 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1165 {
1166 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1167 return BT_STATUS_FAIL;
1168 }
1169
1170 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
1171 {
1172 send_at_result((response_code == BTHF_AT_RESPONSE_OK) ? BTA_AG_OK_DONE
1173 : BTA_AG_OK_ERROR, error_code, idx);
1174 return BT_STATUS_SUCCESS;
1175 }
1176
1177
1178 return BT_STATUS_FAIL;
1179 }
1180
1181 /*******************************************************************************
1182 **
1183 ** Function clcc_response
1184 **
1185 ** Description response for CLCC command
1186 ** Can be iteratively called for each call index. Call index
1187 ** of 0 will be treated as NULL termination (Completes response)
1188 **
1189 ** Returns bt_status_t
1190 **
1191 *******************************************************************************/
clcc_response(int index,bthf_call_direction_t dir,bthf_call_state_t state,bthf_call_mode_t mode,bthf_call_mpty_type_t mpty,const char * number,bthf_call_addrtype_t type,bt_bdaddr_t * bd_addr)1192 static bt_status_t clcc_response(int index, bthf_call_direction_t dir,
1193 bthf_call_state_t state, bthf_call_mode_t mode,
1194 bthf_call_mpty_type_t mpty, const char *number,
1195 bthf_call_addrtype_t type, bt_bdaddr_t *bd_addr)
1196 {
1197 CHECK_BTHF_INIT();
1198
1199 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1200
1201 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1202 {
1203 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1204 return BT_STATUS_FAIL;
1205 }
1206
1207 if (is_connected(bd_addr) && (idx != BTIF_HF_INVALID_IDX))
1208 {
1209 tBTA_AG_RES_DATA ag_res;
1210 int xx;
1211
1212 memset (&ag_res, 0, sizeof (ag_res));
1213
1214 /* Format the response */
1215 if (index == 0)
1216 {
1217 ag_res.ok_flag = BTA_AG_OK_DONE;
1218 }
1219 else
1220 {
1221 BTIF_TRACE_EVENT("clcc_response: [%d] dir %d state %d mode %d number = %s type = %d",
1222 index, dir, state, mode, number, type);
1223 xx = sprintf (ag_res.str, "%d,%d,%d,%d,%d",
1224 index, dir, state, mode, mpty);
1225
1226 if (number)
1227 {
1228 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1229 sprintf (&ag_res.str[xx], ",\"+%s\",%d", number, type);
1230 else
1231 sprintf (&ag_res.str[xx], ",\"%s\",%d", number, type);
1232 }
1233 }
1234 BTA_AgResult (btif_hf_cb[idx].handle, BTA_AG_CLCC_RES, &ag_res);
1235
1236 return BT_STATUS_SUCCESS;
1237 }
1238
1239 return BT_STATUS_FAIL;
1240 }
1241
1242 /*******************************************************************************
1243 **
1244 ** Function phone_state_change
1245 **
1246 ** Description notify of a call state change
1247 ** number & type: valid only for incoming & waiting call
1248 **
1249 ** Returns bt_status_t
1250 **
1251 *******************************************************************************/
1252
phone_state_change(int num_active,int num_held,bthf_call_state_t call_setup_state,const char * number,bthf_call_addrtype_t type)1253 static bt_status_t phone_state_change(int num_active, int num_held, bthf_call_state_t call_setup_state,
1254 const char *number, bthf_call_addrtype_t type)
1255 {
1256 tBTA_AG_RES res = 0xff;
1257 tBTA_AG_RES_DATA ag_res;
1258 bt_status_t status = BT_STATUS_SUCCESS;
1259 BOOLEAN activeCallUpdated = FALSE;
1260 int idx, i;
1261
1262 /* hf_idx is index of connected HS that sent ATA/BLDN,
1263 otherwise index of latest connected HS */
1264 if (hf_idx != BTIF_HF_INVALID_IDX)
1265 idx = hf_idx;
1266 else
1267 idx = btif_hf_latest_connected_idx();
1268
1269 BTIF_TRACE_DEBUG("phone_state_change: idx = %d", idx);
1270
1271 /* Check if SLC is connected */
1272 if (btif_hf_check_if_slc_connected() != BT_STATUS_SUCCESS)
1273 return BT_STATUS_NOT_READY;
1274
1275 BTIF_TRACE_DEBUG("phone_state_change: num_active=%d [prev: %d] num_held=%d[prev: %d]"
1276 " call_setup=%s [prev: %s]", num_active, btif_hf_cb[idx].num_active,
1277 num_held, btif_hf_cb[idx].num_held, dump_hf_call_state(call_setup_state),
1278 dump_hf_call_state(btif_hf_cb[idx].call_setup_state));
1279
1280 /* if all indicators are 0, send end call and return */
1281 if (num_active == 0 && num_held == 0 && call_setup_state == BTHF_CALL_STATE_IDLE)
1282 {
1283 BTIF_TRACE_DEBUG("%s: Phone on hook", __FUNCTION__);
1284
1285 /* record call termination timestamp if there was an active/held call or
1286 callsetup state > BTHF_CALL_STATE_IDLE */
1287 if ((btif_hf_cb[idx].call_setup_state != BTHF_CALL_STATE_IDLE ) ||
1288 (btif_hf_cb[idx].num_active) ||(btif_hf_cb[idx].num_held))
1289 {
1290 BTIF_TRACE_DEBUG("%s: Record call termination timestamp", __FUNCTION__);
1291 clock_gettime(CLOCK_MONOTONIC, &btif_hf_cb[0].call_end_timestamp);
1292 }
1293 BTA_AgResult (BTA_AG_HANDLE_ALL, BTA_AG_END_CALL_RES, NULL);
1294 hf_idx = BTIF_HF_INVALID_IDX;
1295
1296 /* if held call was present, reset that as well */
1297 if (btif_hf_cb[idx].num_held)
1298 send_indicator_update(BTA_AG_IND_CALLHELD, 0);
1299
1300 goto update_call_states;
1301 }
1302
1303 /* active state can change when:
1304 ** 1. an outgoing/incoming call was answered
1305 ** 2. an held was resumed
1306 ** 3. without callsetup notifications, call became active
1307 ** (3) can happen if call is active and a headset connects to us
1308 **
1309 ** In the case of (3), we will have to notify the stack of an active
1310 ** call, instead of sending an indicator update. This will also
1311 ** force the SCO to be setup. Handle this special case here prior to
1312 ** call setup handling
1313 */
1314 if ( ((num_active + num_held) > 0) && (btif_hf_cb[idx].num_active == 0) && (btif_hf_cb[idx].num_held == 0) &&
1315 (btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE) )
1316 {
1317 BTIF_TRACE_DEBUG("%s: Active/Held call notification received without call setup update",
1318 __FUNCTION__);
1319
1320 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1321 ag_res.audio_handle = btif_hf_cb[idx].handle;
1322 /* Addition call setup with the Active call
1323 ** CIND response should have been updated.
1324 ** just open SCO conenction.
1325 */
1326 if (call_setup_state != BTHF_CALL_STATE_IDLE)
1327 res = BTA_AG_MULTI_CALL_RES;
1328 else
1329 res = BTA_AG_OUT_CALL_CONN_RES;
1330 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1331 activeCallUpdated = TRUE;
1332 }
1333
1334 /* Ringing call changed? */
1335 if (call_setup_state != btif_hf_cb[idx].call_setup_state)
1336 {
1337 BTIF_TRACE_DEBUG("%s: Call setup states changed. old: %s new: %s",
1338 __FUNCTION__, dump_hf_call_state(btif_hf_cb[idx].call_setup_state),
1339 dump_hf_call_state(call_setup_state));
1340 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1341
1342 switch (call_setup_state)
1343 {
1344 case BTHF_CALL_STATE_IDLE:
1345 {
1346 switch (btif_hf_cb[idx].call_setup_state)
1347 {
1348 case BTHF_CALL_STATE_INCOMING:
1349 if (num_active > btif_hf_cb[idx].num_active)
1350 {
1351 res = BTA_AG_IN_CALL_CONN_RES;
1352 ag_res.audio_handle = btif_hf_cb[idx].handle;
1353 }
1354 else if (num_held > btif_hf_cb[idx].num_held)
1355 res = BTA_AG_IN_CALL_HELD_RES;
1356 else
1357 res = BTA_AG_CALL_CANCEL_RES;
1358 break;
1359 case BTHF_CALL_STATE_DIALING:
1360 case BTHF_CALL_STATE_ALERTING:
1361 if (num_active > btif_hf_cb[idx].num_active)
1362 {
1363 ag_res.audio_handle = BTA_AG_HANDLE_SCO_NO_CHANGE;
1364 res = BTA_AG_OUT_CALL_CONN_RES;
1365 }
1366 else
1367 res = BTA_AG_CALL_CANCEL_RES;
1368 break;
1369 default:
1370 BTIF_TRACE_ERROR("%s: Incorrect Call setup state transition", __FUNCTION__);
1371 status = BT_STATUS_PARM_INVALID;
1372 break;
1373 }
1374 } break;
1375
1376 case BTHF_CALL_STATE_INCOMING:
1377 if (num_active || num_held)
1378 res = BTA_AG_CALL_WAIT_RES;
1379 else
1380 res = BTA_AG_IN_CALL_RES;
1381 if (number)
1382 {
1383 int xx = 0;
1384 if ((type == BTHF_CALL_ADDRTYPE_INTERNATIONAL) && (*number != '+'))
1385 xx = sprintf (ag_res.str, "\"+%s\"", number);
1386 else
1387 xx = sprintf (ag_res.str, "\"%s\"", number);
1388 ag_res.num = type;
1389
1390 if (res == BTA_AG_CALL_WAIT_RES)
1391 sprintf(&ag_res.str[xx], ",%d", type);
1392 }
1393 break;
1394 case BTHF_CALL_STATE_DIALING:
1395 if (!(num_active + num_held))
1396 ag_res.audio_handle = btif_hf_cb[idx].handle;
1397 res = BTA_AG_OUT_CALL_ORIG_RES;
1398 break;
1399 case BTHF_CALL_STATE_ALERTING:
1400 /* if we went from idle->alert, force SCO setup here. dialing usually triggers it */
1401 if ((btif_hf_cb[idx].call_setup_state == BTHF_CALL_STATE_IDLE) &&
1402 !(num_active + num_held))
1403 ag_res.audio_handle = btif_hf_cb[idx].handle;
1404 res = BTA_AG_OUT_CALL_ALERT_RES;
1405 break;
1406 default:
1407 BTIF_TRACE_ERROR("%s: Incorrect new ringing call state", __FUNCTION__);
1408 status = BT_STATUS_PARM_INVALID;
1409 break;
1410 }
1411 BTIF_TRACE_DEBUG("%s: Call setup state changed. res=%d, audio_handle=%d", __FUNCTION__, res, ag_res.audio_handle);
1412
1413 if (res)
1414 BTA_AgResult(BTA_AG_HANDLE_ALL, res, &ag_res);
1415
1416 /* if call setup is idle, we have already updated call indicator, jump out */
1417 if (call_setup_state == BTHF_CALL_STATE_IDLE)
1418 {
1419 /* check & update callheld */
1420 if ((num_held > 0) && (num_active > 0))
1421 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1422 goto update_call_states;
1423 }
1424 }
1425
1426 memset(&ag_res, 0, sizeof(tBTA_AG_RES_DATA));
1427
1428 /* per the errata 2043, call=1 implies atleast one call is in progress (active/held)
1429 ** https://www.bluetooth.org/errata/errata_view.cfm?errata_id=2043
1430 ** Handle call indicator change
1431 **/
1432 if (!activeCallUpdated && ((num_active + num_held) !=
1433 (btif_hf_cb[idx].num_active + btif_hf_cb[idx].num_held)) )
1434 {
1435 BTIF_TRACE_DEBUG("%s: Active call states changed. old: %d new: %d", __FUNCTION__, btif_hf_cb[idx].num_active, num_active);
1436 send_indicator_update(BTA_AG_IND_CALL, ((num_active + num_held) > 0) ? 1 : 0);
1437 }
1438
1439 /* Held Changed? */
1440 if (num_held != btif_hf_cb[idx].num_held ||
1441 ((num_active == 0) && ((num_held + btif_hf_cb[idx].num_held) > 1)))
1442 {
1443 BTIF_TRACE_DEBUG("%s: Held call states changed. old: %d new: %d",
1444 __FUNCTION__, btif_hf_cb[idx].num_held, num_held);
1445 send_indicator_update(BTA_AG_IND_CALLHELD, ((num_held == 0) ? 0 : ((num_active == 0) ? 2 : 1)));
1446 }
1447
1448 /* Calls Swapped? */
1449 if ( (call_setup_state == btif_hf_cb[idx].call_setup_state) &&
1450 (num_active && num_held) &&
1451 (num_active == btif_hf_cb[idx].num_active) &&
1452 (num_held == btif_hf_cb[idx].num_held) )
1453 {
1454 BTIF_TRACE_DEBUG("%s: Calls swapped", __FUNCTION__);
1455 send_indicator_update(BTA_AG_IND_CALLHELD, 1);
1456 }
1457
1458 update_call_states:
1459 for (i = 0; i < btif_max_hf_clients; i++)
1460 {
1461 btif_hf_cb[i].num_active = num_active;
1462 btif_hf_cb[i].num_held = num_held;
1463 btif_hf_cb[i].call_setup_state = call_setup_state;
1464 }
1465 return status;
1466 }
1467
1468 /*******************************************************************************
1469 **
1470 ** Function btif_hf_is_call_idle
1471 **
1472 ** Description returns true if no call is in progress
1473 **
1474 ** Returns bt_status_t
1475 **
1476 *******************************************************************************/
btif_hf_is_call_idle()1477 BOOLEAN btif_hf_is_call_idle()
1478 {
1479 if (bt_hf_callbacks == NULL)
1480 return TRUE;
1481
1482 for (int i = 0; i < btif_max_hf_clients; ++i)
1483 {
1484 if ((btif_hf_cb[i].call_setup_state != BTHF_CALL_STATE_IDLE)
1485 || ((btif_hf_cb[i].num_held + btif_hf_cb[i].num_active) > 0))
1486 return FALSE;
1487 }
1488
1489 return TRUE;
1490 }
1491
1492 /*******************************************************************************
1493 **
1494 ** Function btif_hf_call_terminated_recently
1495 **
1496 ** Description Checks if a call has been terminated
1497 **
1498 ** Returns bt_status_t
1499 **
1500 *******************************************************************************/
btif_hf_call_terminated_recently()1501 BOOLEAN btif_hf_call_terminated_recently()
1502 {
1503 struct timespec now;
1504
1505 clock_gettime(CLOCK_MONOTONIC, &now);
1506 if (now.tv_sec < btif_hf_cb[0].call_end_timestamp.tv_sec +
1507 BTIF_HF_CALL_END_TIMEOUT)
1508 {
1509 return TRUE;
1510 }
1511 else
1512 {
1513 btif_hf_cb[0].call_end_timestamp.tv_sec = 0;
1514 return FALSE;
1515 }
1516 }
1517
1518 /*******************************************************************************
1519 **
1520 ** Function cleanup
1521 **
1522 ** Description Closes the HF interface
1523 **
1524 ** Returns bt_status_t
1525 **
1526 *******************************************************************************/
cleanup(void)1527 static void cleanup( void )
1528 {
1529 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1530
1531 if (bt_hf_callbacks)
1532 {
1533 btif_disable_service(BTA_HFP_SERVICE_ID);
1534 bt_hf_callbacks = NULL;
1535 }
1536 }
1537
1538 /*******************************************************************************
1539 **
1540 ** Function configure_wbs
1541 **
1542 ** Description set to over-ride the current WBS configuration.
1543 ** It will not send codec setting cmd to the controller now.
1544 ** It just change the configure.
1545 **
1546 ** Returns bt_status_t
1547 **
1548 *******************************************************************************/
configure_wbs(bt_bdaddr_t * bd_addr,bthf_wbs_config_t config)1549 static bt_status_t configure_wbs( bt_bdaddr_t *bd_addr , bthf_wbs_config_t config )
1550 {
1551 CHECK_BTHF_INIT();
1552
1553 int idx = btif_hf_idx_by_bdaddr(bd_addr);
1554
1555 if ((idx < 0) || (idx >= BTIF_HF_NUM_CB))
1556 {
1557 BTIF_TRACE_ERROR("%s: Invalid index %d", __FUNCTION__, idx);
1558 return BT_STATUS_FAIL;
1559 }
1560
1561 BTIF_TRACE_EVENT("%s config is %d", __FUNCTION__,config);
1562 if (config == BTHF_WBS_YES)
1563 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_MSBC);
1564 else if(config == BTHF_WBS_NO)
1565 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_CVSD);
1566 else
1567 BTA_AgSetCodec(btif_hf_cb[idx].handle,BTA_AG_CODEC_NONE);
1568
1569 return BT_STATUS_SUCCESS;
1570 }
1571
1572 static const bthf_interface_t bthfInterface = {
1573 sizeof(bthfInterface),
1574 init,
1575 connect,
1576 disconnect,
1577 connect_audio,
1578 disconnect_audio,
1579 start_voice_recognition,
1580 stop_voice_recognition,
1581 volume_control,
1582 device_status_notification,
1583 cops_response,
1584 cind_response,
1585 formatted_at_response,
1586 at_response,
1587 clcc_response,
1588 phone_state_change,
1589 cleanup,
1590 configure_wbs,
1591 };
1592
1593 /*******************************************************************************
1594 **
1595 ** Function btif_hf_execute_service
1596 **
1597 ** Description Initializes/Shuts down the service
1598 **
1599 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
1600 **
1601 *******************************************************************************/
btif_hf_execute_service(BOOLEAN b_enable)1602 bt_status_t btif_hf_execute_service(BOOLEAN b_enable)
1603 {
1604 char * p_service_names[] = BTIF_HF_SERVICE_NAMES;
1605 int i;
1606 if (b_enable)
1607 {
1608 /* Enable and register with BTA-AG */
1609 BTA_AgEnable (BTA_AG_PARSE, bte_hf_evt);
1610 for (i = 0; i < btif_max_hf_clients; i++)
1611 {
1612 BTA_AgRegister(BTIF_HF_SERVICES, BTIF_HF_SECURITY,
1613 BTIF_HF_FEATURES, p_service_names, bthf_hf_id[i]);
1614 }
1615 }
1616 else {
1617 /* De-register AG */
1618 for (i = 0; i < btif_max_hf_clients; i++)
1619 {
1620 BTA_AgDeregister(btif_hf_cb[i].handle);
1621 }
1622 /* Disable AG */
1623 BTA_AgDisable();
1624 }
1625 return BT_STATUS_SUCCESS;
1626 }
1627
1628 /*******************************************************************************
1629 **
1630 ** Function btif_hf_get_interface
1631 **
1632 ** Description Get the hf callback interface
1633 **
1634 ** Returns bthf_interface_t
1635 **
1636 *******************************************************************************/
btif_hf_get_interface()1637 const bthf_interface_t *btif_hf_get_interface()
1638 {
1639 BTIF_TRACE_EVENT("%s", __FUNCTION__);
1640 return &bthfInterface;
1641 }
1642