13fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/******************************************************************************
23fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta *
36664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal *  Copyright (c) 2016 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
2071f5b3ee55b95d86637e37ea5e7deef25f98637dJakub Pawlowski#include <stdio.h>
211025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include <stdlib.h>
22cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include <string.h>
23303b6ff16e1d257a491d2ae4fac2cd1b78850f67Arman Uguray
241025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include "bt_utils.h"
253fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta#include "bta_api.h"
261025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include "bta_hf_client_api.h"
271025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#include "bta_hf_client_int.h"
28cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include "bta_sys.h"
295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal#include "btcore/include/bdaddr.h"
30cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include "osi/include/osi.h"
31cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#include "osi/include/properties.h"
32bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal#include "utl.h"
333fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
34cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonextern fixed_queue_t* btu_bta_alarm_queue;
3578bcff79e1b1f0efce436b33bdd6da88745bfc8aPavlin Radoslavov
36bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_evt_str(uint16_t event);
37bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_state_str(uint8_t state);
386664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwalvoid bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle);
39bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
403fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state machine states */
41cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonenum {
42cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_INIT_ST,
43cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_OPENING_ST,
44cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_OPEN_ST,
45cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_CLOSING_ST
463fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
473fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
483fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state machine action enumeration list */
49cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonenum {
50cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_DO_CLOSE,
51cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_START_CLOSE,
52cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_START_OPEN,
53cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_ACP_OPEN,
54cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_LISTEN,
55cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_CONN_OPEN,
56cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_CONN_CLOSE,
57cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_OPEN,
58cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SCO_CLOSE,
59cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_FREE_DB,
60cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_OPEN_FAIL,
61cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_OPEN,
62cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_FAIL,
63cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_DISC_INT_RES,
64cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_DO_OPEN,
65cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_DISC_FAIL,
66cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_CLOSE,
67cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_RFC_DATA,
68cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_DISC_ACP_RES,
69cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SVC_CONN_OPEN,
70cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_SEND_AT_CMD,
71cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTA_HF_CLIENT_NUM_ACTIONS,
723fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
733fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
741025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#define BTA_HF_CLIENT_IGNORE BTA_HF_CLIENT_NUM_ACTIONS
753fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
763fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* type for action functions */
77cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsontypedef void (*tBTA_HF_CLIENT_ACTION)(tBTA_HF_CLIENT_DATA* p_data);
783fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
791025687c6679608fe9df918f37011414ffc72b62Hemant Gupta/* action functions table, indexed with action enum */
80cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst tBTA_HF_CLIENT_ACTION bta_hf_client_action[] = {
81cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_DO_CLOSE */ bta_hf_client_rfc_do_close,
82cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_START_CLOSE */ bta_hf_client_start_close,
83cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_START_OPEN */ bta_hf_client_start_open,
84cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_ACP_OPEN */ bta_hf_client_rfc_acp_open,
85ac109dc2256b90c5704bed20e4d15f2400502eaaSanket Agarwal    /* BTA_HF_CLIENT_SCO_LISTEN */ NULL,
86cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_CONN_OPEN */ bta_hf_client_sco_conn_open,
87cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_CONN_CLOSE*/ bta_hf_client_sco_conn_close,
88cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_OPEN */ bta_hf_client_sco_open,
89cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SCO_CLOSE */ bta_hf_client_sco_close,
90cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_FREE_DB */ bta_hf_client_free_db,
91cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_OPEN_FAIL */ bta_hf_client_open_fail,
92cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_OPEN */ bta_hf_client_rfc_open,
93cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_FAIL */ bta_hf_client_rfc_fail,
94cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_DISC_INT_RES */ bta_hf_client_disc_int_res,
95cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_DO_OPEN */ bta_hf_client_rfc_do_open,
96cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_DISC_FAIL */ bta_hf_client_disc_fail,
97cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_CLOSE */ bta_hf_client_rfc_close,
98cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_RFC_DATA */ bta_hf_client_rfc_data,
99cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_DISC_ACP_RES */ bta_hf_client_disc_acp_res,
100cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SVC_CONN_OPEN */ bta_hf_client_svc_conn_open,
101cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* BTA_HF_CLIENT_SEND_AT_CMD */ bta_hf_client_send_at_cmd,
1023fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
1033fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1043fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table information */
105cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define BTA_HF_CLIENT_ACTIONS 2    /* number of actions */
106cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define BTA_HF_CLIENT_NEXT_STATE 2 /* position of next state */
107cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define BTA_HF_CLIENT_NUM_COLS 3   /* number of columns in state tables */
1083fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1093fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for init state */
110cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_init[][BTA_HF_CLIENT_NUM_COLS] = {
111cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
112cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
113cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_START_OPEN, BTA_HF_CLIENT_IGNORE,
114cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
115cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
116cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
117cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
118cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_INIT_ST},
119cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
120cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_INIT_ST},
121ac109dc2256b90c5704bed20e4d15f2400502eaaSanket Agarwal    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_ACP_OPEN, BTA_HF_CLIENT_IGNORE,
122cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
123cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
124cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
125cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
126cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_INIT_ST},
127cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
128cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_INIT_ST},
129cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
130cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_INIT_ST},
131cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
132cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_INIT_ST},
133cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
134cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_INIT_ST},
135cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
136cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
137cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
138cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_INIT_ST},
139cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
140cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
141cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
142cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_INIT_ST},
1433fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
1443fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1453fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for opening state */
146cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_opening[][BTA_HF_CLIENT_NUM_COLS] = {
147cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
148cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
149cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
150cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
151cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_DO_CLOSE, BTA_HF_CLIENT_IGNORE,
152cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
153cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
154cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_OPENING_ST},
155cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
156cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_OPENING_ST},
157ac109dc2256b90c5704bed20e4d15f2400502eaaSanket Agarwal    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_RFC_OPEN, BTA_HF_CLIENT_IGNORE,
158cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
159cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_FAIL, BTA_HF_CLIENT_IGNORE,
160cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
161cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
162cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_OPENING_ST},
163cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
164cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
165cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
166cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPENING_ST},
167cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_DISC_INT_RES, BTA_HF_CLIENT_IGNORE,
168cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPENING_ST},
169cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_RFC_DO_OPEN, BTA_HF_CLIENT_IGNORE,
170cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_OPENING_ST},
171cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_DISC_FAIL, BTA_HF_CLIENT_IGNORE,
172cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
173cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
174cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPENING_ST},
175cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
176cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_OPENING_ST},
177cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
178cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_OPENING_ST},
1793fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
1803fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
1813fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for open state */
182cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_open[][BTA_HF_CLIENT_NUM_COLS] = {
183cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
184cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
185cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
186cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
187cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_START_CLOSE, BTA_HF_CLIENT_IGNORE,
188cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
189cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_OPEN, BTA_HF_CLIENT_IGNORE,
190cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_OPEN_ST},
191cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CLOSE, BTA_HF_CLIENT_IGNORE,
192cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_OPEN_ST},
193cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
194cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
195cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
196cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
197cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
198cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_OPEN_ST},
199cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
200cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
201cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_DISC_ACP_RES, BTA_HF_CLIENT_IGNORE,
202cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPEN_ST},
203cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
204cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_OPEN_ST},
205cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
206cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_OPEN_ST},
207cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
208cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_OPEN_ST},
209cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_SCO_CONN_OPEN, BTA_HF_CLIENT_IGNORE,
210cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_OPEN_ST},
211cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_SCO_CONN_CLOSE, BTA_HF_CLIENT_IGNORE,
212cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_OPEN_ST},
213cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_SEND_AT_CMD, BTA_HF_CLIENT_IGNORE,
214cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_OPEN_ST},
2153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
2163fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2173fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table for closing state */
218cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst uint8_t bta_hf_client_st_closing[][BTA_HF_CLIENT_NUM_COLS] = {
219cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Event                    Action 1                       Action 2
220cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson       Next state */
221cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_OPEN_EVT */ {BTA_HF_CLIENT_OPEN_FAIL, BTA_HF_CLIENT_IGNORE,
222cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
223cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
224cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
225cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
226cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                              BTA_HF_CLIENT_CLOSING_ST},
227cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* API_AUDIO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
228cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                               BTA_HF_CLIENT_CLOSING_ST},
229cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
230cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
231cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_CLOSE_EVT */ {BTA_HF_CLIENT_RFC_CLOSE, BTA_HF_CLIENT_IGNORE,
232cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_INIT_ST},
233cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_SRV_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
234cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                             BTA_HF_CLIENT_CLOSING_ST},
235cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* RFC_DATA_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
236cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
237cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_ACP_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
238cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_CLOSING_ST},
239cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_INT_RES_EVT */ {BTA_HF_CLIENT_FREE_DB, BTA_HF_CLIENT_IGNORE,
240cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                            BTA_HF_CLIENT_INIT_ST},
241cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_OK_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
242cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                       BTA_HF_CLIENT_CLOSING_ST},
243cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* DISC_FAIL_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
244cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
245cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_OPEN_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
246cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                        BTA_HF_CLIENT_CLOSING_ST},
247cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SCO_CLOSE_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
248cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                         BTA_HF_CLIENT_CLOSING_ST},
249cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SEND_AT_CMD_EVT */ {BTA_HF_CLIENT_IGNORE, BTA_HF_CLIENT_IGNORE,
250cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                           BTA_HF_CLIENT_CLOSING_ST},
2513fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta};
2523fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2533fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* type for state table */
254e9e58ced195ec2c983c7723c9cbdabd45eb0f2fdMarie Janssentypedef const uint8_t (*tBTA_HF_CLIENT_ST_TBL)[BTA_HF_CLIENT_NUM_COLS];
2553fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2563fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/* state table */
257cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonconst tBTA_HF_CLIENT_ST_TBL bta_hf_client_st_tbl[] = {
258cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    bta_hf_client_st_init, bta_hf_client_st_opening, bta_hf_client_st_open,
259cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    bta_hf_client_st_closing};
2603fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
2611025687c6679608fe9df918f37011414ffc72b62Hemant Gupta/* HF Client control block */
2625eccd90936d606e0070872b247fd3462e9c9c19bSanket AgarwaltBTA_HF_CLIENT_CB_ARR bta_hf_client_cb_arr;
2633fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
264bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/* Event handler for the state machine */
265bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const tBTA_SYS_REG bta_hf_client_reg = {bta_hf_client_hdl_event,
266bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                               BTA_HfClientDisable};
267bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
2683fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
2690ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2700ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_cb_arr_init
2710ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2720ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Initialize entire control block array set
2730ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2740ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2750ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
2760ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2770ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
278bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwalvoid bta_hf_client_cb_arr_init() {
279bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  memset(&bta_hf_client_cb_arr, 0, sizeof(tBTA_HF_CLIENT_CB_ARR));
280bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal
281bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  // reset the handles and make the CBs non-allocated
282bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
283bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    // Allocate the handles in increasing order of indices
2846664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
285bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    bta_hf_client_cb_arr.cb[i].handle = BTA_HF_CLIENT_CB_FIRST_HANDLE + i;
286bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  }
287bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal}
288bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal
289bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal/*******************************************************************************
2900ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2910ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_cb_init
2920ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2930ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Initialize an HF_Client service control block. Assign the
2940ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  handle to cb->handle.
2950ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2960ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2970ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
2980ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
2990ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3000ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
3016664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwalvoid bta_hf_client_cb_init(tBTA_HF_CLIENT_CB* client_cb, uint16_t handle) {
302cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("%s", __func__);
3036664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal
3046664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  // Free any memory we need to explicity release
3055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  alarm_free(client_cb->collision_timer);
3066664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal
3076664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  // Memset the rest of the block
3086664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  memset(client_cb, 0, sizeof(tBTA_HF_CLIENT_CB));
3096664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal
3106664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  // Re allocate any variables required
3115eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->collision_timer = alarm_new("bta_hf_client.scb_collision_timer");
3126664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  client_cb->handle = handle;
313882760d186f7b49b5681f7ddd1c296706eb80bd8Sanket Agarwal  client_cb->sco_idx = BTM_INVALID_SCO_INDEX;
3143fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3163fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3170ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3180ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_resume_open
3190ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3200ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Resume opening process.
3210ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3220ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3230ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
3240ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3250ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
3265eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_resume_open(tBTA_HF_CLIENT_CB* client_cb) {
327cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("%s", __func__);
328cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
329cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* resume opening process.  */
3305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
3315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->state = BTA_HF_CLIENT_OPENING_ST;
332bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    tBTA_HF_CLIENT_DATA msg;
3335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    msg.hdr.layer_specific = client_cb->handle;
334bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    bta_hf_client_start_open(&msg);
335cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
3363fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3373fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3383fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3390ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3400ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_collision_timer_cback
3410ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3420ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      HF Client connection collision timer callback
3430ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3440ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3450ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
3460ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3470ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
3485eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalstatic void bta_hf_client_collision_timer_cback(void* data) {
349cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("%s", __func__);
3505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  tBTA_HF_CLIENT_CB* client_cb = (tBTA_HF_CLIENT_CB*)data;
3513fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
352cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* If the peer haven't opened connection, restart opening process */
3535eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_resume_open(client_cb);
3543fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
3553fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
3563fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
3570ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3580ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_collision_cback
3590ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3600ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Get notified about collision.
3610ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3620ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3630ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
3640ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
3650ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
366cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonvoid bta_hf_client_collision_cback(UNUSED_ATTR tBTA_SYS_CONN_STATUS status,
367cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                                   uint8_t id, UNUSED_ATTR uint8_t app_id,
3685eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                                   BD_ADDR peer_addr) {
3695eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_bda(peer_addr);
3705eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb != NULL && client_cb->state == BTA_HF_CLIENT_OPENING_ST) {
371cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    if (id == BTA_ID_SYS) /* ACL collision */
372cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    {
373cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_WARNING("HF Client found collision (ACL) ...");
374cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    } else if (id == BTA_ID_HS) /* RFCOMM collision */
3753fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    {
376cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_WARNING("HF Client found collision (RFCOMM) ...");
377cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    } else {
378cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_WARNING("HF Client found collision (\?\?\?) ...");
379cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    }
380cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
3815eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->state = BTA_HF_CLIENT_INIT_ST;
382cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
383cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Cancel SDP if it had been started. */
3845eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (client_cb->p_disc_db) {
3855eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      (void)SDP_CancelServiceSearch(client_cb->p_disc_db);
386cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      bta_hf_client_free_db(NULL);
3873fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    }
388cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
389cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* reopen registered server */
390cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Collision may be detected before or after we close servers. */
3915eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // bta_hf_client_start_server();
392cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
393cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* Start timer to handle connection opening restart */
3945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    alarm_set_on_queue(client_cb->collision_timer,
3955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       BTA_HF_CLIENT_COLLISION_TIMER_MS,
3965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       bta_hf_client_collision_timer_cback, (void*)client_cb,
3975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       btu_bta_alarm_queue);
398cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
3993fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
4003fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
4013fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
4020ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4030ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_api_enable
4040ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4050ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Handle an API enable event.
4060ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4070ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4080ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
4090ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4100ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
411bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_STATUS bta_hf_client_api_enable(tBTA_HF_CLIENT_CBACK* p_cback,
412bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                     tBTA_SEC sec_mask,
413bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                     tBTA_HF_CLIENT_FEAT features,
414bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal                                     const char* p_service_name) {
415bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* If already registered then return error */
416bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  if (bta_sys_is_register(BTA_ID_HS)) {
4175eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_ERROR("BTA HF Client is already enabled, ignoring ...");
418bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    return BTA_FAILURE;
419bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
420bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
421bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* register with BTA system manager */
422bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_sys_register(BTA_ID_HS, &bta_hf_client_reg);
4231025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
424bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  /* reset the control blocks */
425bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  bta_hf_client_cb_arr_init();
4265eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.p_cback = p_cback;
4285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.serv_sec_mask = sec_mask;
4295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.features = features;
4305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  /* create SDP records */
4325eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_create_record(&bta_hf_client_cb_arr, p_service_name);
4335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
434cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* set same setting as AG does */
435cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  BTM_WriteVoiceSettings(AG_VOICE_SETTINGS);
4361025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
437cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  bta_sys_collision_register(BTA_ID_HS, bta_hf_client_collision_cback);
4383fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
439bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* Set the Audio service class bit */
440bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  tBTA_UTL_COD cod;
441bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  cod.service = BTM_COD_SERVICE_AUDIO;
442bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
443bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
444bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* start RFCOMM server */
4455eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_start_server();
446bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
447bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return BTA_SUCCESS;
448bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
449bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
450bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
4510ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4520ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_find_cb_by_handle
4530ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4540ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Finds the control block by handle provided
4550ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4560ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  handle: Handle as obtained from BTA_HfClientOpen call
4570ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4580ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4590ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          Control block corresponding to the handle and NULL if
4600ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  none exists
4610ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4620ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
463bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_handle(uint16_t handle) {
4645eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  // Handles are limited from 1 through HF_CLIENT_MAX_DEVICES
4655eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (handle < 1 || handle > HF_CLIENT_MAX_DEVICES) {
4665eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_ERROR("%s: handle out of range (%d, %d) %d", __func__, 1,
4675eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     HF_CLIENT_MAX_DEVICES, handle);
4685eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return NULL;
469bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
4705eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4715eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  // Check if the associated index is allocated. Index is (handle - 1).
4725eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (bta_hf_client_cb_arr.cb[handle - 1].is_allocated)
4735eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return &(bta_hf_client_cb_arr.cb[handle - 1]);
4745eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
4755eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
476bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return NULL;
477bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
478bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
479bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
4800ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4810ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_find_cb_by_bda
4820ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4830ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Finds the control block by handle provided
4840ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4850ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  bda: BD_ADDR of the device to find the handle for.
4860ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  Since there can only be one HF connection for a device
4870ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  we should always find a unique block
4880ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4890ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          Control block corresponding to the BD_ADDR and NULL if
4900ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  none exists
4910ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
4920ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
493bd3ae7cbf195caf91693046147b34d25b6317485Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_bda(const BD_ADDR peer_addr) {
4945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
4955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Check if the associated index is allocated and that BD ADDR matches
4965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
497bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    if (client_cb->is_allocated && !bdcmp(peer_addr, client_cb->peer_addr)) {
4985eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      return client_cb;
4995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    } else {
5005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      APPL_TRACE_WARNING("%s: bdaddr mismatch for handle %d alloc %d", __func__,
5015eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                         i, client_cb->is_allocated);
5025eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
5035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
5045eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: block not found", __func__);
5055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  return NULL;
5065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal}
5075eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5085eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal/*******************************************************************************
5090ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5100ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_find_cb_by_rfc_handle
5110ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5120ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Finds the control block by RFC handle provided.
5130ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5140ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  handle: RFC handle for the established connection
5150ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5160ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5170ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          Control block corresponding to the handle and NULL if none
5180ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  exists
5190ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5200ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
521bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_rfc_handle(uint16_t handle) {
5225eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
5235eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
5245eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bool is_allocated = client_cb->is_allocated;
5255eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    uint16_t conn_handle = client_cb->conn_handle;
5265eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_DEBUG("%s: cb rfc_handle %d alloc %d conn_handle %d", __func__,
5285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     handle, is_allocated, conn_handle);
5295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (is_allocated && conn_handle == handle) {
531bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal      return client_cb;
532bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    }
5335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5345eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_WARNING("%s: no cb yet %d alloc %d conn_handle %d", __func__,
5355eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                       handle, is_allocated, conn_handle);
536bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
5375eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
5385eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: no cb found for rfc handle %d", __func__, handle);
539bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return NULL;
540bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
541bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
542bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
5430ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5440ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_find_cb_by_sco_handle
5450ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5460ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Finds the control block by sco handle provided
5470ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5480ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  handle: sco handle
5490ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5500ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5510ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          Control block corresponding to the sco handle and
5520ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  none if none exists
5530ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5540ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
555bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket AgarwaltBTA_HF_CLIENT_CB* bta_hf_client_find_cb_by_sco_handle(uint16_t handle) {
5565eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
5575eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
5585eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (client_cb->is_allocated && client_cb->sco_idx == handle) {
5595eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      return client_cb;
5605eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
561bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
562bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  APPL_TRACE_ERROR("%s: block not found for handle %d", __func__, handle);
563bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  return NULL;
564bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal}
565bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
566bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal/*******************************************************************************
5670ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5680ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_allocate_handle
5690ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5700ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Allocates a handle for the new BD ADDR that needs a new RF
5710ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  channel for HF connection. If the channel cannot be created
5720ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  for a reason then false is returned
5730ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5740ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  bd_addr: Address of the device for which this block is
5750ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  being created. Single device can only have one block.
5760ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  p_handle: OUT variable to store the outcome of allocate. If
5770ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *                  allocate failed then value is not valid
5780ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5790ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5800ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          true if the creation of p_handle succeeded, false otherwise
5810ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
5820ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
583bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwalbool bta_hf_client_allocate_handle(const BD_ADDR bd_addr, uint16_t* p_handle) {
584f9c5752344ec459def74765f512d28fa0f402168Marie Janssen  tBTA_HF_CLIENT_CB* existing_cb = bta_hf_client_find_cb_by_bda(bd_addr);
585f9c5752344ec459def74765f512d28fa0f402168Marie Janssen  if (existing_cb != NULL) {
586bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    BTIF_TRACE_ERROR("%s: cannot allocate handle since BDADDR already exists",
587bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal                     __func__);
588bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    return false;
589bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal  }
590bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* Check that we do not have a request to for same device in the control
591bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal   * blocks */
5925eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
5935eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
5945eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (client_cb->is_allocated) {
5955eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      APPL_TRACE_WARNING("%s: control block already used index %d", __func__,
5965eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                         i);
5975eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      continue;
5985eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
5995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
6006664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    // Reset the client control block
6016664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    bta_hf_client_cb_init(client_cb, client_cb->handle);
6026664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal
6035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    *p_handle = client_cb->handle;
6046664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    APPL_TRACE_DEBUG("%s: marking CB handle %d to true", __func__,
6056664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal                     client_cb->handle);
6066664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal
6075eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->is_allocated = true;
608bd3ae7cbf195caf91693046147b34d25b6317485Sanket Agarwal    bdcpy(client_cb->peer_addr, bd_addr);
6095eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_at_init(client_cb);
6105eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return true;
611bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
612bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
6135eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  return false;
6145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_ERROR("%s: all control blocks in use!", __func__);
6153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
6163fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6173fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
6188af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6195eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal * Function         bta_hf_client_app_callback
6208af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6215eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal * Description      Calls the application callback
6228af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6238af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6245eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal * Returns          Void
6258af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6268af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
6275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_app_callback(uint16_t event, tBTA_HF_CLIENT* data) {
6285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (bta_hf_client_cb_arr.p_cback != NULL) {
6295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_cb_arr.p_cback(event, data);
6305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
6315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal}
6325eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
6335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal/*******************************************************************************
6340ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
6350ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Function         bta_hf_client_api_disable
6360ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
6370ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Description      Handle an API disable event.
6380ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
6390ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
6400ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson * Returns          void
6410ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson *
6420ec947509d38d15b75bc899b6b7720de4c4fea4fMyles Watson ******************************************************************************/
643bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalvoid bta_hf_client_api_disable() {
644cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  if (!bta_sys_is_register(BTA_ID_HS)) {
645bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal    APPL_TRACE_WARNING("BTA HF Client is already disabled, ignoring ...");
646cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return;
647cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
6483fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
649bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* Remove the collision handler */
650bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_sys_collision_register(BTA_ID_HS, NULL);
6513fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6525eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_cb_arr.deregister = true;
6533fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
654bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* remove sdp record */
6555eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_del_record(&bta_hf_client_cb_arr);
656bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
657bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* remove rfcomm server */
6585eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_close_server();
659bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
660bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* reinit the control block */
6615eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
6625eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (bta_hf_client_cb_arr.cb[i].is_allocated) {
6636664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal      bta_hf_client_cb_init(&(bta_hf_client_cb_arr.cb[i]), i);
6645eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
6655eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
666bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
667bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* De-register with BTA system manager */
668bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_sys_deregister(BTA_ID_HS);
6693fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
6703fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6713fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
6728af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6738af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Function         bta_hf_client_hdl_event
6748af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6758af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Description      Data HF Client main event handling function.
6768af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6778af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6788af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Returns          bool
6798af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6808af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
681cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonbool bta_hf_client_hdl_event(BT_HDR* p_msg) {
682bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  APPL_TRACE_DEBUG("%s: %s (0x%x)", __func__,
683cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                   bta_hf_client_evt_str(p_msg->event), p_msg->event);
684bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  bta_hf_client_sm_execute(p_msg->event, (tBTA_HF_CLIENT_DATA*)p_msg);
685cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  return true;
6863fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
6873fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
6883fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
6898af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6908af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Function         bta_hf_client_sm_execute
6918af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6928af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Description      State machine event handling function for HF Client
6938af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6948af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6958af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Returns          void
6968af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
6978af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
698cd1fd07f1306e08fe048682dd5918987e579f937Myles Watsonvoid bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) {
6995eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  tBTA_HF_CLIENT_CB* client_cb =
7005eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
7015eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb == NULL) {
7025eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
7035eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     p_data->hdr.layer_specific);
7045eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    return;
7055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
7065eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
707cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  tBTA_HF_CLIENT_ST_TBL state_table;
708cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  uint8_t action;
709cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  int i;
7103fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
711cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  uint16_t in_event = event;
7125eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  uint8_t in_state = client_cb->state;
713cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
714cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* Ignore displaying of AT results when not connected (Ignored in state
715cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson   * machine) */
7165eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
717cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    APPL_TRACE_EVENT("HF Client evt : State %d (%s), Event 0x%04x (%s)",
7185eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     client_cb->state,
7195eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                     bta_hf_client_state_str(client_cb->state), event,
720cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson                     bta_hf_client_evt_str(event));
721cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7223fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
723cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  event &= 0x00FF;
724cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  if (event >= (BTA_HF_CLIENT_MAX_EVT & 0x00FF)) {
725cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    APPL_TRACE_ERROR("HF Client evt out of range, ignoring...");
726cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return;
727cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7283fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
729cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* look up the state table for the current state */
7305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  state_table = bta_hf_client_st_tbl[client_cb->state];
7313fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
732cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* set next state */
7335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->state = state_table[event][BTA_HF_CLIENT_NEXT_STATE];
734bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
735cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  /* execute action functions */
736cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  for (i = 0; i < BTA_HF_CLIENT_ACTIONS; i++) {
737f33b6f434f086b20fabe5913016bc423ac975057Marie Janssen    action = state_table[event][i];
738f33b6f434f086b20fabe5913016bc423ac975057Marie Janssen    if (action != BTA_HF_CLIENT_IGNORE) {
739cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      (*bta_hf_client_action[action])(p_data);
740cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    } else {
741cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
7423fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    }
743cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
7441025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7456664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  /* If the state has changed then notify the app of the corresponding change */
7466664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  if (in_state != client_cb->state) {
7476664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    APPL_TRACE_DEBUG(
7486664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal        "%s: notifying state change to %d -> %d "
7496664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal        "device %02x:%02x:%02x:%02x:%02x:%02x",
7506664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal        __func__, in_state, client_cb->state, client_cb->peer_addr[0],
7516664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal        client_cb->peer_addr[1], client_cb->peer_addr[2],
7526664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal        client_cb->peer_addr[3], client_cb->peer_addr[4],
7536664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal        client_cb->peer_addr[5]);
7546664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    tBTA_HF_CLIENT evt;
7556664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    memset(&evt, 0, sizeof(evt));
7566664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    bdcpy(evt.bd_addr, client_cb->peer_addr);
7576664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
7586664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal      bta_hf_client_app_callback(BTA_HF_CLIENT_CLOSE_EVT, &evt);
7596664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    } else if (client_cb->state == BTA_HF_CLIENT_OPEN_ST) {
7606664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal      evt.open.handle = client_cb->handle;
7616664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal      bta_hf_client_app_callback(BTA_HF_CLIENT_OPEN_EVT, &evt);
7626664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    }
7636664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  }
7646664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal
765bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  /* if the next state is INIT then release the cb for future use */
7665eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  if (client_cb->state == BTA_HF_CLIENT_INIT_ST) {
7676664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    APPL_TRACE_DEBUG("%s: marking CB handle %d to false", __func__,
7686664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal                     client_cb->handle);
7695eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    client_cb->is_allocated = false;
770bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal  }
771bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal
7725eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  APPL_TRACE_EVENT(
7735eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      "%s: device %02x:%02x:%02x:%02x:%02x:%02x "
7745eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      "state change: [%s] -> [%s] after Event [%s]",
7755eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      __func__, client_cb->peer_addr[0], client_cb->peer_addr[1],
7765eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      client_cb->peer_addr[2], client_cb->peer_addr[3], client_cb->peer_addr[4],
7775eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      client_cb->peer_addr[5], bta_hf_client_state_str(in_state),
7785eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_state_str(client_cb->state),
7795eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_evt_str(in_event));
7803fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
7813fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
7825eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalstatic void send_post_slc_cmd(tBTA_HF_CLIENT_CB* client_cb) {
7835eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  client_cb->at_cb.current_cmd = BTA_HF_CLIENT_AT_NONE;
7841025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7855eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_bia(client_cb);
7865eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_ccwa(client_cb, true);
7875eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_cmee(client_cb, true);
7885eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_cops(client_cb, false);
7895eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_btrh(client_cb, true, 0);
7905eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  bta_hf_client_send_at_clip(client_cb, true);
7911025687c6679608fe9df918f37011414ffc72b62Hemant Gupta}
7921025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
7933fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta/*******************************************************************************
7948af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7958af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Function         bta_hf_client_slc_seq
7968af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7978af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Description      Handles AT commands sequence required for SLC creation
7988af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
7998af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
8008af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson * Returns          void
8018af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson *
8028af480e24549ba51a3f6858d9d9af504715e0beaMyles Watson ******************************************************************************/
803bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalvoid bta_hf_client_slc_seq(tBTA_HF_CLIENT_CB* client_cb, bool error) {
804cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  APPL_TRACE_DEBUG("bta_hf_client_slc_seq cmd: %u",
8055eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal                   client_cb->at_cb.current_cmd);
8063fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
807cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  if (error) {
808cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    /* SLC establishment error, sent close rfcomm event */
809cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    APPL_TRACE_ERROR(
810cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson        "HFPClient: Failed to create SLC due to AT error, disconnecting (%u)",
8115eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        client_cb->at_cb.current_cmd);
8121025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8135eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_DATA msg;
8145eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    msg.hdr.layer_specific = client_cb->handle;
8155eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
816cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return;
817cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
8181025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8196664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  if (client_cb->svc_conn) {
8206664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    APPL_TRACE_WARNING("%s: SLC already connected for CB handle %d", __func__,
8216664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal                       client_cb->handle);
8226664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal    return;
8236664b2ccbbf0240524bc23c5dc81c690cf4daffaSanket Agarwal  }
8241025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8255eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  switch (client_cb->at_cb.current_cmd) {
8261025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_NONE:
8275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_brsf(client_cb, bta_hf_client_cb_arr.features);
828cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8293fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8301025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_BRSF:
8315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      if ((bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_CODEC) &&
8325eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal          (client_cb->peer_features & BTA_HF_CLIENT_PEER_CODEC)) {
8335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        bta_hf_client_send_at_bac(client_cb);
8341025687c6679608fe9df918f37011414ffc72b62Hemant Gupta        break;
835cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      }
836cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
8375eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cind(client_cb, false);
838cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8393fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8401025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_BAC:
8415eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cind(client_cb, false);
842cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8433fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8441025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_CIND:
8455eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cind(client_cb, true);
846cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8471025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8481025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_CIND_STATUS:
8495eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_send_at_cmer(client_cb, true);
850cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8511025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8521025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    case BTA_HF_CLIENT_AT_CMER:
8535eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      if (client_cb->peer_features & BTA_HF_CLIENT_PEER_FEAT_3WAY &&
8545eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal          bta_hf_client_cb_arr.features & BTA_HF_CLIENT_FEAT_3WAY) {
8555eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        bta_hf_client_send_at_chld(client_cb, '?', 0);
856cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      } else {
857bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal        tBTA_HF_CLIENT_DATA msg;
8585eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        msg.hdr.layer_specific = client_cb->handle;
859bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal        bta_hf_client_svc_conn_open(&msg);
8605eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal        send_post_slc_cmd(client_cb);
861cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      }
862cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8631025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8645eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    case BTA_HF_CLIENT_AT_CHLD: {
865bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal      tBTA_HF_CLIENT_DATA msg;
8665eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      msg.hdr.layer_specific = client_cb->handle;
867bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwal      bta_hf_client_svc_conn_open(&msg);
8685eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      send_post_slc_cmd(client_cb);
869cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8705eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
8711025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
8725eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    default: {
873cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      /* If happen there is a bug in SLC creation procedure... */
874cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      APPL_TRACE_ERROR(
875cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson          "HFPClient: Failed to create SLCdue to unexpected AT command, "
876cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson          "disconnecting (%u)",
8775eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal          client_cb->at_cb.current_cmd);
878cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson
8795eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      tBTA_HF_CLIENT_DATA msg;
8805eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      msg.hdr.layer_specific = client_cb->handle;
8815eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      bta_hf_client_sm_execute(BTA_HF_CLIENT_API_CLOSE_EVT, &msg);
882cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      break;
8835eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
884cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
8853fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
8863fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
8871025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#ifndef CASE_RETURN_STR
888cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson#define CASE_RETURN_STR(const) \
889cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  case const:                  \
890cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson    return #const;
8911025687c6679608fe9df918f37011414ffc72b62Hemant Gupta#endif
8921025687c6679608fe9df918f37011414ffc72b62Hemant Gupta
893bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_evt_str(uint16_t event) {
894cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  switch (event) {
8951025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_OPEN_EVT)
8961025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_CLOSE_EVT)
8971025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_OPEN_EVT)
8981025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_AUDIO_CLOSE_EVT)
8991025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_OPEN_EVT)
9001025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_CLOSE_EVT)
9011025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_SRV_CLOSE_EVT)
9021025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_RFC_DATA_EVT)
9031025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_ACP_RES_EVT)
9041025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_INT_RES_EVT)
9051025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_OK_EVT)
9061025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_DISC_FAIL_EVT)
9071025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_ENABLE_EVT)
9081025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_API_DISABLE_EVT)
9091025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_SCO_OPEN_EVT)
9101025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_SCO_CLOSE_EVT)
9111025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_SEND_AT_CMD_EVT)
9123fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    default:
913cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      return "Unknown HF Client Event";
914cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
9153fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
9163fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta
917bdcfc045f9d21afc1510cdad4fddd97a93c26477Sanket Agarwalstatic const char* bta_hf_client_state_str(uint8_t state) {
918cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  switch (state) {
9191025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_INIT_ST)
9201025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_OPENING_ST)
9211025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_OPEN_ST)
9221025687c6679608fe9df918f37011414ffc72b62Hemant Gupta    CASE_RETURN_STR(BTA_HF_CLIENT_CLOSING_ST)
9233fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta    default:
924cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson      return "Unknown HF Client State";
925cd1fd07f1306e08fe048682dd5918987e579f937Myles Watson  }
9263fe1b49071420903cb8e3082ec04e76296352690Hemant Gupta}
9275eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9285eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwalvoid bta_hf_client_dump_statistics(int fd) {
9295eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  dprintf(fd, "\nBluetooth HF Client BTA Statistics\n");
9305eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9315eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  // We dump statistics for all control blocks
9325eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  for (int i = 0; i < HF_CLIENT_MAX_DEVICES; i++) {
9335eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    tBTA_HF_CLIENT_CB* client_cb = &bta_hf_client_cb_arr.cb[i];
9345eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    if (!client_cb->is_allocated) {
935dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal      // Skip the blocks which are not allocated
9365eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal      continue;
9375eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    }
9385eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
939dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal    dprintf(fd, "  Control block #%d\n", i + 1);
940dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal
9415eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Device name
942dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal    dprintf(fd, "    Peer Device: %02x:%02x:%02x:%02x:%02x:%02x\n",
9435eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            client_cb->peer_addr[0], client_cb->peer_addr[1],
9445eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            client_cb->peer_addr[2], client_cb->peer_addr[3],
9455eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            client_cb->peer_addr[4], client_cb->peer_addr[5]);
9465eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9475eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // State machine state
948dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal    dprintf(fd, "    State Machine State: %s\n",
9495eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal            bta_hf_client_state_str(client_cb->state));
9505eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9515eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // Local RFC channelfor communication
952dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal    dprintf(fd, "    RFCOMM Channel (local) %d\n", client_cb->conn_handle);
9535eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal
9545eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal    // BTA Handle shared between BTA and client (ex BTIF)
955dda9fab7a86661a044251cfceddb60420ed3ba86Sanket Agarwal    dprintf(fd, "    BTA Generated handle %d\n", client_cb->handle);
9565eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal  }
9575eccd90936d606e0070872b247fd3462e9c9c19bSanket Agarwal}
958