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 (com::android::bluetooth::flags::rfcomm_prevent_unnecessary_collisions()) {
114 if (PORT_IsCollisionDetected(client_cb->peer_addr)) {
115 /* Let the incoming connection go through. */
116 /* Issue collision for now. */
117 /* We will decide what to do when we find incoming connection later.*/
118 bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0, client_cb->peer_addr);
119 }
120 } else {
121 RawAddress pending_bd_addr = RawAddress::kEmpty;
122 if (PORT_IsOpening(&pending_bd_addr)) {
123 /* Let the incoming connection go through. */
124 /* Issue collision for now. */
125 /* We will decide what to do when we find incoming connection later.*/
126 bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0, client_cb->peer_addr);
127 return;
128 }
129 }
130
131 /* set role */
132 client_cb->role = BTA_HF_CLIENT_INT;
133
134 /* do service search */
135 bta_hf_client_do_disc(client_cb);
136 }
137
138 /*******************************************************************************
139 *
140 * Function bta_hf_client_rfc_open
141 *
142 * Description Handle RFCOMM channel open.
143 *
144 *
145 * Returns void
146 *
147 ******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)148 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
149 log::verbose("");
150 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
151 if (client_cb == NULL) {
152 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
153 return;
154 }
155
156 bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
157
158 /* start SLC procedure */
159 bta_hf_client_slc_seq(client_cb, false);
160 }
161
162 /*******************************************************************************
163 *
164 * Function bta_hf_client_rfc_acp_open
165 *
166 * Description Handle RFCOMM channel open when accepting connection.
167 *
168 *
169 * Returns void
170 *
171 ******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)172 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
173 log::verbose("");
174 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
175 if (client_cb == NULL) {
176 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
177 return;
178 }
179 /* set role */
180 client_cb->role = BTA_HF_CLIENT_ACP;
181
182 log::verbose("conn_handle {}", client_cb->conn_handle);
183
184 /* get bd addr of peer */
185 uint16_t lcid = 0;
186 RawAddress dev_addr = RawAddress::kEmpty;
187 int status = PORT_CheckConnection(client_cb->conn_handle, &dev_addr, &lcid);
188 if (status != PORT_SUCCESS) {
189 log::error("PORT_CheckConnection returned status:{}", status);
190 }
191
192 /* Collision Handling */
193 if (alarm_is_scheduled(client_cb->collision_timer)) {
194 alarm_cancel(client_cb->collision_timer);
195
196 if (dev_addr == client_cb->peer_addr) {
197 /* If incoming and outgoing device are same, nothing more to do. */
198 /* Outgoing conn will be aborted because we have successful incoming conn.
199 */
200 } else {
201 /* Resume outgoing connection. */
202 bta_hf_client_resume_open(client_cb);
203 }
204 }
205
206 client_cb->peer_addr = dev_addr;
207
208 /* do service discovery to get features */
209 bta_hf_client_do_disc(client_cb);
210
211 /* continue with open processing */
212 bta_hf_client_rfc_open(p_data);
213 }
214
215 /*******************************************************************************
216 *
217 * Function bta_hf_client_rfc_fail
218 *
219 * Description RFCOMM connection failed.
220 *
221 *
222 * Returns void
223 *
224 ******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)225 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
226 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
227 if (client_cb == NULL) {
228 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
229 return;
230 }
231
232 /* reinitialize stuff */
233 client_cb->peer_features = 0;
234 client_cb->chld_features = 0;
235 client_cb->role = BTA_HF_CLIENT_ACP;
236 client_cb->svc_conn = false;
237 client_cb->send_at_reply = false;
238 client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
239
240 bta_hf_client_at_reset(client_cb);
241 }
242
243 /*******************************************************************************
244 *
245 * Function bta_hf_client_disc_fail
246 *
247 * Description This function handles a discovery failure.
248 *
249 *
250 * Returns void
251 *
252 ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)253 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
254 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
255 if (client_cb == NULL) {
256 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
257 return;
258 }
259 }
260
261 /*******************************************************************************
262 *
263 * Function bta_hf_client_open_fail
264 *
265 * Description open connection failed.
266 *
267 *
268 * Returns void
269 *
270 ******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)271 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
272 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
273 if (client_cb == NULL) {
274 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
275 return;
276 }
277 }
278
279 /*******************************************************************************
280 *
281 * Function bta_hf_client_rfc_close
282 *
283 * Description RFCOMM connection closed.
284 *
285 *
286 * Returns void
287 *
288 ******************************************************************************/
bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA * p_data)289 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
290 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
291 if (client_cb == NULL) {
292 log::error("cb not found for handle {}", 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) {
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 } else {
312 /* else close port and deallocate scb */
313 tBTA_HF_CLIENT evt;
314 memset(&evt, 0, sizeof(evt));
315 evt.reg.bd_addr = client_cb->peer_addr;
316 bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
317 }
318 }
319
320 /*******************************************************************************
321 *
322 * Function bta_hf_client_disc_int_res
323 *
324 * Description This function handles a discovery result when initiator.
325 *
326 *
327 * Returns void
328 *
329 ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)330 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
331 uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
332
333 log::verbose("Status: {}", p_data->disc_result.status);
334 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
335 if (client_cb == NULL) {
336 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
337 return;
338 }
339
340 /* if found service */
341 if (p_data->disc_result.status == tSDP_STATUS::SDP_SUCCESS ||
342 p_data->disc_result.status == tSDP_STATUS::SDP_DB_FULL) {
343 /* get attributes */
344 if (bta_hf_client_sdp_find_attr(client_cb)) {
345 event = BTA_HF_CLIENT_DISC_OK_EVT;
346 }
347 }
348
349 /* free discovery db */
350 bta_hf_client_free_db(p_data);
351
352 /* send ourselves sdp ok/fail event */
353 bta_hf_client_sm_execute(event, p_data);
354 }
355
356 /*******************************************************************************
357 *
358 * Function bta_hf_client_disc_acp_res
359 *
360 * Description This function handles a discovery result when acceptor.
361 *
362 *
363 * Returns void
364 *
365 ******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)366 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
367 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
368 if (client_cb == NULL) {
369 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
370 return;
371 }
372
373 /* if found service */
374 if (p_data->disc_result.status == tSDP_STATUS::SDP_SUCCESS ||
375 p_data->disc_result.status == tSDP_STATUS::SDP_DB_FULL) {
376 /* get attributes */
377 bta_hf_client_sdp_find_attr(client_cb);
378 }
379
380 /* free discovery db */
381 bta_hf_client_free_db(p_data);
382 }
383
384 /*******************************************************************************
385 *
386 * Function bta_hf_client_rfc_data
387 *
388 * Description Read and process data from RFCOMM.
389 *
390 *
391 * Returns void
392 *
393 ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)394 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
395 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
396 if (client_cb == NULL) {
397 log::error("cb not found for handle {}", p_data->hdr.layer_specific);
398 return;
399 }
400
401 uint16_t len;
402 char buf[BTA_HF_CLIENT_RFC_READ_MAX];
403 memset(buf, 0, sizeof(buf));
404 /* read data from rfcomm; if bad status, we're done */
405 while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) ==
406 PORT_SUCCESS) {
407 /* if no data, we're done */
408 if (len == 0) {
409 break;
410 }
411
412 bta_hf_client_at_parse(client_cb, buf, len);
413
414 /* no more data to read, we're done */
415 if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
416 break;
417 }
418 }
419 }
420
421 /*******************************************************************************
422 *
423 * Function bta_hf_client_svc_conn_open
424 *
425 * Description Service level connection opened
426 *
427 *
428 * Returns void
429 *
430 ******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)431 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
432 log::verbose("");
433 tBTA_HF_CLIENT_CB* client_cb = bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
434 if (client_cb == NULL) {
435 log::error("cb not found for handle {}", 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