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