1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * 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 *
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;
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
168 uint16_t lcid;
169 RawAddress dev_addr;
170 int status;
171
172 /* set role */
173 client_cb->role = BTA_HF_CLIENT_ACP;
174
175 APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, client_cb->conn_handle);
176
177 /* get bd addr of peer */
178 if (PORT_SUCCESS != (status = PORT_CheckConnection(client_cb->conn_handle,
179 dev_addr, &lcid))) {
180 APPL_TRACE_DEBUG("%s: error PORT_CheckConnection returned status %d",
181 __func__, status);
182 }
183
184 /* Collision Handling */
185 if (alarm_is_scheduled(client_cb->collision_timer)) {
186 alarm_cancel(client_cb->collision_timer);
187
188 if (dev_addr == client_cb->peer_addr) {
189 /* 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. */
194 bta_hf_client_resume_open(client_cb);
195 }
196 }
197
198 client_cb->peer_addr = dev_addr;
199
200 /* do service discovery to get features */
201 bta_hf_client_do_disc(client_cb);
202
203 /* continue with open processing */
204 bta_hf_client_rfc_open(p_data);
205 }
206
207 /*******************************************************************************
208 *
209 * Function bta_hf_client_rfc_fail
210 *
211 * Description RFCOMM connection failed.
212 *
213 *
214 * Returns void
215 *
216 ******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)217 void 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 }
225
226 /* reinitialize stuff */
227 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;
233
234 bta_hf_client_at_reset(client_cb);
235 }
236
237 /*******************************************************************************
238 *
239 * Function bta_hf_client_disc_fail
240 *
241 * Description This function handles a discovery failure.
242 *
243 *
244 * Returns void
245 *
246 ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)247 void 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 }
255 }
256
257 /*******************************************************************************
258 *
259 * Function bta_hf_client_open_fail
260 *
261 * Description open connection failed.
262 *
263 *
264 * Returns void
265 *
266 ******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)267 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
268 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 }
275 }
276
277 /*******************************************************************************
278 *
279 * Function bta_hf_client_rfc_close
280 *
281 * Description RFCOMM connection closed.
282 *
283 *
284 * Returns void
285 *
286 ******************************************************************************/
bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA * p_data)287 void 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
296 bta_hf_client_at_reset(client_cb);
297
298 bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
299
300 /* call close cback */
301 tBTA_HF_CLIENT evt;
302 memset(&evt, 0, sizeof(evt));
303 evt.conn.bd_addr = client_cb->peer_addr;
304
305 /* if not deregistering reopen server */
306 if (bta_hf_client_cb_arr.deregister == false) {
307 /* Make sure SCO is shutdown */
308 bta_hf_client_sco_shutdown(client_cb);
309
310 bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
311 }
312 /* else close port and deallocate scb */
313 else {
314 tBTA_HF_CLIENT evt;
315 memset(&evt, 0, sizeof(evt));
316 evt.reg.bd_addr = client_cb->peer_addr;
317 bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
318 }
319 }
320
321 /*******************************************************************************
322 *
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 ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)331 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
332 uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
333
334 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 }
342
343 /* if found service */
344 if (p_data->disc_result.status == SDP_SUCCESS ||
345 p_data->disc_result.status == SDP_DB_FULL) {
346 /* get attributes */
347 if (bta_hf_client_sdp_find_attr(client_cb)) {
348 event = BTA_HF_CLIENT_DISC_OK_EVT;
349 }
350 }
351
352 /* free discovery db */
353 bta_hf_client_free_db(p_data);
354
355 /* send ourselves sdp ok/fail event */
356 bta_hf_client_sm_execute(event, p_data);
357 }
358
359 /*******************************************************************************
360 *
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 ******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)369 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
370 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
378 /* if found service */
379 if (p_data->disc_result.status == SDP_SUCCESS ||
380 p_data->disc_result.status == SDP_DB_FULL) {
381 /* get attributes */
382 bta_hf_client_sdp_find_attr(client_cb);
383 }
384
385 /* free discovery db */
386 bta_hf_client_free_db(p_data);
387 }
388
389 /*******************************************************************************
390 *
391 * Function bta_hf_client_rfc_data
392 *
393 * Description Read and process data from RFCOMM.
394 *
395 *
396 * Returns void
397 *
398 ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)399 void 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
408 uint16_t len;
409 char buf[BTA_HF_CLIENT_RFC_READ_MAX];
410 memset(buf, 0, sizeof(buf));
411 /* read data from rfcomm; if bad status, we're done */
412 while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
413 &len) == PORT_SUCCESS) {
414 /* if no data, we're done */
415 if (len == 0) {
416 break;
417 }
418
419 bta_hf_client_at_parse(client_cb, buf, len);
420
421 /* no more data to read, we're done */
422 if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
423 break;
424 }
425 }
426 }
427
428 /*******************************************************************************
429 *
430 * Function bta_hf_client_svc_conn_open
431 *
432 * Description Service level connection opened
433 *
434 *
435 * Returns void
436 *
437 ******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)438 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
439 APPL_TRACE_DEBUG("%s", __func__);
440 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
448 tBTA_HF_CLIENT evt;
449
450 memset(&evt, 0, sizeof(evt));
451
452 if (!client_cb->svc_conn) {
453 /* set state variable */
454 client_cb->svc_conn = true;
455
456 /* call callback */
457 evt.conn.bd_addr = client_cb->peer_addr;
458 evt.conn.peer_feat = client_cb->peer_features;
459 evt.conn.chld_feat = client_cb->chld_features;
460
461 bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
462 }
463 }
464