• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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