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