blob: b633bd01fba1e374df97851341bbd2c9a8f8baa9 [file] [log] [blame]
Hemant Gupta3fe1b492014-04-29 16:23:59 +05301/******************************************************************************
2 *
Hemant Gupta10256872013-08-19 18:33:01 +05303 * Copyright (c) 2014 The Android Open Source Project
Hemant Gupta3fe1b492014-04-29 16:23:59 +05304 * Copyright (C) 2003-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20/******************************************************************************
21 *
Hemant Gupta10256872013-08-19 18:33:01 +053022 * This file contains action functions for the handsfree client.
Hemant Gupta3fe1b492014-04-29 16:23:59 +053023 *
24 ******************************************************************************/
25
Myles Watsoncd1fd072016-11-09 13:17:43 -080026#include <string.h>
27#include "bt_utils.h"
Hemant Gupta3fe1b492014-04-29 16:23:59 +053028#include "bta_api.h"
Pavlin Radoslavovb2a292b2016-10-14 19:34:48 -070029#include "bta_dm_api.h"
Hemant Gupta10256872013-08-19 18:33:01 +053030#include "bta_hf_client_api.h"
31#include "bta_hf_client_int.h"
Hemant Gupta10256872013-08-19 18:33:01 +053032#include "bta_sys.h"
Myles Watsoncd1fd072016-11-09 13:17:43 -080033#include "l2c_api.h"
Scott James Remnant47d68ee2015-04-02 15:22:29 -070034#include "osi/include/compat.h"
Myles Watsond7ffd642016-10-27 10:27:36 -070035#include "osi/include/osi.h"
Myles Watsoncd1fd072016-11-09 13:17:43 -080036#include "port_api.h"
37#include "utl.h"
Hemant Gupta3fe1b492014-04-29 16:23:59 +053038
39/*****************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -080040 * Constants
41 ****************************************************************************/
Hemant Gupta3fe1b492014-04-29 16:23:59 +053042
43/* maximum length of data to read from RFCOMM */
Myles Watsoncd1fd072016-11-09 13:17:43 -080044#define BTA_HF_CLIENT_RFC_READ_MAX 512
Hemant Gupta3fe1b492014-04-29 16:23:59 +053045
46/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -080047 *
Myles Watson8af480e2016-11-09 10:40:23 -080048 * Function bta_hf_client_start_close
49 *
50 * Description Start the process of closing SCO and RFCOMM connection.
51 *
52 *
53 * Returns void
54 *
55 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -080056void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
Sanket Agarwalbdcfc042016-11-30 19:43:47 -080057 tBTA_HF_CLIENT_CB* client_cb =
58 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
59 if (client_cb == NULL) {
60 APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
61 p_data->hdr.layer_specific);
62 return;
63 }
64
Myles Watsoncd1fd072016-11-09 13:17:43 -080065 /* Take the link out of sniff and set L2C idle time to 0 */
Jakub Pawlowski744eeca2017-06-16 09:35:52 -070066 bta_dm_pm_active(client_cb->peer_addr);
67 L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
Hemant Gupta3fe1b492014-04-29 16:23:59 +053068
Myles Watsoncd1fd072016-11-09 13:17:43 -080069 /* if SCO is open close SCO and wait on RFCOMM close */
Sanket Agarwal5eccd902016-11-30 19:43:47 -080070 if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
71 client_cb->sco_close_rfc = true;
Myles Watsoncd1fd072016-11-09 13:17:43 -080072 } else {
73 bta_hf_client_rfc_do_close(p_data);
74 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +053075
Myles Watsoncd1fd072016-11-09 13:17:43 -080076 /* always do SCO shutdown to handle all SCO corner cases */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -080077 bta_hf_client_sco_shutdown(client_cb);
Hemant Gupta3fe1b492014-04-29 16:23:59 +053078}
79
80/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -080081 *
82 * Function bta_hf_client_start_open
83 *
84 * Description This starts an HF Client open.
85 *
86 *
87 * Returns void
88 *
89 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -080090void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
Sanket Agarwalbdcfc042016-11-30 19:43:47 -080091 tBTA_HF_CLIENT_CB* client_cb =
92 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
93 if (client_cb == NULL) {
94 APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
95 p_data->hdr.layer_specific);
96 return;
97 }
Hemant Gupta10256872013-08-19 18:33:01 +053098
Myles Watsoncd1fd072016-11-09 13:17:43 -080099 /* store parameters */
100 if (p_data) {
Jakub Pawlowski744eeca2017-06-16 09:35:52 -0700101 client_cb->peer_addr = p_data->api_open.bd_addr;
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800102 client_cb->cli_sec_mask = p_data->api_open.sec_mask;
Myles Watsoncd1fd072016-11-09 13:17:43 -0800103 }
Hemant Gupta10256872013-08-19 18:33:01 +0530104
Myles Watsoncd1fd072016-11-09 13:17:43 -0800105 /* Check if RFCOMM has any incoming connection to avoid collision. */
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700106 RawAddress pending_bd_addr;
Jakub Pawlowski1979fa32017-06-16 10:46:47 -0700107 if (PORT_IsOpening(pending_bd_addr)) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800108 /* Let the incoming connection goes through. */
109 /* Issue collision for now. */
110 /* We will decide what to do when we find incoming connection later.*/
Jakub Pawlowskic752e132017-06-16 12:52:23 -0700111 bta_hf_client_collision_cback(0, BTA_ID_HS, 0, &client_cb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800112 return;
113 }
Hemant Gupta10256872013-08-19 18:33:01 +0530114
Myles Watsoncd1fd072016-11-09 13:17:43 -0800115 /* set role */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800116 client_cb->role = BTA_HF_CLIENT_INT;
Hemant Gupta10256872013-08-19 18:33:01 +0530117
Myles Watsoncd1fd072016-11-09 13:17:43 -0800118 /* do service search */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800119 bta_hf_client_do_disc(client_cb);
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530120}
121
122/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800123 *
Myles Watson8af480e2016-11-09 10:40:23 -0800124 * Function bta_hf_client_rfc_open
125 *
126 * Description Handle RFCOMM channel open.
127 *
128 *
129 * Returns void
130 *
131 ******************************************************************************/
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800132void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
133 APPL_TRACE_DEBUG("%s", __func__);
134 tBTA_HF_CLIENT_CB* client_cb =
135 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
136 if (client_cb == NULL) {
137 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
138 p_data->hdr.layer_specific);
139 return;
140 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530141
Jakub Pawlowskic752e132017-06-16 12:52:23 -0700142 bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800143
Myles Watsoncd1fd072016-11-09 13:17:43 -0800144 /* start SLC procedure */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800145 bta_hf_client_slc_seq(client_cb, false);
Hemant Gupta10256872013-08-19 18:33:01 +0530146}
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530147
Hemant Gupta10256872013-08-19 18:33:01 +0530148/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800149 *
150 * Function bta_hf_client_rfc_acp_open
151 *
152 * Description Handle RFCOMM channel open when accepting connection.
153 *
154 *
155 * Returns void
156 *
157 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800158void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800159 APPL_TRACE_DEBUG("%s", __func__);
160 tBTA_HF_CLIENT_CB* client_cb =
161 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
162 if (client_cb == NULL) {
163 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
164 p_data->hdr.layer_specific);
165 return;
166 }
167
Myles Watsoncd1fd072016-11-09 13:17:43 -0800168 uint16_t lcid;
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700169 RawAddress dev_addr;
Myles Watsoncd1fd072016-11-09 13:17:43 -0800170 int status;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530171
Myles Watsoncd1fd072016-11-09 13:17:43 -0800172 /* set role */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800173 client_cb->role = BTA_HF_CLIENT_ACP;
Hemant Gupta10256872013-08-19 18:33:01 +0530174
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800175 APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, client_cb->conn_handle);
Hemant Gupta10256872013-08-19 18:33:01 +0530176
Myles Watsoncd1fd072016-11-09 13:17:43 -0800177 /* get bd addr of peer */
Jakub Pawlowski1979fa32017-06-16 10:46:47 -0700178 if (PORT_SUCCESS != (status = PORT_CheckConnection(client_cb->conn_handle,
179 dev_addr, &lcid))) {
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800180 APPL_TRACE_DEBUG("%s: error PORT_CheckConnection returned status %d",
181 __func__, status);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800182 }
183
184 /* Collision Handling */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800185 if (alarm_is_scheduled(client_cb->collision_timer)) {
186 alarm_cancel(client_cb->collision_timer);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800187
Jakub Pawlowski744eeca2017-06-16 09:35:52 -0700188 if (dev_addr == client_cb->peer_addr) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800189 /* If incoming and outgoing device are same, nothing more to do. */
190 /* Outgoing conn will be aborted because we have successful incoming conn.
191 */
192 } else {
193 /* Resume outgoing connection. */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800194 bta_hf_client_resume_open(client_cb);
Hemant Gupta10256872013-08-19 18:33:01 +0530195 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800196 }
Hemant Gupta10256872013-08-19 18:33:01 +0530197
Jakub Pawlowski744eeca2017-06-16 09:35:52 -0700198 client_cb->peer_addr = dev_addr;
Hemant Gupta10256872013-08-19 18:33:01 +0530199
Myles Watsoncd1fd072016-11-09 13:17:43 -0800200 /* do service discovery to get features */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800201 bta_hf_client_do_disc(client_cb);
Hemant Gupta10256872013-08-19 18:33:01 +0530202
Myles Watsoncd1fd072016-11-09 13:17:43 -0800203 /* continue with open processing */
204 bta_hf_client_rfc_open(p_data);
Hemant Gupta10256872013-08-19 18:33:01 +0530205}
206
207/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800208 *
209 * Function bta_hf_client_rfc_fail
210 *
211 * Description RFCOMM connection failed.
212 *
213 *
214 * Returns void
215 *
216 ******************************************************************************/
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800217void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
218 tBTA_HF_CLIENT_CB* client_cb =
219 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
220 if (client_cb == NULL) {
221 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
222 p_data->hdr.layer_specific);
223 return;
224 }
Hemant Gupta10256872013-08-19 18:33:01 +0530225
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800226 /* reinitialize stuff */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800227 client_cb->peer_features = 0;
228 client_cb->chld_features = 0;
229 client_cb->role = BTA_HF_CLIENT_ACP;
230 client_cb->svc_conn = false;
231 client_cb->send_at_reply = false;
232 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800233
234 bta_hf_client_at_reset(client_cb);
Hemant Gupta10256872013-08-19 18:33:01 +0530235}
236
237/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800238 *
239 * Function bta_hf_client_disc_fail
240 *
241 * Description This function handles a discovery failure.
242 *
243 *
244 * Returns void
245 *
246 ******************************************************************************/
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800247void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
248 tBTA_HF_CLIENT_CB* client_cb =
249 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
250 if (client_cb == NULL) {
251 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
252 p_data->hdr.layer_specific);
253 return;
254 }
Hemant Gupta10256872013-08-19 18:33:01 +0530255}
256
257/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800258 *
259 * Function bta_hf_client_open_fail
260 *
261 * Description open connection failed.
262 *
263 *
264 * Returns void
265 *
266 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800267void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800268 tBTA_HF_CLIENT_CB* client_cb =
269 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
270 if (client_cb == NULL) {
271 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
272 p_data->hdr.layer_specific);
273 return;
274 }
Hemant Gupta10256872013-08-19 18:33:01 +0530275}
276
277/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800278 *
279 * Function bta_hf_client_rfc_close
280 *
281 * Description RFCOMM connection closed.
282 *
283 *
284 * Returns void
285 *
286 ******************************************************************************/
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800287void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
288 tBTA_HF_CLIENT_CB* client_cb =
289 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
290 if (client_cb == NULL) {
291 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
292 p_data->hdr.layer_specific);
293 return;
294 }
295
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800296 bta_hf_client_at_reset(client_cb);
Hemant Gupta10256872013-08-19 18:33:01 +0530297
Jakub Pawlowskic752e132017-06-16 12:52:23 -0700298 bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
Hemant Gupta10256872013-08-19 18:33:01 +0530299
Myles Watsoncd1fd072016-11-09 13:17:43 -0800300 /* call close cback */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800301 tBTA_HF_CLIENT evt;
302 memset(&evt, 0, sizeof(evt));
Jakub Pawlowski744eeca2017-06-16 09:35:52 -0700303 evt.conn.bd_addr = client_cb->peer_addr;
Hemant Gupta10256872013-08-19 18:33:01 +0530304
Myles Watsoncd1fd072016-11-09 13:17:43 -0800305 /* if not deregistering reopen server */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800306 if (bta_hf_client_cb_arr.deregister == false) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800307 /* Make sure SCO is shutdown */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800308 bta_hf_client_sco_shutdown(client_cb);
Hemant Gupta10256872013-08-19 18:33:01 +0530309
Jakub Pawlowskic752e132017-06-16 12:52:23 -0700310 bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800311 }
312 /* else close port and deallocate scb */
313 else {
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800314 tBTA_HF_CLIENT evt;
315 memset(&evt, 0, sizeof(evt));
Jakub Pawlowski744eeca2017-06-16 09:35:52 -0700316 evt.reg.bd_addr = client_cb->peer_addr;
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800317 bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800318 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530319}
320
321/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800322 *
323 * Function bta_hf_client_disc_int_res
324 *
325 * Description This function handles a discovery result when initiator.
326 *
327 *
328 * Returns void
329 *
330 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800331void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
332 uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
Hemant Gupta10256872013-08-19 18:33:01 +0530333
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800334 APPL_TRACE_DEBUG("%s: Status: %d", __func__, p_data->disc_result.status);
335 tBTA_HF_CLIENT_CB* client_cb =
336 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
337 if (client_cb == NULL) {
338 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
339 p_data->hdr.layer_specific);
340 return;
341 }
Hemant Gupta10256872013-08-19 18:33:01 +0530342
Myles Watsoncd1fd072016-11-09 13:17:43 -0800343 /* if found service */
344 if (p_data->disc_result.status == SDP_SUCCESS ||
345 p_data->disc_result.status == SDP_DB_FULL) {
346 /* get attributes */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800347 if (bta_hf_client_sdp_find_attr(client_cb)) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800348 event = BTA_HF_CLIENT_DISC_OK_EVT;
Hemant Gupta10256872013-08-19 18:33:01 +0530349 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800350 }
Hemant Gupta10256872013-08-19 18:33:01 +0530351
Myles Watsoncd1fd072016-11-09 13:17:43 -0800352 /* free discovery db */
353 bta_hf_client_free_db(p_data);
Hemant Gupta10256872013-08-19 18:33:01 +0530354
Myles Watsoncd1fd072016-11-09 13:17:43 -0800355 /* send ourselves sdp ok/fail event */
356 bta_hf_client_sm_execute(event, p_data);
Hemant Gupta10256872013-08-19 18:33:01 +0530357}
358
359/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800360 *
361 * Function bta_hf_client_disc_acp_res
362 *
363 * Description This function handles a discovery result when acceptor.
364 *
365 *
366 * Returns void
367 *
368 ******************************************************************************/
Myles Watsoncd1fd072016-11-09 13:17:43 -0800369void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800370 tBTA_HF_CLIENT_CB* client_cb =
371 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
372 if (client_cb == NULL) {
373 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
374 p_data->hdr.layer_specific);
375 return;
376 }
377
Myles Watsoncd1fd072016-11-09 13:17:43 -0800378 /* if found service */
379 if (p_data->disc_result.status == SDP_SUCCESS ||
380 p_data->disc_result.status == SDP_DB_FULL) {
381 /* get attributes */
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800382 bta_hf_client_sdp_find_attr(client_cb);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800383 }
Hemant Gupta10256872013-08-19 18:33:01 +0530384
Myles Watsoncd1fd072016-11-09 13:17:43 -0800385 /* free discovery db */
386 bta_hf_client_free_db(p_data);
Hemant Gupta10256872013-08-19 18:33:01 +0530387}
388
389/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800390 *
391 * Function bta_hf_client_rfc_data
392 *
393 * Description Read and process data from RFCOMM.
394 *
395 *
396 * Returns void
397 *
398 ******************************************************************************/
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800399void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
400 tBTA_HF_CLIENT_CB* client_cb =
401 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
402 if (client_cb == NULL) {
403 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
404 p_data->hdr.layer_specific);
405 return;
406 }
407
Myles Watsoncd1fd072016-11-09 13:17:43 -0800408 uint16_t len;
409 char buf[BTA_HF_CLIENT_RFC_READ_MAX];
Myles Watsoncd1fd072016-11-09 13:17:43 -0800410 memset(buf, 0, sizeof(buf));
Myles Watsoncd1fd072016-11-09 13:17:43 -0800411 /* read data from rfcomm; if bad status, we're done */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800412 while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
413 &len) == PORT_SUCCESS) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800414 /* if no data, we're done */
415 if (len == 0) {
416 break;
Hemant Gupta10256872013-08-19 18:33:01 +0530417 }
Myles Watsoncd1fd072016-11-09 13:17:43 -0800418
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800419 bta_hf_client_at_parse(client_cb, buf, len);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800420
421 /* no more data to read, we're done */
422 if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
423 break;
424 }
425 }
Hemant Gupta10256872013-08-19 18:33:01 +0530426}
427
428/*******************************************************************************
Myles Watson8af480e2016-11-09 10:40:23 -0800429 *
430 * Function bta_hf_client_svc_conn_open
431 *
432 * Description Service level connection opened
433 *
434 *
435 * Returns void
436 *
437 ******************************************************************************/
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800438void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
Sanket Agarwal6664b2c2016-12-15 14:47:29 -0800439 APPL_TRACE_DEBUG("%s", __func__);
Sanket Agarwalbdcfc042016-11-30 19:43:47 -0800440 tBTA_HF_CLIENT_CB* client_cb =
441 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
442 if (client_cb == NULL) {
443 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
444 p_data->hdr.layer_specific);
445 return;
446 }
447
Myles Watsoncd1fd072016-11-09 13:17:43 -0800448 tBTA_HF_CLIENT evt;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530449
Myles Watsoncd1fd072016-11-09 13:17:43 -0800450 memset(&evt, 0, sizeof(evt));
Hemant Gupta10256872013-08-19 18:33:01 +0530451
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800452 if (!client_cb->svc_conn) {
Myles Watsoncd1fd072016-11-09 13:17:43 -0800453 /* set state variable */
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800454 client_cb->svc_conn = true;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530455
Myles Watsoncd1fd072016-11-09 13:17:43 -0800456 /* call callback */
Jakub Pawlowski744eeca2017-06-16 09:35:52 -0700457 evt.conn.bd_addr = client_cb->peer_addr;
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800458 evt.conn.peer_feat = client_cb->peer_features;
459 evt.conn.chld_feat = client_cb->chld_features;
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530460
Sanket Agarwal5eccd902016-11-30 19:43:47 -0800461 bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
Myles Watsoncd1fd072016-11-09 13:17:43 -0800462 }
Hemant Gupta3fe1b492014-04-29 16:23:59 +0530463}