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 <bluetooth/log.h>
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 "stack/include/sdp_status.h"
33 #include "types/bt_transport.h"
34 #include "types/raw_address.h"
35
36 using namespace bluetooth;
37
38 /*****************************************************************************
39 * Constants
40 ****************************************************************************/
41
42 /* maximum length of data to read from RFCOMM */
43 #define BTA_HF_CLIENT_RFC_READ_MAX 512
44
45 /*******************************************************************************
46 *
47 * Function bta_hf_client_start_close
48 *
49 * Description Start the process of closing SCO and RFCOMM connection.
50 *
51 *
52 * Returns void
53 *
54 ******************************************************************************/
bta_hf_client_start_close(tBTA_HF_CLIENT_DATA * p_data)55 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
56 tBTA_HF_CLIENT_CB* client_cb =
57 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
58 if (client_cb == NULL) {
59 log::error("wrong handle to control block {}", p_data->hdr.layer_specific);
60 return;
61 }
62
63 /* Take the link out of sniff and set L2C idle time to 0 */
64 bta_dm_pm_active(client_cb->peer_addr);
65 if (!L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0,
66 BT_TRANSPORT_BR_EDR)) {
67 log::warn(
68 "Unable to set L2CAP idle timeout peer:{} transport:{} timeout:{}",
69 client_cb->peer_addr, bt_transport_text(BT_TRANSPORT_BR_EDR), 0);
70 }
71
72 /* if SCO is open close SCO and wait on RFCOMM close */
73 if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
74 client_cb->sco_close_rfc = true;
75 } else {
76 bta_hf_client_rfc_do_close(p_data);
77 }
78
79 /* always do SCO shutdown to handle all SCO corner cases */
80 bta_hf_client_sco_shutdown(client_cb);
81 }
82
83 /*******************************************************************************
84 *
85 * Function bta_hf_client_start_open
86 *
87 * Description This starts an HF Client open.
88 *
89 *
90 * Returns void
91 *
92 ******************************************************************************/
bta_hf_client_start_open(tBTA_HF_CLIENT_DATA * p_data)93 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
94 tBTA_HF_CLIENT_CB* client_cb =
95 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
96 if (client_cb == NULL) {
97 log::error("wrong handle to control block {}", p_data->hdr.layer_specific);
98 return;
99 }
100
101 /* store parameters */
102 if (p_data) {
103 client_cb->peer_addr = p_data->api_open.bd_addr;
104 }
105
106 /* Check if RFCOMM has any incoming connection to avoid collision. */
107 RawAddress pending_bd_addr = RawAddress::kEmpty;
108 if (PORT_IsOpening(&pending_bd_addr)) {
109 /* Let the incoming connection goes through. */
110 /* Issue collision for now. */
111 /* We will decide what to do when we find incoming connection later.*/
112 bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0,
113 client_cb->peer_addr);
114 return;
115 }
116
117 /* set role */
118 client_cb->role = BTA_HF_CLIENT_INT;
119
120 /* do service search */
121 bta_hf_client_do_disc(client_cb);
122 }
123
124 /*******************************************************************************
125 *
126 * Function bta_hf_client_rfc_open
127 *
128 * Description Handle RFCOMM channel open.
129 *
130 *
131 * Returns void
132 *
133 ******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)134 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
135 log::verbose("");
136 tBTA_HF_CLIENT_CB* client_cb =
137 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
138 if (client_cb == NULL) {
139 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
140 return;
141 }
142
143 bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
144
145 /* start SLC procedure */
146 bta_hf_client_slc_seq(client_cb, false);
147 }
148
149 /*******************************************************************************
150 *
151 * Function bta_hf_client_rfc_acp_open
152 *
153 * Description Handle RFCOMM channel open when accepting connection.
154 *
155 *
156 * Returns void
157 *
158 ******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)159 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
160 log::verbose("");
161 tBTA_HF_CLIENT_CB* client_cb =
162 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
163 if (client_cb == NULL) {
164 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
165 return;
166 }
167 /* set role */
168 client_cb->role = BTA_HF_CLIENT_ACP;
169
170 log::verbose("conn_handle {}", 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("PORT_CheckConnection returned status:{}", 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 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
218 return;
219 }
220
221 /* reinitialize stuff */
222 client_cb->peer_features = 0;
223 client_cb->chld_features = 0;
224 client_cb->role = BTA_HF_CLIENT_ACP;
225 client_cb->svc_conn = false;
226 client_cb->send_at_reply = false;
227 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
228
229 bta_hf_client_at_reset(client_cb);
230 }
231
232 /*******************************************************************************
233 *
234 * Function bta_hf_client_disc_fail
235 *
236 * Description This function handles a discovery failure.
237 *
238 *
239 * Returns void
240 *
241 ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)242 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
243 tBTA_HF_CLIENT_CB* client_cb =
244 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
245 if (client_cb == NULL) {
246 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
247 return;
248 }
249 }
250
251 /*******************************************************************************
252 *
253 * Function bta_hf_client_open_fail
254 *
255 * Description open connection failed.
256 *
257 *
258 * Returns void
259 *
260 ******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)261 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
262 tBTA_HF_CLIENT_CB* client_cb =
263 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
264 if (client_cb == NULL) {
265 log::error("cb not found for handle {}", 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 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
285 return;
286 }
287
288 bta_hf_client_at_reset(client_cb);
289
290 bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
291
292 /* call close cback */
293 tBTA_HF_CLIENT evt;
294 memset(&evt, 0, sizeof(evt));
295 evt.conn.bd_addr = client_cb->peer_addr;
296
297 /* if not deregistering reopen server */
298 if (!bta_hf_client_cb_arr.deregister) {
299 /* Make sure SCO is shutdown */
300 bta_hf_client_sco_shutdown(client_cb);
301
302 bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
303 }
304 /* else close port and deallocate scb */
305 else {
306 tBTA_HF_CLIENT evt;
307 memset(&evt, 0, sizeof(evt));
308 evt.reg.bd_addr = client_cb->peer_addr;
309 bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
310 }
311 }
312
313 /*******************************************************************************
314 *
315 * Function bta_hf_client_disc_int_res
316 *
317 * Description This function handles a discovery result when initiator.
318 *
319 *
320 * Returns void
321 *
322 ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)323 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
324 uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
325
326 log::verbose("Status: {}", p_data->disc_result.status);
327 tBTA_HF_CLIENT_CB* client_cb =
328 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
329 if (client_cb == NULL) {
330 log::error("cb not found for handle {}", 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 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
365 return;
366 }
367
368 /* if found service */
369 if (p_data->disc_result.status == SDP_SUCCESS ||
370 p_data->disc_result.status == SDP_DB_FULL) {
371 /* get attributes */
372 bta_hf_client_sdp_find_attr(client_cb);
373 }
374
375 /* free discovery db */
376 bta_hf_client_free_db(p_data);
377 }
378
379 /*******************************************************************************
380 *
381 * Function bta_hf_client_rfc_data
382 *
383 * Description Read and process data from RFCOMM.
384 *
385 *
386 * Returns void
387 *
388 ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)389 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
390 tBTA_HF_CLIENT_CB* client_cb =
391 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
392 if (client_cb == NULL) {
393 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
394 return;
395 }
396
397 uint16_t len;
398 char buf[BTA_HF_CLIENT_RFC_READ_MAX];
399 memset(buf, 0, sizeof(buf));
400 /* read data from rfcomm; if bad status, we're done */
401 while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
402 &len) == PORT_SUCCESS) {
403 /* if no data, we're done */
404 if (len == 0) {
405 break;
406 }
407
408 bta_hf_client_at_parse(client_cb, buf, len);
409
410 /* no more data to read, we're done */
411 if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
412 break;
413 }
414 }
415 }
416
417 /*******************************************************************************
418 *
419 * Function bta_hf_client_svc_conn_open
420 *
421 * Description Service level connection opened
422 *
423 *
424 * Returns void
425 *
426 ******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)427 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
428 log::verbose("");
429 tBTA_HF_CLIENT_CB* client_cb =
430 bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
431 if (client_cb == NULL) {
432 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
433 return;
434 }
435
436 tBTA_HF_CLIENT evt;
437
438 memset(&evt, 0, sizeof(evt));
439
440 if (!client_cb->svc_conn) {
441 /* set state variable */
442 client_cb->svc_conn = true;
443
444 /* call callback */
445 evt.conn.bd_addr = client_cb->peer_addr;
446 evt.conn.peer_feat = client_cb->peer_features;
447 evt.conn.chld_feat = client_cb->chld_features;
448
449 bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
450 }
451 }
452