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