• 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 "bt_trace.h"  // Legacy trace logging
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 "types/raw_address.h"
33 
34 #include <base/logging.h>
35 
36 /*****************************************************************************
37  *  Constants
38  ****************************************************************************/
39 
40 /* maximum length of data to read from RFCOMM */
41 #define BTA_HF_CLIENT_RFC_READ_MAX 512
42 
43 /*******************************************************************************
44  *
45  * Function         bta_hf_client_start_close
46  *
47  * Description      Start the process of closing SCO and RFCOMM connection.
48  *
49  *
50  * Returns          void
51  *
52  ******************************************************************************/
bta_hf_client_start_close(tBTA_HF_CLIENT_DATA * p_data)53 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
54   tBTA_HF_CLIENT_CB* client_cb =
55       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
56   if (client_cb == NULL) {
57     APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
58                      p_data->hdr.layer_specific);
59     return;
60   }
61 
62   /* Take the link out of sniff and set L2C idle time to 0 */
63   bta_dm_pm_active(client_cb->peer_addr);
64   L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
65 
66   /* if SCO is open close SCO and wait on RFCOMM close */
67   if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
68     client_cb->sco_close_rfc = true;
69   } else {
70     bta_hf_client_rfc_do_close(p_data);
71   }
72 
73   /* always do SCO shutdown to handle all SCO corner cases */
74   bta_hf_client_sco_shutdown(client_cb);
75 }
76 
77 /*******************************************************************************
78  *
79  * Function         bta_hf_client_start_open
80  *
81  * Description      This starts an HF Client open.
82  *
83  *
84  * Returns          void
85  *
86  ******************************************************************************/
bta_hf_client_start_open(tBTA_HF_CLIENT_DATA * p_data)87 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
88   tBTA_HF_CLIENT_CB* client_cb =
89       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
90   if (client_cb == NULL) {
91     APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
92                      p_data->hdr.layer_specific);
93     return;
94   }
95 
96   /* store parameters */
97   if (p_data) {
98     client_cb->peer_addr = p_data->api_open.bd_addr;
99   }
100 
101   /* Check if RFCOMM has any incoming connection to avoid collision. */
102   RawAddress pending_bd_addr = RawAddress::kEmpty;
103   if (PORT_IsOpening(&pending_bd_addr)) {
104     /* Let the incoming connection goes through.                        */
105     /* Issue collision for now.                                         */
106     /* We will decide what to do when we find incoming connection later.*/
107     bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0,
108                                   client_cb->peer_addr);
109     return;
110   }
111 
112   /* set role */
113   client_cb->role = BTA_HF_CLIENT_INT;
114 
115   /* do service search */
116   bta_hf_client_do_disc(client_cb);
117 }
118 
119 /*******************************************************************************
120  *
121  * Function         bta_hf_client_rfc_open
122  *
123  * Description      Handle RFCOMM channel open.
124  *
125  *
126  * Returns          void
127  *
128  ******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)129 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
130   APPL_TRACE_DEBUG("%s", __func__);
131   tBTA_HF_CLIENT_CB* client_cb =
132       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
133   if (client_cb == NULL) {
134     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
135                      p_data->hdr.layer_specific);
136     return;
137   }
138 
139   bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
140 
141   /* start SLC procedure */
142   bta_hf_client_slc_seq(client_cb, false);
143 }
144 
145 /*******************************************************************************
146  *
147  * Function         bta_hf_client_rfc_acp_open
148  *
149  * Description      Handle RFCOMM channel open when accepting connection.
150  *
151  *
152  * Returns          void
153  *
154  ******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)155 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
156   APPL_TRACE_DEBUG("%s", __func__);
157   tBTA_HF_CLIENT_CB* client_cb =
158       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
159   if (client_cb == NULL) {
160     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
161                      p_data->hdr.layer_specific);
162     return;
163   }
164   /* set role */
165   client_cb->role = BTA_HF_CLIENT_ACP;
166 
167   APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, client_cb->conn_handle);
168 
169   /* get bd addr of peer */
170   uint16_t lcid = 0;
171   RawAddress dev_addr = RawAddress::kEmpty;
172   int status = PORT_CheckConnection(client_cb->conn_handle, &dev_addr, &lcid);
173   if (status != PORT_SUCCESS) {
174     LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status;
175   }
176 
177   /* Collision Handling */
178   if (alarm_is_scheduled(client_cb->collision_timer)) {
179     alarm_cancel(client_cb->collision_timer);
180 
181     if (dev_addr == client_cb->peer_addr) {
182       /* If incoming and outgoing device are same, nothing more to do. */
183       /* Outgoing conn will be aborted because we have successful incoming conn.
184        */
185     } else {
186       /* Resume outgoing connection. */
187       bta_hf_client_resume_open(client_cb);
188     }
189   }
190 
191   client_cb->peer_addr = dev_addr;
192 
193   /* do service discovery to get features */
194   bta_hf_client_do_disc(client_cb);
195 
196   /* continue with open processing */
197   bta_hf_client_rfc_open(p_data);
198 }
199 
200 /*******************************************************************************
201  *
202  * Function         bta_hf_client_rfc_fail
203  *
204  * Description      RFCOMM connection failed.
205  *
206  *
207  * Returns          void
208  *
209  ******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)210 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
211   tBTA_HF_CLIENT_CB* client_cb =
212       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
213   if (client_cb == NULL) {
214     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
215                      p_data->hdr.layer_specific);
216     return;
217   }
218 
219   /* reinitialize stuff */
220   client_cb->peer_features = 0;
221   client_cb->chld_features = 0;
222   client_cb->role = BTA_HF_CLIENT_ACP;
223   client_cb->svc_conn = false;
224   client_cb->send_at_reply = false;
225   client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
226 
227   bta_hf_client_at_reset(client_cb);
228 }
229 
230 /*******************************************************************************
231  *
232  * Function         bta_hf_client_disc_fail
233  *
234  * Description      This function handles a discovery failure.
235  *
236  *
237  * Returns          void
238  *
239  ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)240 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
241   tBTA_HF_CLIENT_CB* client_cb =
242       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
243   if (client_cb == NULL) {
244     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
245                      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 =
262       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
263   if (client_cb == NULL) {
264     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
265                      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     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
285                      p_data->hdr.layer_specific);
286     return;
287   }
288 
289   bta_hf_client_at_reset(client_cb);
290 
291   bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
292 
293   /* call close cback */
294   tBTA_HF_CLIENT evt;
295   memset(&evt, 0, sizeof(evt));
296   evt.conn.bd_addr = client_cb->peer_addr;
297 
298   /* if not deregistering reopen server */
299   if (!bta_hf_client_cb_arr.deregister) {
300     /* Make sure SCO is shutdown */
301     bta_hf_client_sco_shutdown(client_cb);
302 
303     bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
304   }
305   /* else close port and deallocate scb */
306   else {
307     tBTA_HF_CLIENT evt;
308     memset(&evt, 0, sizeof(evt));
309     evt.reg.bd_addr = client_cb->peer_addr;
310     bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
311   }
312 }
313 
314 /*******************************************************************************
315  *
316  * Function         bta_hf_client_disc_int_res
317  *
318  * Description      This function handles a discovery result when initiator.
319  *
320  *
321  * Returns          void
322  *
323  ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)324 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
325   uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
326 
327   APPL_TRACE_DEBUG("%s: Status: %d", __func__, p_data->disc_result.status);
328   tBTA_HF_CLIENT_CB* client_cb =
329       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
330   if (client_cb == NULL) {
331     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
332                      p_data->hdr.layer_specific);
333     return;
334   }
335 
336   /* if found service */
337   if (p_data->disc_result.status == SDP_SUCCESS ||
338       p_data->disc_result.status == SDP_DB_FULL) {
339     /* get attributes */
340     if (bta_hf_client_sdp_find_attr(client_cb)) {
341       event = BTA_HF_CLIENT_DISC_OK_EVT;
342     }
343   }
344 
345   /* free discovery db */
346   bta_hf_client_free_db(p_data);
347 
348   /* send ourselves sdp ok/fail event */
349   bta_hf_client_sm_execute(event, p_data);
350 }
351 
352 /*******************************************************************************
353  *
354  * Function         bta_hf_client_disc_acp_res
355  *
356  * Description      This function handles a discovery result when acceptor.
357  *
358  *
359  * Returns          void
360  *
361  ******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)362 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
363   tBTA_HF_CLIENT_CB* client_cb =
364       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
365   if (client_cb == NULL) {
366     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
367                      p_data->hdr.layer_specific);
368     return;
369   }
370 
371   /* if found service */
372   if (p_data->disc_result.status == SDP_SUCCESS ||
373       p_data->disc_result.status == SDP_DB_FULL) {
374     /* get attributes */
375     bta_hf_client_sdp_find_attr(client_cb);
376   }
377 
378   /* free discovery db */
379   bta_hf_client_free_db(p_data);
380 }
381 
382 /*******************************************************************************
383  *
384  * Function         bta_hf_client_rfc_data
385  *
386  * Description      Read and process data from RFCOMM.
387  *
388  *
389  * Returns          void
390  *
391  ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)392 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
393   tBTA_HF_CLIENT_CB* client_cb =
394       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
395   if (client_cb == NULL) {
396     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
397                      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,
406                        &len) == 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   APPL_TRACE_DEBUG("%s", __func__);
433   tBTA_HF_CLIENT_CB* client_cb =
434       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
435   if (client_cb == NULL) {
436     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
437                      p_data->hdr.layer_specific);
438     return;
439   }
440 
441   tBTA_HF_CLIENT evt;
442 
443   memset(&evt, 0, sizeof(evt));
444 
445   if (!client_cb->svc_conn) {
446     /* set state variable */
447     client_cb->svc_conn = true;
448 
449     /* call callback */
450     evt.conn.bd_addr = client_cb->peer_addr;
451     evt.conn.peer_feat = client_cb->peer_features;
452     evt.conn.chld_feat = client_cb->chld_features;
453 
454     bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
455   }
456 }
457