bta_hf_client_main.cc revision bd3ae7cbf195caf91693046147b34d25b6317485
13fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/******************************************************************************
23fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *
31025687c6679608fe9df918f37011414ffc72b62Hemant Gupta *  Copyright (c) 2014 The Android Open Source Project
43fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  Copyright (C) 2003-2012 Broadcom Corporation
53fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *
63fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  Licensed under the Apache License, Version 2.0 (the "License");
73fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  you may not use this file except in compliance with the License.
83fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  You may obtain a copy of the License at:
93fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *
103fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  http://www.apache.org/licenses/LICENSE-2.0
113fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *
123fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  Unless required by applicable law or agreed to in writing, software
133fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  distributed under the License is distributed on an "AS IS" BASIS,
143fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  See the License for the specific language governing permissions and
163fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *  limitations under the License.
173fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *
183fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta ******************************************************************************/
193fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
201025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include <stdlib.h>
21cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include <string.h>
22303b6ff16e1d257a491d2ae4fac2cd1b78850f67Arman Uguray
231025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include "bt_utils.h"
243fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta#include "bta_api.h"
251025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include "bta_hf_client_api.h"
261025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include "bta_hf_client_int.h"
27cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include "bta_sys.h"
285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal#include "btcore/include/bdaddr.h"
29cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include "osi/include/osi.h"
30cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include "osi/include/properties.h"
31bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal#include "utl.h"
323fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
33cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonextern fixed_queue_t* btu_bta_alarm_queue;
3478bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov
35bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_evt_str(uint16_t event);
36bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_state_str(uint8_t state);
37bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
383fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state machine states */
39cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonenum {
40cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_INIT_ST,
41cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_OPENING_ST,
42cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_OPEN_ST,
43cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_CLOSING_ST
443fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
453fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
463fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state machine action enumeration list */
47cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonenum {
48cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_DO_CLOSE,
49cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_START_CLOSE,
50cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_START_OPEN,
51cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_ACP_OPEN,
52cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_LISTEN,
53cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_CONN_OPEN,
54cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_CONN_CLOSE,
55cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_OPEN,
56cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_CLOSE,
57cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_FREE_DB,
58cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_OPEN_FAIL,
59cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_OPEN,
60cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_FAIL,
61cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_DISC_INT_RES,
62cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_DO_OPEN,
63cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_DISC_FAIL,
64cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_CLOSE,
65cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_DATA,
66cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_DISC_ACP_RES,
67cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SVC_CONN_OPEN,
68cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SEND_AT_CMD,
69cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_NUM_ACTIONS,
703fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
713fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
721025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
733fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
743fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* type for action functions */
75cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsontypedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data);
763fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
771025687c6679608fe9df918f37011414ffc72b62Hemant Gupta/* action functions table, indexed with action enum */
78cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
79cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
80cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
81cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
82cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
83cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_LISTEN */ bta_hf_client_sco_listen,
84cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
85cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
86cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
87cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
88cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
89cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
90cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
91cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
92cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
93cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
94cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
95cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
96cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
97cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
98cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
99cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
1003fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
1013fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1023fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table information */
103cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define BTA_HF_CLIENT_ACTIONS 2    /* number of actions */
104cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
105cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define BTA_HF_CLIENT_NUM_COLS 3   /* number of columns in state tables */
1063fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1073fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for init state */
108cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
109cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
110cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
111cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
112cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
113cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
114cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
115cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
116cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_INIT_ST},
117cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
118cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_INIT_ST},
119cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_SCO_LISTEN,
120cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
121cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
122cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
123cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
124cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_INIT_ST},
125cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
126cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_INIT_ST},
127cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
128cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_INIT_ST},
129cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
130cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_INIT_ST},
131cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
132cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_INIT_ST},
133cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
134cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
135cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
136cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_INIT_ST},
137cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
138cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
139cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
140cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_INIT_ST},
1413fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
1423fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1433fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for opening state */
144cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
145cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
146cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
147cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
148cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
149cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE,
150cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
151cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
152cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_OPENING_ST},
153cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
154cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_OPENING_ST},
155cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_SCO_LISTEN,
156cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
157cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE,
158cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
159cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
160cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_OPENING_ST},
161cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
162cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
163cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
164cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPENING_ST},
165cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE,
166cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPENING_ST},
167cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE,
168cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_OPENING_ST},
169cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE,
170cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
171cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
172cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
173cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
174cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_OPENING_ST},
175cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
176cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_OPENING_ST},
1773fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
1783fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1793fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for open state */
180cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
181cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
182cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
183cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
184cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
185cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE,
186cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
187cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE,
188cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_OPEN_ST},
189cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE,
190cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_OPEN_ST},
191cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
192cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
193cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
194cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
195cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
196cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_OPEN_ST},
197cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
198cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
199cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE,
200cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPEN_ST},
201cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
202cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPEN_ST},
203cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
204cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_OPEN_ST},
205cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
206cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_OPEN_ST},
207cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE,
208cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
209cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,
210cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_OPEN_ST},
211cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE,
212cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_OPEN_ST},
2133fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
2143fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for closing state */
216cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
217cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
218cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
219cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
220cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
221cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
222cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
223cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
224cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_CLOSING_ST},
225cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
226cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_CLOSING_ST},
227cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
228cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
229cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
230cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
231cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
232cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_CLOSING_ST},
233cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
234cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
235cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
236cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_CLOSING_ST},
237cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
238cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_INIT_ST},
239cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
240cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_CLOSING_ST},
241cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
242cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
243cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
244cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
245cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
246cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
247cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
248cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_CLOSING_ST},
2493fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
2503fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2513fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* type for state table */
252e9e58ced195ec2c983c7723c9cbdabd45eb0f2fdMarie Janssentypedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
2533fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2543fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table */
255cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
256cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
257cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    bta_hf_client_st_closing};
2583fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2591025687c6679608fe9df918f37011414ffc72b62Hemant Gupta/* HF Client control block */
2605eccd90936d606e0070872b247fd3462e9c9c19bSanket AgarwaltBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
2613fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
262bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/* Event handler for the state machine */
263bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
264bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                               BTA_HfClientDisable};
265bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
2663fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
2675eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
268bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal* Function         bta_hf_client_cb_arr_init
269bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*
270bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal* Description      Initialize entire control block array set
271bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*
272bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*
273bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal* Returns          void
274bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*
275bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal******************************************************************************/
276bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwalvoid bta_hf_client_cb_arr_init() {
277bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR));
278bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal
279bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  // reset the handles and make the CBs non-allocated
280bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
281bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    // Allocate the handles in increasing order of indices
282bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
283bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    bta_hf_client_cb_arr.cb[i].is_allocated = false;
284bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  }
285bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal}
286bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal
287bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal/*******************************************************************************
288bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*
2895eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_cb_init
2905eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
2915eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Initialize an HF_Client service control block.
2925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
2935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
2945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          void
2955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
2965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
2975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb) {
298cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("%s", __func__);
2995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  alarm_free(client_cb->collision_timer);
3005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->collision_timer = NULL;
3015eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
3025eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
3035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
3043fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3053fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3063fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3075eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3085eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_resume_open
3095eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3105eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Resume opening process.
3115eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3125eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3135eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          void
3145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3155eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
3165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) {
317cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("%s", __func__);
318cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
319cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* resume opening process.  */
3205eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
3215eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->state = BTA_HF_CLIENT_OPENING_ST;
322bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    tBTA_HF_CLIENT_DATA msg;
3235eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    msg.hdr.layer_specific = client_cb->handle;
324bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    bta_hf_client_start_open(&msg);
325cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
3263fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3273fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3283fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_collision_timer_cback
3315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3325eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      HF Client connection collision timer callback
3335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3345eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3355eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          void
3365eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3375eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
3385eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalstatic void bta_hf_client_collision_timer_cback(void* data) {
339cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("%s", __func__);
3405eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
3413fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
342cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* If the peer haven't opened connection, restart opening process */
3435eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_resume_open(client_cb);
3443fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3453fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3463fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3475eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3485eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_collision_cback
3495eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Get notified about collision.
3515eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3525eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3535eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          void
3545eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3555eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
356cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonvoid bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
357cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                                   uint8_t id, UNUSED_ATTR uint8_t app_id,
3585eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                                   BD_ADDR peer_addr) {
3595eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr);
3605eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
361cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    if (id == BTA_ID_SYS) /* ACL collision */
362cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    {
363cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_WARNING("HF Client found collision (ACL) ...");
364cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    } else if (id == BTA_ID_HS) /* RFCOMM collision */
3653fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    {
366cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_WARNING("HF Client found collision (RFCOMM) ...");
367cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    } else {
368cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_WARNING("HF Client found collision (\?\?\?) ...");
369cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    }
370cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
3715eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->state = BTA_HF_CLIENT_INIT_ST;
372cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
373cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Cancel SDP if it had been started. */
3745eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (client_cb->p_disc_db) {
3755eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
376cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      bta_hf_client_free_db(NULL);
3773fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    }
378cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
379cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* reopen registered server */
380cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Collision may be detected before or after we close servers. */
3815eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // bta_hf_client_start_server();
382cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
383cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Start timer to handle connection opening restart */
3845eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    alarm_set_on_queue(client_cb->collision_timer,
3855eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       BTA_HF_CLIENT_COLLISION_TIMER_MS,
3865eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       bta_hf_client_collision_timer_cback, (void*)client_cb,
3875eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       btu_bta_alarm_queue);
388cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
3893fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3903fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3913fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_api_enable
3945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Handle an API enable event.
3965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
3985eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          void
3995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
401bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
402bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                     tBTA_SEC sec_mask,
403bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                     tBTA_HF_CLIENT_FEAT features,
404bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                     const char* p_service_name) {
405bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* If already registered then return error */
406bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  if (bta_sys_is_register(BTA_ID_HS)) {
4075eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
408bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    return BTA_FAILURE;
409bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
410bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
411bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* register with BTA system manager */
412bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
4131025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
414bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  /* reset the control blocks */
415bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  bta_hf_client_cb_arr_init();
4165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4175eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.p_cback = p_cback;
4185eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.serv_sec_mask = sec_mask;
4195eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.features = features;
4205eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4215eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  /* create SDP records */
4225eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
4235eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
424cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* set same setting as AG does */
425cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
4261025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
427cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
4283fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
429bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* Set the Audio service class bit */
430bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  tBTA_UTL_COD cod;
431bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  cod.service = BTM_COD_SERVICE_AUDIO;
432bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
433bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
434bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* start RFCOMM server */
4355eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_start_server();
436bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
437bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return BTA_SUCCESS;
438bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
439bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
440bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
4415eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4425eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_find_cb_by_handle
4435eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4445eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Finds the control block by handle provided
4455eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4465eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  handle: Handle as obtained from BTA_HfClientOpen call
4475eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4485eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4495eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          Control block corresponding to the handle and NULL if
4505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  none exists
4515eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4525eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
453bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) {
4545eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES
4555eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) {
4565eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1,
4575eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     HF_CLIENT_MAX_DEVICES, handle);
4585eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return NULL;
459bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
4605eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4615eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  // Check if the associated index is allocated. Index is (handle - 1).
4625eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated)
4635eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return &(bta_hf_client_cb_arr.cb[handle - 1]);
4645eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4655eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
466bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return NULL;
467bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
468bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
469bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
4705eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4715eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_find_cb_by_bda
4725eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4735eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Finds the control block by handle provided
4745eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4755eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  bda: BD_ADDR of the device to find the handle for.
4765eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  Since there can only be one HF connection for a device
4775eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  we should always find a unique block
4785eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4795eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          Control block corresponding to the BD_ADDR and NULL if
4805eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  none exists
4815eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
4825eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
483bd3ae7cbf195caf91693046147b34d25b6317485Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const BD_ADDR peer_addr) {
4845eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
4855eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Check if the associated index is allocated and that BD ADDR matches
4865eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
487bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    if (client_cb->is_allocated && !bdcmp(peer_addr, client_cb->peer_addr)) {
4885eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      return client_cb;
4895eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    } else {
4905eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__,
4915eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                         i, client_cb->is_allocated);
4925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
4935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
4945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: block not found", __func__);
4955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  return NULL;
4965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal}
4975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4985eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal/*******************************************************************************
4995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_find_cb_by_rfc_handle
5015eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5025eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Finds the control block by RFC handle provided.
5035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5045eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  handle: RFC handle for the established connection
5055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5075eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          Control block corresponding to the handle and NULL if none
5085eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  exists
5095eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5105eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
511bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) {
5125eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
5135eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
5145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bool is_allocated = client_cb->is_allocated;
5155eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    uint16_t conn_handle = client_cb->conn_handle;
5165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5175eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__,
5185eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     handle, is_allocated, conn_handle);
5195eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5205eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (is_allocated && conn_handle == handle) {
521bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal      return client_cb;
522bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    }
5235eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5245eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__,
5255eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       handle, is_allocated, conn_handle);
526bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
5275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle);
529bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return NULL;
530bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
531bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
532bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
5335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5345eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_find_cb_by_sco_handle
5355eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5365eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Finds the control block by sco handle provided
5375eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5385eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  handle: sco handle
5395eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5405eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5415eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          Control block corresponding to the sco handle and
5425eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  none if none exists
5435eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5445eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
545bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) {
5465eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
5475eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
5485eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (client_cb->is_allocated && client_cb->sco_idx == handle) {
5495eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      return client_cb;
5505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
551bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
552bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
553bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return NULL;
554bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
555bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
556bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
5575eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5585eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_allocate_handle
5595eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5605eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Allocates a handle for the new BD ADDR that needs a new RF
5615eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  channel for HF connection. If the channel cannot be created
5625eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  for a reason then false is returned
5635eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
564bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*                  bd_addr: Address of the device for which this block is
565bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal*                  being created. Single device can only have one block.
5665eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  p_handle: OUT variable to store the outcome of allocate. If
5675eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*                  allocate failed then value is not valid
5685eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5695eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5705eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          true if the creation of p_handle succeeded, false otherwise
5715eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
5725eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
573bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwalbool bta_hf_client_allocate_handle(const BD_ADDR bd_addr, uint16_t* p_handle) {
574bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  tBTA_HF_CLIENT_CB* existing_cb;
575bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  if ((existing_cb = bta_hf_client_find_cb_by_bda(bd_addr)) != NULL) {
576bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists",
577bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal                     __func__);
578bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    return false;
579bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  }
580bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* Check that we do not have a request to for same device in the control
581bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal   * blocks */
5825eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
5835eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
5845eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (client_cb->is_allocated) {
5855eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      APPL_TRACE_WARNING("%s: control block already used index %d", __func__,
5865eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                         i);
5875eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      continue;
5885eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
5895eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5905eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    *p_handle = client_cb->handle;
5915eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->is_allocated = true;
592bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    bdcpy(client_cb->peer_addr, bd_addr);
5935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Reset the handle for use (i.e. reset timers etc)
5955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_cb_init(client_cb);
5965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_at_init(client_cb);
5975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return true;
598bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
599bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
6005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  return false;
6015eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: all control blocks in use!", __func__);
6023fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
6033fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6043fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
6058af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal * Function         bta_hf_client_app_callback
6078af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6085eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal * Description      Calls the application callback
6098af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6108af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6115eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal * Returns          Void
6128af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6138af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
6145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) {
6155eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (bta_hf_client_cb_arr.p_cback != NULL) {
6165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_cb_arr.p_cback(event, data);
6175eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
6185eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal}
6195eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
6205eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal/*******************************************************************************
6215eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
6225eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Function         bta_hf_client_api_disable
6235eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
6245eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Description      Handle an API disable event.
6255eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
6265eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
6275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal* Returns          void
6285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal*
6295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal******************************************************************************/
630bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalvoid bta_hf_client_api_disable() {
631cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  if (!bta_sys_is_register(BTA_ID_HS)) {
632bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    APPL_TRACE_WARNING("BTA HF Client is already disabled, ignoring ...");
633cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return;
634cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
6353fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
636bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* Remove the collision handler */
637bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_sys_collision_register(BTA_ID_HS, NULL);
6383fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6395eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.deregister = true;
6403fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
641bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* remove sdp record */
6425eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_del_record(&bta_hf_client_cb_arr);
643bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
644bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* remove rfcomm server */
6455eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_close_server();
646bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
647bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* reinit the control block */
6485eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
6495eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (bta_hf_client_cb_arr.cb[i].is_allocated) {
6505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]));
6515eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
6525eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
653bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
654bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* De-register with BTA system manager */
655bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_sys_deregister(BTA_ID_HS);
6563fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
6573fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6583fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
6598af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6608af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Function         bta_hf_client_hdl_event
6618af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6628af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Description      Data HF Client main event handling function.
6638af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6648af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6658af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Returns          bool
6668af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6678af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
668cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonbool bta_hf_client_hdl_event(BT_HDR* p_msg) {
669bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__,
670cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                   bta_hf_client_evt_str(p_msg->event), p_msg->event);
671bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
672cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  return true;
6733fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
6743fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6753fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
6768af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6778af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Function         bta_hf_client_sm_execute
6788af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6798af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Description      State machine event handling function for HF Client
6808af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6818af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6828af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Returns          void
6838af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6848af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
685cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonvoid bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
6865eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  tBTA_HF_CLIENT_CB* client_cb =
6875eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
6885eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb == NULL) {
6895eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
6905eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     p_data->hdr.layer_specific);
6915eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return;
6925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
6935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
694cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  tBTA_HF_CLIENT_ST_TBL state_table;
695cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  uint8_t action;
696cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  int i;
6973fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
698cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  uint16_t in_event = event;
6995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  uint8_t in_state = client_cb->state;
700cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
701cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* Ignore displaying of AT results when not connected (Ignored in state
702cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson   * machine) */
7035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
704cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
7055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     client_cb->state,
7065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     bta_hf_client_state_str(client_cb->state), event,
707cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                     bta_hf_client_evt_str(event));
708cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7093fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
710cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  event &= 0x00FF;
711cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
712cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
713cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return;
714cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
716cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* look up the state table for the current state */
7175eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  state_table = bta_hf_client_st_tbl[client_cb->state];
7183fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
719cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* set next state */
7205eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
721bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
722cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* execute action functions */
723cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
724f33b6f434f086b20fabe5913016bc423ac975057Marie Janssen    action = state_table[event][i];
725f33b6f434f086b20fabe5913016bc423ac975057Marie Janssen    if (action != BTA_HF_CLIENT_IGNORE) {
726cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      (*bta_hf_client_action[action])(p_data);
727cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    } else {
728cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
7293fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    }
730cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7311025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
732bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* if the next state is INIT then release the cb for future use */
7335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
7345eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->is_allocated = false;
735bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
736bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
7375eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_EVENT(
7385eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      "%s: device %02x:%02x:%02x:%02x:%02x:%02x "
7395eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      "state change: [%s] -> [%s] after Event [%s]",
7405eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      __func__, client_cb->peer_addr[0], client_cb->peer_addr[1],
7415eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      client_cb->peer_addr[2], client_cb->peer_addr[3], client_cb->peer_addr[4],
7425eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      client_cb->peer_addr[5], bta_hf_client_state_str(in_state),
7435eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_state_str(client_cb->state),
7445eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_evt_str(in_event));
7453fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
7463fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
7475eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalstatic void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
7485eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
7491025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_bia(client_cb);
7515eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_ccwa(client_cb, true);
7525eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_cmee(client_cb, true);
7535eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_cops(client_cb, false);
7545eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_btrh(client_cb, true, 0);
7555eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_clip(client_cb, true);
7561025687c6679608fe9df918f37011414ffc72b62Hemant Gupta}
7571025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7583fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
7598af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7608af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Function         bta_hf_client_slc_seq
7618af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7628af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Description      Handles AT commands sequence required for SLC creation
7638af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7648af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7658af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Returns          void
7668af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7678af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
768bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalvoid bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
769cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u",
7705eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                   client_cb->at_cb.current_cmd);
7713fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
772cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  if (error) {
773cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SLC establishment error, sent close rfcomm event */
774cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    APPL_TRACE_ERROR(
775cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson        "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
7765eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        client_cb->at_cb.current_cmd);
7771025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7785eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_DATA msg;
7795eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    msg.hdr.layer_specific = client_cb->handle;
7805eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
781cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return;
782cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7831025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7845eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->svc_conn) return;
7851025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7865eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  switch (client_cb->at_cb.current_cmd) {
7871025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_NONE:
7885eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features);
789cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
7903fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
7911025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_BRSF:
7925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) &&
7935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal          (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) {
7945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        bta_hf_client_send_at_bac(client_cb);
7951025687c6679608fe9df918f37011414ffc72b62Hemant Gupta        break;
796cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      }
797cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
7985eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cind(client_cb, false);
799cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8003fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8011025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_BAC:
8025eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cind(client_cb, false);
803cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8043fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8051025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_CIND:
8065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cind(client_cb, true);
807cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8081025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8091025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_CIND_STATUS:
8105eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cmer(client_cb, true);
811cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8121025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8131025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_CMER:
8145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
8155eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal          bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
8165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        bta_hf_client_send_at_chld(client_cb, '?', 0);
817cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      } else {
818bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal        tBTA_HF_CLIENT_DATA msg;
8195eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        msg.hdr.layer_specific = client_cb->handle;
820bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal        bta_hf_client_svc_conn_open(&msg);
8215eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        send_post_slc_cmd(client_cb);
822cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      }
823cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8241025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8255eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    case BTA_HF_CLIENT_AT_CHLD: {
826bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal      tBTA_HF_CLIENT_DATA msg;
8275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      msg.hdr.layer_specific = client_cb->handle;
828bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal      bta_hf_client_svc_conn_open(&msg);
8295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      send_post_slc_cmd(client_cb);
830cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
8321025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    default: {
834cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      /* If happen there is a bug in SLC creation procedure... */
835cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_ERROR(
836cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson          "HFPClient: Failed to create SLCdue to unexpected AT command, "
837cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson          "disconnecting (%u)",
8385eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal          client_cb->at_cb.current_cmd);
839cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
8405eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      tBTA_HF_CLIENT_DATA msg;
8415eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      msg.hdr.layer_specific = client_cb->handle;
8425eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
843cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8445eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
845cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
8463fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
8473fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8481025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#ifndef CASE_RETURN_STR
849cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define CASE_RETURN_STR(const) \
850cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  case const:                  \
851cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return #const;
8521025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#endif
8531025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
854bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_evt_str(uint16_t event) {
855cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  switch (event) {
8561025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
8571025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
8581025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
8591025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
8601025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
8611025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
8621025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
8631025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
8641025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
8651025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
8661025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
8671025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
8681025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
8691025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
8701025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
8711025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
8721025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
8733fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    default:
874cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      return "Unknown HF Client Event";
875cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
8763fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
8773fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
878bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_state_str(uint8_t state) {
879cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  switch (state) {
8801025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
8811025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
8821025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
8831025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
8843fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    default:
885cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      return "Unknown HF Client State";
886cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
8873fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
8885eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
8895eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_dump_statistics(int fd) {
8905eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  dprintf(fd, "\nBluetooth HF Client BTA Statistics\n");
8915eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
8925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  // We dump statistics for all control blocks
8935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
8945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
8955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    dprintf(fd, "Contol block #%d\n", i + 1);
8965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
8975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (!client_cb->is_allocated) {
8985eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      dprintf(fd, "NOT ALLOCATED\n");
8995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      continue;
9005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
9015eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9025eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Device name
9035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    dprintf(fd, "Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n",
9045eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            client_cb->peer_addr[0], client_cb->peer_addr[1],
9055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            client_cb->peer_addr[2], client_cb->peer_addr[3],
9065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            client_cb->peer_addr[4], client_cb->peer_addr[5]);
9075eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9085eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // State machine state
9095eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    dprintf(fd, "State Machine State: %s\n",
9105eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            bta_hf_client_state_str(client_cb->state));
9115eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9125eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Local RFC channelfor communication
9135eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    dprintf(fd, "RFCOMM Channel (local) %d\n", client_cb->conn_handle);
9145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9155eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // BTA Handle shared between BTA and client (ex BTIF)
9165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    dprintf(fd, "BTA Generated handle %d\n", client_cb->handle);
9175eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
9185eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal}
919