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