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