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