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