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