1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright 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 *
22 * This file contains action functions for the handsfree client.
23 *
24 ******************************************************************************/
25
26 #include "bt_trace.h" // Legacy trace logging
27
28 #include "bta/hf_client/bta_hf_client_int.h"
29 #include "bta/include/bta_dm_api.h"
30 #include "stack/include/l2c_api.h"
31 #include "stack/include/port_api.h"
32 #include "types/raw_address.h"
33
34 #include <base/logging.h>
35
36 /*****************************************************************************
37 * Constants
38 ****************************************************************************/
39
40 /* maximum length of data to read from RFCOMM */
41 #define BTA_HF_CLIENT_RFC_READ_MAX 512
42
43 /*******************************************************************************
44 *
45 * Function bta_hf_client_start_close
46 *
47 * Description Start the process of closing SCO and RFCOMM connection.
48 *
49 *
50 * Returns void
51 *
52 ******************************************************************************/
bta_hf_client_start_close(tBTA_HF_CLIENT_DATA * p_data)53 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
54 tBTA_HF_CLIENT_CB* client_cb =
55 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
56 if (client_cb == NULL) {
57 APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
58 p_data->hdr.layer_specific);
59 return;
60 }
61
62 /* Take the link out of sniff and set L2C idle time to 0 */
63 bta_dm_pm_active(client_cb->peer_addr);
64 L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
65
66 /* if SCO is open close SCO and wait on RFCOMM close */
67 if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
68 client_cb->sco_close_rfc = true;
69 } else {
70 bta_hf_client_rfc_do_close(p_data);
71 }
72
73 /* always do SCO shutdown to handle all SCO corner cases */
74 bta_hf_client_sco_shutdown(client_cb);
75 }
76
77 /*******************************************************************************
78 *
79 * Function bta_hf_client_start_open
80 *
81 * Description This starts an HF Client open.
82 *
83 *
84 * Returns void
85 *
86 ******************************************************************************/
bta_hf_client_start_open(tBTA_HF_CLIENT_DATA * p_data)87 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
88 tBTA_HF_CLIENT_CB* client_cb =
89 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
90 if (client_cb == NULL) {
91 APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
92 p_data->hdr.layer_specific);
93 return;
94 }
95
96 /* store parameters */
97 if (p_data) {
98 client_cb->peer_addr = p_data->api_open.bd_addr;
99 }
100
101 /* Check if RFCOMM has any incoming connection to avoid collision. */
102 RawAddress pending_bd_addr = RawAddress::kEmpty;
103 if (PORT_IsOpening(&pending_bd_addr)) {
104 /* Let the incoming connection goes through. */
105 /* Issue collision for now. */
106 /* We will decide what to do when we find incoming connection later.*/
107 bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0,
108 client_cb->peer_addr);
109 return;
110 }
111
112 /* set role */
113 client_cb->role = BTA_HF_CLIENT_INT;
114
115 /* do service search */
116 bta_hf_client_do_disc(client_cb);
117 }
118
119 /*******************************************************************************
120 *
121 * Function bta_hf_client_rfc_open
122 *
123 * Description Handle RFCOMM channel open.
124 *
125 *
126 * Returns void
127 *
128 ******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)129 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
130 APPL_TRACE_DEBUG("%s", __func__);
131 tBTA_HF_CLIENT_CB* client_cb =
132 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
133 if (client_cb == NULL) {
134 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
135 p_data->hdr.layer_specific);
136 return;
137 }
138
139 bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
140
141 /* start SLC procedure */
142 bta_hf_client_slc_seq(client_cb, false);
143 }
144
145 /*******************************************************************************
146 *
147 * Function bta_hf_client_rfc_acp_open
148 *
149 * Description Handle RFCOMM channel open when accepting connection.
150 *
151 *
152 * Returns void
153 *
154 ******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)155 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
156 APPL_TRACE_DEBUG("%s", __func__);
157 tBTA_HF_CLIENT_CB* client_cb =
158 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
159 if (client_cb == NULL) {
160 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
161 p_data->hdr.layer_specific);
162 return;
163 }
164 /* set role */
165 client_cb->role = BTA_HF_CLIENT_ACP;
166
167 APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, client_cb->conn_handle);
168
169 /* get bd addr of peer */
170 uint16_t lcid = 0;
171 RawAddress dev_addr = RawAddress::kEmpty;
172 int status = PORT_CheckConnection(client_cb->conn_handle, &dev_addr, &lcid);
173 if (status != PORT_SUCCESS) {
174 LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status;
175 }
176
177 /* Collision Handling */
178 if (alarm_is_scheduled(client_cb->collision_timer)) {
179 alarm_cancel(client_cb->collision_timer);
180
181 if (dev_addr == client_cb->peer_addr) {
182 /* If incoming and outgoing device are same, nothing more to do. */
183 /* Outgoing conn will be aborted because we have successful incoming conn.
184 */
185 } else {
186 /* Resume outgoing connection. */
187 bta_hf_client_resume_open(client_cb);
188 }
189 }
190
191 client_cb->peer_addr = dev_addr;
192
193 /* do service discovery to get features */
194 bta_hf_client_do_disc(client_cb);
195
196 /* continue with open processing */
197 bta_hf_client_rfc_open(p_data);
198 }
199
200 /*******************************************************************************
201 *
202 * Function bta_hf_client_rfc_fail
203 *
204 * Description RFCOMM connection failed.
205 *
206 *
207 * Returns void
208 *
209 ******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)210 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
211 tBTA_HF_CLIENT_CB* client_cb =
212 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
213 if (client_cb == NULL) {
214 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
215 p_data->hdr.layer_specific);
216 return;
217 }
218
219 /* reinitialize stuff */
220 client_cb->peer_features = 0;
221 client_cb->chld_features = 0;
222 client_cb->role = BTA_HF_CLIENT_ACP;
223 client_cb->svc_conn = false;
224 client_cb->send_at_reply = false;
225 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
226
227 bta_hf_client_at_reset(client_cb);
228 }
229
230 /*******************************************************************************
231 *
232 * Function bta_hf_client_disc_fail
233 *
234 * Description This function handles a discovery failure.
235 *
236 *
237 * Returns void
238 *
239 ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)240 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
241 tBTA_HF_CLIENT_CB* client_cb =
242 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
243 if (client_cb == NULL) {
244 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
245 p_data->hdr.layer_specific);
246 return;
247 }
248 }
249
250 /*******************************************************************************
251 *
252 * Function bta_hf_client_open_fail
253 *
254 * Description open connection failed.
255 *
256 *
257 * Returns void
258 *
259 ******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)260 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
261 tBTA_HF_CLIENT_CB* client_cb =
262 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
263 if (client_cb == NULL) {
264 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
265 p_data->hdr.layer_specific);
266 return;
267 }
268 }
269
270 /*******************************************************************************
271 *
272 * Function bta_hf_client_rfc_close
273 *
274 * Description RFCOMM connection closed.
275 *
276 *
277 * Returns void
278 *
279 ******************************************************************************/
bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA * p_data)280 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
281 tBTA_HF_CLIENT_CB* client_cb =
282 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
283 if (client_cb == NULL) {
284 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
285 p_data->hdr.layer_specific);
286 return;
287 }
288
289 bta_hf_client_at_reset(client_cb);
290
291 bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
292
293 /* call close cback */
294 tBTA_HF_CLIENT evt;
295 memset(&evt, 0, sizeof(evt));
296 evt.conn.bd_addr = client_cb->peer_addr;
297
298 /* if not deregistering reopen server */
299 if (!bta_hf_client_cb_arr.deregister) {
300 /* Make sure SCO is shutdown */
301 bta_hf_client_sco_shutdown(client_cb);
302
303 bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
304 }
305 /* else close port and deallocate scb */
306 else {
307 tBTA_HF_CLIENT evt;
308 memset(&evt, 0, sizeof(evt));
309 evt.reg.bd_addr = client_cb->peer_addr;
310 bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
311 }
312 }
313
314 /*******************************************************************************
315 *
316 * Function bta_hf_client_disc_int_res
317 *
318 * Description This function handles a discovery result when initiator.
319 *
320 *
321 * Returns void
322 *
323 ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)324 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
325 uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
326
327 APPL_TRACE_DEBUG("%s: Status: %d", __func__, p_data->disc_result.status);
328 tBTA_HF_CLIENT_CB* client_cb =
329 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
330 if (client_cb == NULL) {
331 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
332 p_data->hdr.layer_specific);
333 return;
334 }
335
336 /* if found service */
337 if (p_data->disc_result.status == SDP_SUCCESS ||
338 p_data->disc_result.status == SDP_DB_FULL) {
339 /* get attributes */
340 if (bta_hf_client_sdp_find_attr(client_cb)) {
341 event = BTA_HF_CLIENT_DISC_OK_EVT;
342 }
343 }
344
345 /* free discovery db */
346 bta_hf_client_free_db(p_data);
347
348 /* send ourselves sdp ok/fail event */
349 bta_hf_client_sm_execute(event, p_data);
350 }
351
352 /*******************************************************************************
353 *
354 * Function bta_hf_client_disc_acp_res
355 *
356 * Description This function handles a discovery result when acceptor.
357 *
358 *
359 * Returns void
360 *
361 ******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)362 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
363 tBTA_HF_CLIENT_CB* client_cb =
364 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
365 if (client_cb == NULL) {
366 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
367 p_data->hdr.layer_specific);
368 return;
369 }
370
371 /* if found service */
372 if (p_data->disc_result.status == SDP_SUCCESS ||
373 p_data->disc_result.status == SDP_DB_FULL) {
374 /* get attributes */
375 bta_hf_client_sdp_find_attr(client_cb);
376 }
377
378 /* free discovery db */
379 bta_hf_client_free_db(p_data);
380 }
381
382 /*******************************************************************************
383 *
384 * Function bta_hf_client_rfc_data
385 *
386 * Description Read and process data from RFCOMM.
387 *
388 *
389 * Returns void
390 *
391 ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)392 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
393 tBTA_HF_CLIENT_CB* client_cb =
394 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
395 if (client_cb == NULL) {
396 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
397 p_data->hdr.layer_specific);
398 return;
399 }
400
401 uint16_t len;
402 char buf[BTA_HF_CLIENT_RFC_READ_MAX];
403 memset(buf, 0, sizeof(buf));
404 /* read data from rfcomm; if bad status, we're done */
405 while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
406 &len) == PORT_SUCCESS) {
407 /* if no data, we're done */
408 if (len == 0) {
409 break;
410 }
411
412 bta_hf_client_at_parse(client_cb, buf, len);
413
414 /* no more data to read, we're done */
415 if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
416 break;
417 }
418 }
419 }
420
421 /*******************************************************************************
422 *
423 * Function bta_hf_client_svc_conn_open
424 *
425 * Description Service level connection opened
426 *
427 *
428 * Returns void
429 *
430 ******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)431 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
432 APPL_TRACE_DEBUG("%s", __func__);
433 tBTA_HF_CLIENT_CB* client_cb =
434 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
435 if (client_cb == NULL) {
436 APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
437 p_data->hdr.layer_specific);
438 return;
439 }
440
441 tBTA_HF_CLIENT evt;
442
443 memset(&evt, 0, sizeof(evt));
444
445 if (!client_cb->svc_conn) {
446 /* set state variable */
447 client_cb->svc_conn = true;
448
449 /* call callback */
450 evt.conn.bd_addr = client_cb->peer_addr;
451 evt.conn.peer_feat = client_cb->peer_features;
452 evt.conn.chld_feat = client_cb->chld_features;
453
454 bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
455 }
456 }
457