1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright (C) 2009-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 /************************************************************************************
21 *
22 * Filename: btif_hf_client.c
23 *
24 * Description: Handsfree Profile (HF role) Bluetooth Interface
25 *
26 *
27 ***********************************************************************************/
28
29 #include <hardware/bluetooth.h>
30 #include <hardware/bt_hf_client.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <cutils/properties.h>
34
35 #define LOG_TAG "bt_btif_hfc"
36 #include "btif_common.h"
37 #include "btif_util.h"
38 #include "btif_profile_queue.h"
39 #include "bt_utils.h"
40 #include "btcore/include/bdaddr.h"
41 #include "bta_hf_client_api.h"
42
43 /************************************************************************************
44 ** Constants & Macros
45 ************************************************************************************/
46
47 #ifndef BTIF_HF_CLIENT_SERVICE_NAME
48 #define BTIF_HF_CLIENT_SERVICE_NAME ("Handsfree")
49 #endif
50
51 #ifndef BTIF_HF_CLIENT_SECURITY
52 #define BTIF_HF_CLIENT_SECURITY (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT)
53 #endif
54
55 #ifndef BTIF_HF_CLIENT_FEATURES
56 #define BTIF_HF_CLIENT_FEATURES ( BTA_HF_CLIENT_FEAT_ECNR | \
57 BTA_HF_CLIENT_FEAT_3WAY | \
58 BTA_HF_CLIENT_FEAT_CLI | \
59 BTA_HF_CLIENT_FEAT_VREC | \
60 BTA_HF_CLIENT_FEAT_VOL | \
61 BTA_HF_CLIENT_FEAT_ECS | \
62 BTA_HF_CLIENT_FEAT_ECC | \
63 BTA_HF_CLIENT_FEAT_CODEC)
64 #endif
65
66 /************************************************************************************
67 ** Local type definitions
68 ************************************************************************************/
69
70 /************************************************************************************
71 ** Static variables
72 ************************************************************************************/
73 static bthf_client_callbacks_t *bt_hf_client_callbacks = NULL;
74 char btif_hf_client_version[PROPERTY_VALUE_MAX];
75 static UINT32 btif_hf_client_features = 0;
76
77
78 #define CHECK_BTHF_CLIENT_INIT() if (bt_hf_client_callbacks == NULL)\
79 {\
80 BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __FUNCTION__);\
81 return BT_STATUS_NOT_READY;\
82 }\
83 else\
84 {\
85 BTIF_TRACE_EVENT("BTHF CLIENT: %s", __FUNCTION__);\
86 }
87
88 #define CHECK_BTHF_CLIENT_SLC_CONNECTED() if (bt_hf_client_callbacks == NULL)\
89 {\
90 BTIF_TRACE_WARNING("BTHF CLIENT: %s: not initialized", __FUNCTION__);\
91 return BT_STATUS_NOT_READY;\
92 }\
93 else if (btif_hf_client_cb.state != BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED)\
94 {\
95 BTIF_TRACE_WARNING("BTHF CLIENT: %s: SLC connection not up. state=%s",\
96 __FUNCTION__, \
97 dump_hf_conn_state(btif_hf_client_cb.state));\
98 return BT_STATUS_NOT_READY;\
99 }\
100 else\
101 {\
102 BTIF_TRACE_EVENT("BTHF CLIENT: %s", __FUNCTION__);\
103 }
104
105 /* BTIF-HF control block to map bdaddr to BTA handle */
106 typedef struct
107 {
108 UINT16 handle;
109 bt_bdaddr_t connected_bda;
110 bthf_client_connection_state_t state;
111 bthf_client_vr_state_t vr_state;
112 tBTA_HF_CLIENT_PEER_FEAT peer_feat;
113 tBTA_HF_CLIENT_CHLD_FEAT chld_feat;
114 } btif_hf_client_cb_t;
115
116 static btif_hf_client_cb_t btif_hf_client_cb;
117
118
119 /************************************************************************************
120 ** Static functions
121 ************************************************************************************/
122
123 /*******************************************************************************
124 **
125 ** Function btif_in_hf_client_generic_evt
126 **
127 ** Description Processes generic events to be sent to JNI that are not triggered from the BTA.
128 ** Always runs in BTIF context
129 **
130 ** Returns void
131 **
132 *******************************************************************************/
btif_in_hf_client_generic_evt(UINT16 event,char * p_param)133 static void btif_in_hf_client_generic_evt(UINT16 event, char *p_param)
134 {
135 UNUSED(p_param);
136
137 BTIF_TRACE_EVENT("%s: event=%d", __FUNCTION__, event);
138 switch (event) {
139 case BTIF_HF_CLIENT_CB_AUDIO_CONNECTING:
140 {
141 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, (bthf_client_audio_state_t)BTHF_AUDIO_STATE_CONNECTING,
142 &btif_hf_client_cb.connected_bda);
143 } break;
144 default:
145 {
146 BTIF_TRACE_WARNING("%s : Unknown event 0x%x", __FUNCTION__, event);
147 }
148 break;
149 }
150 }
151
152 /************************************************************************************
153 ** Externs
154 ************************************************************************************/
155
156 /************************************************************************************
157 ** Functions
158 ************************************************************************************/
159
clear_state(void)160 static void clear_state(void)
161 {
162 memset(&btif_hf_client_cb, 0, sizeof(btif_hf_client_cb_t));
163 }
164
is_connected(bt_bdaddr_t * bd_addr)165 static BOOLEAN is_connected(bt_bdaddr_t *bd_addr)
166 {
167 if (((btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTED) ||
168 (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED))&&
169 ((bd_addr == NULL) || (bdcmp(bd_addr->address, btif_hf_client_cb.connected_bda.address) == 0)))
170 return TRUE;
171 return FALSE;
172 }
173
174 /*****************************************************************************
175 ** Section name (Group of functions)
176 *****************************************************************************/
177
178 /*****************************************************************************
179 **
180 ** btif hf api functions (no context switch)
181 **
182 *****************************************************************************/
183
184 /*******************************************************************************
185 **
186 ** Function btif_hf_client_init
187 **
188 ** Description initializes the hf interface
189 **
190 ** Returns bt_status_t
191 **
192 *******************************************************************************/
init(bthf_client_callbacks_t * callbacks)193 static bt_status_t init( bthf_client_callbacks_t* callbacks )
194 {
195 BTIF_TRACE_EVENT("%s", __FUNCTION__);
196
197 bt_hf_client_callbacks = callbacks;
198
199 btif_enable_service(BTA_HFP_HS_SERVICE_ID);
200
201 clear_state();
202
203 return BT_STATUS_SUCCESS;
204 }
205
206 /*******************************************************************************
207 **
208 ** Function connect
209 **
210 ** Description connect to audio gateway
211 **
212 ** Returns bt_status_t
213 **
214 *******************************************************************************/
connect_int(bt_bdaddr_t * bd_addr,uint16_t uuid)215 static bt_status_t connect_int( bt_bdaddr_t *bd_addr, uint16_t uuid )
216 {
217 if (is_connected(bd_addr))
218 return BT_STATUS_BUSY;
219
220 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTING;
221 bdcpy(btif_hf_client_cb.connected_bda.address, bd_addr->address);
222
223 BTA_HfClientOpen(btif_hf_client_cb.handle, btif_hf_client_cb.connected_bda.address,
224 BTIF_HF_CLIENT_SECURITY);
225
226 return BT_STATUS_SUCCESS;
227 }
228
connect(bt_bdaddr_t * bd_addr)229 static bt_status_t connect( bt_bdaddr_t *bd_addr )
230 {
231 BTIF_TRACE_EVENT("HFP Client version is %s", btif_hf_client_version);
232 CHECK_BTHF_CLIENT_INIT();
233 return btif_queue_connect(UUID_SERVCLASS_HF_HANDSFREE, bd_addr, connect_int);
234
235 }
236
237 /*******************************************************************************
238 **
239 ** Function disconnect
240 **
241 ** Description disconnect from audio gateway
242 **
243 ** Returns bt_status_t
244 **
245 *******************************************************************************/
disconnect(bt_bdaddr_t * bd_addr)246 static bt_status_t disconnect( bt_bdaddr_t *bd_addr )
247 {
248 CHECK_BTHF_CLIENT_INIT();
249
250 if (is_connected(bd_addr))
251 {
252 BTA_HfClientClose(btif_hf_client_cb.handle);
253 return BT_STATUS_SUCCESS;
254 }
255
256 return BT_STATUS_FAIL;
257 }
258
259 /*******************************************************************************
260 **
261 ** Function connect_audio
262 **
263 ** Description create an audio connection
264 **
265 ** Returns bt_status_t
266 **
267 *******************************************************************************/
connect_audio(bt_bdaddr_t * bd_addr)268 static bt_status_t connect_audio( bt_bdaddr_t *bd_addr )
269 {
270 CHECK_BTHF_CLIENT_SLC_CONNECTED();
271
272 if (is_connected(bd_addr))
273 {
274 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_CODEC)
275 {
276 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BCC, 0, 0, NULL);
277 }
278 else
279 {
280 BTA_HfClientAudioOpen(btif_hf_client_cb.handle);
281 }
282
283 /* Inform the application that the audio connection has been initiated successfully */
284 btif_transfer_context(btif_in_hf_client_generic_evt, BTIF_HF_CLIENT_CB_AUDIO_CONNECTING,
285 (char *)bd_addr, sizeof(bt_bdaddr_t), NULL);
286 return BT_STATUS_SUCCESS;
287 }
288
289 return BT_STATUS_FAIL;
290 }
291
292 /*******************************************************************************
293 **
294 ** Function disconnect_audio
295 **
296 ** Description close the audio connection
297 **
298 ** Returns bt_status_t
299 **
300 *******************************************************************************/
disconnect_audio(bt_bdaddr_t * bd_addr)301 static bt_status_t disconnect_audio( bt_bdaddr_t *bd_addr )
302 {
303 CHECK_BTHF_CLIENT_SLC_CONNECTED();
304
305 if (is_connected(bd_addr))
306 {
307 BTA_HfClientAudioClose(btif_hf_client_cb.handle);
308 return BT_STATUS_SUCCESS;
309 }
310
311 return BT_STATUS_FAIL;
312 }
313
314 /*******************************************************************************
315 **
316 ** Function start_voice_recognition
317 **
318 ** Description start voice recognition
319 **
320 ** Returns bt_status_t
321 **
322 *******************************************************************************/
start_voice_recognition()323 static bt_status_t start_voice_recognition()
324 {
325 CHECK_BTHF_CLIENT_SLC_CONNECTED();
326
327 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC)
328 {
329 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BVRA, 1, 0, NULL);
330
331 return BT_STATUS_SUCCESS;
332 }
333
334 return BT_STATUS_UNSUPPORTED;
335 }
336
337 /*******************************************************************************
338 **
339 ** Function stop_voice_recognition
340 **
341 ** Description stop voice recognition
342 **
343 ** Returns bt_status_t
344 **
345 *******************************************************************************/
stop_voice_recognition()346 static bt_status_t stop_voice_recognition()
347 {
348 CHECK_BTHF_CLIENT_SLC_CONNECTED();
349
350 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_VREC)
351 {
352 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BVRA, 0, 0, NULL);
353
354 return BT_STATUS_SUCCESS;
355 }
356
357 return BT_STATUS_UNSUPPORTED;
358 }
359
360 /*******************************************************************************
361 **
362 ** Function volume_control
363 **
364 ** Description volume control
365 **
366 ** Returns bt_status_t
367 **
368 *******************************************************************************/
volume_control(bthf_client_volume_type_t type,int volume)369 static bt_status_t volume_control(bthf_client_volume_type_t type, int volume)
370 {
371 CHECK_BTHF_CLIENT_SLC_CONNECTED();
372
373 switch (type)
374 {
375 case BTHF_CLIENT_VOLUME_TYPE_SPK:
376 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VGS, volume, 0, NULL);
377 break;
378 case BTHF_CLIENT_VOLUME_TYPE_MIC:
379 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VGM, volume, 0, NULL);
380 break;
381 default:
382 return BT_STATUS_UNSUPPORTED;
383 }
384
385 return BT_STATUS_SUCCESS;
386 }
387
388 /*******************************************************************************
389 **
390 ** Function dial
391 **
392 ** Description place a call
393 **
394 ** Returns bt_status_t
395 **
396 *******************************************************************************/
dial(const char * number)397 static bt_status_t dial(const char *number)
398 {
399 CHECK_BTHF_CLIENT_SLC_CONNECTED();
400
401 if (number)
402 {
403 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATD, 0, 0, number);
404 }
405 else
406 {
407 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BLDN, 0, 0, NULL);
408 }
409
410 return BT_STATUS_SUCCESS;
411 }
412
413 /*******************************************************************************
414 **
415 ** Function dial_memory
416 **
417 ** Description place a call with number specified by location (speed dial)
418 **
419 ** Returns bt_status_t
420 **
421 *******************************************************************************/
dial_memory(int location)422 static bt_status_t dial_memory(int location)
423 {
424 CHECK_BTHF_CLIENT_SLC_CONNECTED();
425
426 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATD, location, 0, NULL);
427
428 return BT_STATUS_SUCCESS;
429 }
430
431 /*******************************************************************************
432 **
433 ** Function handle_call_action
434 **
435 ** Description handle specified call related action
436 **
437 ** Returns bt_status_t
438 **
439 *******************************************************************************/
handle_call_action(bthf_client_call_action_t action,int idx)440 static bt_status_t handle_call_action(bthf_client_call_action_t action, int idx)
441 {
442 CHECK_BTHF_CLIENT_SLC_CONNECTED();
443
444 switch (action)
445 {
446 case BTHF_CLIENT_CALL_ACTION_CHLD_0:
447 if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_REL)
448 {
449 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 0, 0, NULL);
450 break;
451 }
452 return BT_STATUS_UNSUPPORTED;
453 case BTHF_CLIENT_CALL_ACTION_CHLD_1:
454 // CHLD 1 is mandatory for 3 way calling
455 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY)
456 {
457 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, 0, NULL);
458 break;
459 }
460 return BT_STATUS_UNSUPPORTED;
461 case BTHF_CLIENT_CALL_ACTION_CHLD_2:
462 // CHLD 2 is mandatory for 3 way calling
463 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_FEAT_3WAY)
464 {
465 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, 0, NULL);
466 break;
467 }
468 return BT_STATUS_UNSUPPORTED;
469 case BTHF_CLIENT_CALL_ACTION_CHLD_3:
470 if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_MERGE)
471 {
472 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 3, 0, NULL);
473 break;
474 }
475 return BT_STATUS_UNSUPPORTED;
476 case BTHF_CLIENT_CALL_ACTION_CHLD_4:
477 if (btif_hf_client_cb.chld_feat & BTA_HF_CLIENT_CHLD_MERGE_DETACH)
478 {
479 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 4, 0, NULL);
480 break;
481 }
482 return BT_STATUS_UNSUPPORTED;
483 case BTHF_CLIENT_CALL_ACTION_CHLD_1x:
484 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECC)
485 {
486 if (idx < 1)
487 {
488 return BT_STATUS_FAIL;
489 }
490 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 1, idx, NULL);
491 break;
492 }
493 return BT_STATUS_UNSUPPORTED;
494 case BTHF_CLIENT_CALL_ACTION_CHLD_2x:
495 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECC)
496 {
497 if (idx < 1)
498 {
499 return BT_STATUS_FAIL;
500 }
501 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHLD, 2, idx, NULL);
502 break;
503 }
504 return BT_STATUS_UNSUPPORTED;
505 case BTHF_CLIENT_CALL_ACTION_ATA:
506 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_ATA, 0, 0, NULL);
507 break;
508 case BTHF_CLIENT_CALL_ACTION_CHUP:
509 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CHUP, 0, 0, NULL);
510 break;
511 case BTHF_CLIENT_CALL_ACTION_BTRH_0:
512 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 0, 0, NULL);
513 break;
514 case BTHF_CLIENT_CALL_ACTION_BTRH_1:
515 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 1, 0, NULL);
516 break;
517 case BTHF_CLIENT_CALL_ACTION_BTRH_2:
518 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BTRH, 2, 0, NULL);
519 break;
520 default:
521 return BT_STATUS_FAIL;
522
523 }
524
525 return BT_STATUS_SUCCESS;
526 }
527
528 /*******************************************************************************
529 **
530 ** Function query_current_calls
531 **
532 ** Description query list of current calls
533 **
534 ** Returns bt_status_t
535 **
536 *******************************************************************************/
query_current_calls(void)537 static bt_status_t query_current_calls(void)
538 {
539 CHECK_BTHF_CLIENT_SLC_CONNECTED();
540
541 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_ECS)
542 {
543 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CLCC, 0, 0, NULL);
544
545 return BT_STATUS_SUCCESS;
546 }
547
548 return BT_STATUS_UNSUPPORTED;
549 }
550
551 /*******************************************************************************
552 **
553 ** Function query_current_operator_name
554 **
555 ** Description query current selected operator name
556 **
557 ** Returns bt_status_t
558 **
559 *******************************************************************************/
query_current_operator_name(void)560 static bt_status_t query_current_operator_name(void)
561 {
562 CHECK_BTHF_CLIENT_SLC_CONNECTED();
563
564 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_COPS, 0, 0, NULL);
565
566 return BT_STATUS_SUCCESS;
567 }
568
569 /*******************************************************************************
570 **
571 ** Function retieve_subscriber_info
572 **
573 ** Description retrieve subscriber number information
574 **
575 ** Returns bt_status_t
576 **
577 *******************************************************************************/
retrieve_subscriber_info(void)578 static bt_status_t retrieve_subscriber_info(void)
579 {
580 CHECK_BTHF_CLIENT_SLC_CONNECTED();
581
582 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_CNUM, 0, 0, NULL);
583
584 return BT_STATUS_SUCCESS;
585 }
586
587 /*******************************************************************************
588 **
589 ** Function send_dtmf
590 **
591 ** Description send dtmf
592 **
593 ** Returns bt_status_t
594 **
595 *******************************************************************************/
send_dtmf(char code)596 static bt_status_t send_dtmf(char code)
597 {
598 CHECK_BTHF_CLIENT_SLC_CONNECTED();
599
600 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_VTS, code, 0, NULL);
601
602 return BT_STATUS_SUCCESS;
603 }
604
605 /*******************************************************************************
606 **
607 ** Function request_last_voice_tag_number
608 **
609 ** Description Request number from AG for VR purposes
610 **
611 ** Returns bt_status_t
612 **
613 *******************************************************************************/
request_last_voice_tag_number(void)614 static bt_status_t request_last_voice_tag_number(void)
615 {
616 CHECK_BTHF_CLIENT_SLC_CONNECTED();
617
618 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_VTAG)
619 {
620 BTA_HfClientSendAT(btif_hf_client_cb.handle, BTA_HF_CLIENT_AT_CMD_BINP, 1, 0, NULL);
621
622 return BT_STATUS_SUCCESS;
623 }
624
625 return BT_STATUS_UNSUPPORTED;
626 }
627
628 /*******************************************************************************
629 **
630 ** Function cleanup
631 **
632 ** Description Closes the HF interface
633 **
634 ** Returns bt_status_t
635 **
636 *******************************************************************************/
cleanup(void)637 static void cleanup( void )
638 {
639 BTIF_TRACE_EVENT("%s", __FUNCTION__);
640
641 if (bt_hf_client_callbacks)
642 {
643 btif_disable_service(BTA_HFP_HS_SERVICE_ID);
644 bt_hf_client_callbacks = NULL;
645 }
646 }
647
648 /*******************************************************************************
649 **
650 ** Function send_at_cmd
651 **
652 ** Description Send requested AT command to rempte device.
653 **
654 ** Returns bt_status_t
655 **
656 *******************************************************************************/
send_at_cmd(int cmd,int val1,int val2,const char * arg)657 static bt_status_t send_at_cmd(int cmd,int val1,int val2,const char *arg)
658 {
659 CHECK_BTHF_CLIENT_SLC_CONNECTED();
660 BTIF_TRACE_EVENT("%s Cmd %d val1 %d val2 %d arg %s",
661 __FUNCTION__,cmd,val1,val2,arg);
662 BTA_HfClientSendAT(btif_hf_client_cb.handle, cmd, val1, val2, arg);
663
664 return BT_STATUS_SUCCESS;
665 }
666
667 static const bthf_client_interface_t bthfClientInterface = {
668 sizeof(bthf_client_interface_t),
669 .init = init,
670 .connect = connect,
671 .disconnect = disconnect,
672 .connect_audio = connect_audio,
673 .disconnect_audio = disconnect_audio,
674 .start_voice_recognition = start_voice_recognition,
675 .stop_voice_recognition = stop_voice_recognition,
676 .volume_control = volume_control,
677 .dial = dial,
678 .dial_memory = dial_memory,
679 .handle_call_action = handle_call_action,
680 .query_current_calls = query_current_calls,
681 .query_current_operator_name = query_current_operator_name,
682 .retrieve_subscriber_info = retrieve_subscriber_info,
683 .send_dtmf = send_dtmf,
684 .request_last_voice_tag_number = request_last_voice_tag_number,
685 .cleanup = cleanup,
686 .send_at_cmd = send_at_cmd,
687 };
688
process_ind_evt(tBTA_HF_CLIENT_IND * ind)689 static void process_ind_evt(tBTA_HF_CLIENT_IND *ind)
690 {
691 switch (ind->type)
692 {
693 case BTA_HF_CLIENT_IND_CALL:
694 HAL_CBACK(bt_hf_client_callbacks, call_cb, ind->value);
695 break;
696
697 case BTA_HF_CLIENT_IND_CALLSETUP:
698 HAL_CBACK(bt_hf_client_callbacks, callsetup_cb, ind->value);
699 break;
700 case BTA_HF_CLIENT_IND_CALLHELD:
701 HAL_CBACK(bt_hf_client_callbacks, callheld_cb, ind->value);
702 break;
703
704 case BTA_HF_CLIENT_IND_SERVICE:
705 HAL_CBACK(bt_hf_client_callbacks, network_state_cb, ind->value);
706 break;
707
708 case BTA_HF_CLIENT_IND_SIGNAL:
709 HAL_CBACK(bt_hf_client_callbacks, network_signal_cb, ind->value);
710 break;
711
712 case BTA_HF_CLIENT_IND_ROAM:
713 HAL_CBACK(bt_hf_client_callbacks, network_roaming_cb, ind->value);
714 break;
715
716 case BTA_HF_CLIENT_IND_BATTCH:
717 HAL_CBACK(bt_hf_client_callbacks, battery_level_cb, ind->value);
718 break;
719
720 default:
721 break;
722 }
723 }
724
725 /*******************************************************************************
726 **
727 ** Function btif_hf_client_upstreams_evt
728 **
729 ** Description Executes HF CLIENT UPSTREAMS events in btif context
730 **
731 ** Returns void
732 **
733 *******************************************************************************/
btif_hf_client_upstreams_evt(UINT16 event,char * p_param)734 static void btif_hf_client_upstreams_evt(UINT16 event, char* p_param)
735 {
736 tBTA_HF_CLIENT *p_data = (tBTA_HF_CLIENT *)p_param;
737 bdstr_t bdstr;
738
739 BTIF_TRACE_DEBUG("%s: event=%s (%u)", __FUNCTION__, dump_hf_client_event(event), event);
740
741 switch (event)
742 {
743 case BTA_HF_CLIENT_ENABLE_EVT:
744 case BTA_HF_CLIENT_DISABLE_EVT:
745 break;
746
747 case BTA_HF_CLIENT_REGISTER_EVT:
748 btif_hf_client_cb.handle = p_data->reg.handle;
749 break;
750
751 case BTA_HF_CLIENT_OPEN_EVT:
752 if (p_data->open.status == BTA_HF_CLIENT_SUCCESS)
753 {
754 bdcpy(btif_hf_client_cb.connected_bda.address, p_data->open.bd_addr);
755 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_CONNECTED;
756 btif_hf_client_cb.peer_feat = 0;
757 btif_hf_client_cb.chld_feat = 0;
758 //clear_phone_state();
759 }
760 else if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_CONNECTING)
761 {
762 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
763 }
764 else
765 {
766 BTIF_TRACE_WARNING("%s: HF CLient open failed, but another device connected. status=%d state=%d connected device=%s",
767 __FUNCTION__, p_data->open.status, btif_hf_client_cb.state, bdaddr_to_string(&btif_hf_client_cb.connected_bda, bdstr, sizeof(bdstr)));
768 break;
769 }
770
771 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
772 0, 0, &btif_hf_client_cb.connected_bda);
773
774 if (btif_hf_client_cb.state == BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED)
775 bdsetany(btif_hf_client_cb.connected_bda.address);
776
777 if (p_data->open.status != BTA_HF_CLIENT_SUCCESS)
778 btif_queue_advance();
779 break;
780
781 case BTA_HF_CLIENT_CONN_EVT:
782 btif_hf_client_cb.peer_feat = p_data->conn.peer_feat;
783 btif_hf_client_cb.chld_feat = p_data->conn.chld_feat;
784 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED;
785
786 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
787 btif_hf_client_cb.peer_feat, btif_hf_client_cb.chld_feat,
788 &btif_hf_client_cb.connected_bda);
789
790 /* Inform the application about in-band ringtone */
791 if (btif_hf_client_cb.peer_feat & BTA_HF_CLIENT_PEER_INBAND)
792 {
793 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
794 }
795
796 btif_queue_advance();
797 break;
798
799 case BTA_HF_CLIENT_CLOSE_EVT:
800 btif_hf_client_cb.state = BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED;
801 HAL_CBACK(bt_hf_client_callbacks, connection_state_cb, btif_hf_client_cb.state,
802 0, 0, &btif_hf_client_cb.connected_bda);
803 bdsetany(btif_hf_client_cb.connected_bda.address);
804 btif_hf_client_cb.peer_feat = 0;
805 btif_hf_client_cb.chld_feat = 0;
806 btif_queue_advance();
807 break;
808
809 case BTA_HF_CLIENT_IND_EVT:
810 process_ind_evt(&p_data->ind);
811 break;
812
813 case BTA_HF_CLIENT_MIC_EVT:
814 HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_MIC, p_data->val.value);
815 break;
816
817 case BTA_HF_CLIENT_SPK_EVT:
818 HAL_CBACK(bt_hf_client_callbacks, volume_change_cb, BTHF_CLIENT_VOLUME_TYPE_SPK, p_data->val.value);
819 break;
820
821 case BTA_HF_CLIENT_VOICE_REC_EVT:
822 HAL_CBACK(bt_hf_client_callbacks, vr_cmd_cb, p_data->val.value);
823 break;
824
825 case BTA_HF_CLIENT_OPERATOR_NAME_EVT:
826 HAL_CBACK(bt_hf_client_callbacks, current_operator_cb, p_data->operator.name);
827 break;
828
829 case BTA_HF_CLIENT_CLIP_EVT:
830 HAL_CBACK(bt_hf_client_callbacks, clip_cb, p_data->number.number);
831 break;
832
833 case BTA_HF_CLIENT_BINP_EVT:
834 HAL_CBACK(bt_hf_client_callbacks, last_voice_tag_number_callback, p_data->number.number);
835 break;
836
837 case BTA_HF_CLIENT_CCWA_EVT:
838 HAL_CBACK(bt_hf_client_callbacks, call_waiting_cb, p_data->number.number);
839 break;
840
841 case BTA_HF_CLIENT_AT_RESULT_EVT:
842 HAL_CBACK(bt_hf_client_callbacks, cmd_complete_cb, p_data->result.type, p_data->result.cme);
843 break;
844
845 case BTA_HF_CLIENT_CLCC_EVT:
846 HAL_CBACK(bt_hf_client_callbacks, current_calls_cb, p_data->clcc.idx,
847 p_data->clcc.inc ? BTHF_CLIENT_CALL_DIRECTION_INCOMING : BTHF_CLIENT_CALL_DIRECTION_OUTGOING,
848 p_data->clcc.status,
849 p_data->clcc.mpty ? BTHF_CLIENT_CALL_MPTY_TYPE_MULTI : BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE,
850 p_data->clcc.number_present ? p_data->clcc.number : NULL);
851 break;
852
853 case BTA_HF_CLIENT_CNUM_EVT:
854 if (p_data->cnum.service == 4)
855 {
856 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_VOICE);
857 }
858 else if (p_data->cnum.service == 5)
859 {
860 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_FAX);
861 }
862 else
863 {
864 HAL_CBACK(bt_hf_client_callbacks, subscriber_info_cb, p_data->cnum.number, BTHF_CLIENT_SERVICE_UNKNOWN);
865 }
866 break;
867
868 case BTA_HF_CLIENT_BTRH_EVT:
869 if (p_data->val.value <= BTRH_CLIENT_RESP_AND_HOLD_REJECT)
870 {
871 HAL_CBACK(bt_hf_client_callbacks, resp_and_hold_cb, p_data->val.value);
872 }
873 break;
874
875 case BTA_HF_CLIENT_BSIR_EVT:
876 if (p_data->val.value != 0)
877 {
878 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED);
879 }
880 else
881 {
882 HAL_CBACK(bt_hf_client_callbacks, in_band_ring_tone_cb, BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED);
883 }
884 break;
885
886 case BTA_HF_CLIENT_AUDIO_OPEN_EVT:
887 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED, &btif_hf_client_cb.connected_bda);
888 break;
889
890 case BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT:
891 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, &btif_hf_client_cb.connected_bda);
892 break;
893
894 case BTA_HF_CLIENT_AUDIO_CLOSE_EVT:
895 HAL_CBACK(bt_hf_client_callbacks, audio_state_cb, BTHF_CLIENT_AUDIO_STATE_DISCONNECTED, &btif_hf_client_cb.connected_bda);
896 break;
897 case BTA_HF_CLIENT_RING_INDICATION:
898 HAL_CBACK(bt_hf_client_callbacks, ring_indication_cb);
899 break;
900 default:
901 BTIF_TRACE_WARNING("%s: Unhandled event: %d", __FUNCTION__, event);
902 break;
903 }
904 }
905
906 /*******************************************************************************
907 **
908 ** Function bte_hf_client_evt
909 **
910 ** Description Switches context from BTE to BTIF for all HF Client events
911 **
912 ** Returns void
913 **
914 *******************************************************************************/
915
bte_hf_client_evt(tBTA_HF_CLIENT_EVT event,tBTA_HF_CLIENT * p_data)916 static void bte_hf_client_evt(tBTA_HF_CLIENT_EVT event, tBTA_HF_CLIENT *p_data)
917 {
918 bt_status_t status;
919
920 /* switch context to btif task context (copy full union size for convenience) */
921 status = btif_transfer_context(btif_hf_client_upstreams_evt, (uint16_t)event, (void*)p_data, sizeof(*p_data), NULL);
922
923 /* catch any failed context transfers */
924 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
925 }
926
927 /*******************************************************************************
928 **
929 ** Function btif_hf_client_execute_service
930 **
931 ** Description Initializes/Shuts down the service
932 **
933 ** Returns BT_STATUS_SUCCESS on success, BT_STATUS_FAIL otherwise
934 **
935 *******************************************************************************/
btif_hf_client_execute_service(BOOLEAN b_enable)936 bt_status_t btif_hf_client_execute_service(BOOLEAN b_enable)
937 {
938 BTIF_TRACE_EVENT("%s enable:%d", __FUNCTION__, b_enable);
939
940 property_get("ro.bluetooth.hfp.ver", btif_hf_client_version, "1.5");
941
942 if (b_enable)
943 {
944 /* Enable and register with BTA-HFClient */
945 BTA_HfClientEnable(bte_hf_client_evt);
946 if (strcmp(btif_hf_client_version, "1.6") == 0)
947 {
948 BTIF_TRACE_EVENT("Support Codec Nego. %d ", BTIF_HF_CLIENT_FEATURES);
949 BTA_HfClientRegister(BTIF_HF_CLIENT_SECURITY, BTIF_HF_CLIENT_FEATURES,
950 BTIF_HF_CLIENT_SERVICE_NAME);
951 }
952 else
953 {
954 BTIF_TRACE_EVENT("No Codec Nego Supported");
955 btif_hf_client_features = BTIF_HF_CLIENT_FEATURES;
956 btif_hf_client_features = btif_hf_client_features & (~BTA_HF_CLIENT_FEAT_CODEC);
957 BTIF_TRACE_EVENT("btif_hf_client_features is %d", btif_hf_client_features);
958 BTA_HfClientRegister(BTIF_HF_CLIENT_SECURITY, btif_hf_client_features,
959 BTIF_HF_CLIENT_SERVICE_NAME);
960 }
961
962 }
963 else
964 {
965 BTA_HfClientDeregister(btif_hf_client_cb.handle);
966 BTA_HfClientDisable();
967 }
968 return BT_STATUS_SUCCESS;
969 }
970
971 /*******************************************************************************
972 **
973 ** Function btif_hf_get_interface
974 **
975 ** Description Get the hf callback interface
976 **
977 ** Returns bthf_interface_t
978 **
979 *******************************************************************************/
btif_hf_client_get_interface(void)980 const bthf_client_interface_t *btif_hf_client_get_interface(void)
981 {
982 BTIF_TRACE_EVENT("%s", __FUNCTION__);
983 return &bthfClientInterface;
984 }
985