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