• 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 /*****************************************************************************
35  *  Constants
36  ****************************************************************************/
37 
38 /* maximum length of data to read from RFCOMM */
39 #define BTA_HF_CLIENT_RFC_READ_MAX 512
40 
41 /*******************************************************************************
42  *
43  * Function         bta_hf_client_start_close
44  *
45  * Description      Start the process of closing SCO and RFCOMM connection.
46  *
47  *
48  * Returns          void
49  *
50  ******************************************************************************/
bta_hf_client_start_close(tBTA_HF_CLIENT_DATA * p_data)51 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
52   tBTA_HF_CLIENT_CB* client_cb =
53       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
54   if (client_cb == NULL) {
55     APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
56                      p_data->hdr.layer_specific);
57     return;
58   }
59 
60   /* Take the link out of sniff and set L2C idle time to 0 */
61   bta_dm_pm_active(client_cb->peer_addr);
62   L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
63 
64   /* if SCO is open close SCO and wait on RFCOMM close */
65   if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
66     client_cb->sco_close_rfc = true;
67   } else {
68     bta_hf_client_rfc_do_close(p_data);
69   }
70 
71   /* always do SCO shutdown to handle all SCO corner cases */
72   bta_hf_client_sco_shutdown(client_cb);
73 }
74 
75 /*******************************************************************************
76  *
77  * Function         bta_hf_client_start_open
78  *
79  * Description      This starts an HF Client open.
80  *
81  *
82  * Returns          void
83  *
84  ******************************************************************************/
bta_hf_client_start_open(tBTA_HF_CLIENT_DATA * p_data)85 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
86   tBTA_HF_CLIENT_CB* client_cb =
87       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
88   if (client_cb == NULL) {
89     APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
90                      p_data->hdr.layer_specific);
91     return;
92   }
93 
94   /* store parameters */
95   if (p_data) {
96     client_cb->peer_addr = p_data->api_open.bd_addr;
97   }
98 
99   /* Check if RFCOMM has any incoming connection to avoid collision. */
100   RawAddress pending_bd_addr = RawAddress::kEmpty;
101   if (PORT_IsOpening(&pending_bd_addr)) {
102     /* Let the incoming connection goes through.                        */
103     /* Issue collision for now.                                         */
104     /* We will decide what to do when we find incoming connection later.*/
105     bta_hf_client_collision_cback(BTA_SYS_CONN_OPEN, BTA_ID_HS, 0,
106                                   client_cb->peer_addr);
107     return;
108   }
109 
110   /* set role */
111   client_cb->role = BTA_HF_CLIENT_INT;
112 
113   /* do service search */
114   bta_hf_client_do_disc(client_cb);
115 }
116 
117 /*******************************************************************************
118  *
119  * Function         bta_hf_client_rfc_open
120  *
121  * Description      Handle RFCOMM channel open.
122  *
123  *
124  * Returns          void
125  *
126  ******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)127 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
128   APPL_TRACE_DEBUG("%s", __func__);
129   tBTA_HF_CLIENT_CB* client_cb =
130       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
131   if (client_cb == NULL) {
132     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
133                      p_data->hdr.layer_specific);
134     return;
135   }
136 
137   bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
138 
139   /* start SLC procedure */
140   bta_hf_client_slc_seq(client_cb, false);
141 }
142 
143 /*******************************************************************************
144  *
145  * Function         bta_hf_client_rfc_acp_open
146  *
147  * Description      Handle RFCOMM channel open when accepting connection.
148  *
149  *
150  * Returns          void
151  *
152  ******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)153 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
154   APPL_TRACE_DEBUG("%s", __func__);
155   tBTA_HF_CLIENT_CB* client_cb =
156       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
157   if (client_cb == NULL) {
158     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
159                      p_data->hdr.layer_specific);
160     return;
161   }
162   /* set role */
163   client_cb->role = BTA_HF_CLIENT_ACP;
164 
165   APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, client_cb->conn_handle);
166 
167   /* get bd addr of peer */
168   uint16_t lcid = 0;
169   RawAddress dev_addr = RawAddress::kEmpty;
170   int status = PORT_CheckConnection(client_cb->conn_handle, &dev_addr, &lcid);
171   if (status != PORT_SUCCESS) {
172     LOG(ERROR) << __func__ << ": PORT_CheckConnection returned " << status;
173   }
174 
175   /* Collision Handling */
176   if (alarm_is_scheduled(client_cb->collision_timer)) {
177     alarm_cancel(client_cb->collision_timer);
178 
179     if (dev_addr == client_cb->peer_addr) {
180       /* If incoming and outgoing device are same, nothing more to do. */
181       /* Outgoing conn will be aborted because we have successful incoming conn.
182        */
183     } else {
184       /* Resume outgoing connection. */
185       bta_hf_client_resume_open(client_cb);
186     }
187   }
188 
189   client_cb->peer_addr = dev_addr;
190 
191   /* do service discovery to get features */
192   bta_hf_client_do_disc(client_cb);
193 
194   /* continue with open processing */
195   bta_hf_client_rfc_open(p_data);
196 }
197 
198 /*******************************************************************************
199  *
200  * Function         bta_hf_client_rfc_fail
201  *
202  * Description      RFCOMM connection failed.
203  *
204  *
205  * Returns          void
206  *
207  ******************************************************************************/
bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA * p_data)208 void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA* p_data) {
209   tBTA_HF_CLIENT_CB* client_cb =
210       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
211   if (client_cb == NULL) {
212     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
213                      p_data->hdr.layer_specific);
214     return;
215   }
216 
217   /* reinitialize stuff */
218   client_cb->peer_features = 0;
219   client_cb->chld_features = 0;
220   client_cb->role = BTA_HF_CLIENT_ACP;
221   client_cb->svc_conn = false;
222   client_cb->send_at_reply = false;
223   client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
224 
225   bta_hf_client_at_reset(client_cb);
226 }
227 
228 /*******************************************************************************
229  *
230  * Function         bta_hf_client_disc_fail
231  *
232  * Description      This function handles a discovery failure.
233  *
234  *
235  * Returns          void
236  *
237  ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)238 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
239   tBTA_HF_CLIENT_CB* client_cb =
240       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
241   if (client_cb == NULL) {
242     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
243                      p_data->hdr.layer_specific);
244     return;
245   }
246 }
247 
248 /*******************************************************************************
249  *
250  * Function         bta_hf_client_open_fail
251  *
252  * Description      open connection failed.
253  *
254  *
255  * Returns          void
256  *
257  ******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)258 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
259   tBTA_HF_CLIENT_CB* client_cb =
260       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
261   if (client_cb == NULL) {
262     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
263                      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 =
280       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
281   if (client_cb == NULL) {
282     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
283                      p_data->hdr.layer_specific);
284     return;
285   }
286 
287   bta_hf_client_at_reset(client_cb);
288 
289   bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
290 
291   /* call close cback */
292   tBTA_HF_CLIENT evt;
293   memset(&evt, 0, sizeof(evt));
294   evt.conn.bd_addr = client_cb->peer_addr;
295 
296   /* if not deregistering reopen server */
297   if (!bta_hf_client_cb_arr.deregister) {
298     /* Make sure SCO is shutdown */
299     bta_hf_client_sco_shutdown(client_cb);
300 
301     bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
302   }
303   /* else close port and deallocate scb */
304   else {
305     tBTA_HF_CLIENT evt;
306     memset(&evt, 0, sizeof(evt));
307     evt.reg.bd_addr = client_cb->peer_addr;
308     bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
309   }
310 }
311 
312 /*******************************************************************************
313  *
314  * Function         bta_hf_client_disc_int_res
315  *
316  * Description      This function handles a discovery result when initiator.
317  *
318  *
319  * Returns          void
320  *
321  ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)322 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
323   uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
324 
325   APPL_TRACE_DEBUG("%s: Status: %d", __func__, p_data->disc_result.status);
326   tBTA_HF_CLIENT_CB* client_cb =
327       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
328   if (client_cb == NULL) {
329     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
330                      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     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
365                      p_data->hdr.layer_specific);
366     return;
367   }
368 
369   /* if found service */
370   if (p_data->disc_result.status == SDP_SUCCESS ||
371       p_data->disc_result.status == SDP_DB_FULL) {
372     /* get attributes */
373     bta_hf_client_sdp_find_attr(client_cb);
374   }
375 
376   /* free discovery db */
377   bta_hf_client_free_db(p_data);
378 }
379 
380 /*******************************************************************************
381  *
382  * Function         bta_hf_client_rfc_data
383  *
384  * Description      Read and process data from RFCOMM.
385  *
386  *
387  * Returns          void
388  *
389  ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)390 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
391   tBTA_HF_CLIENT_CB* client_cb =
392       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
393   if (client_cb == NULL) {
394     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
395                      p_data->hdr.layer_specific);
396     return;
397   }
398 
399   uint16_t len;
400   char buf[BTA_HF_CLIENT_RFC_READ_MAX];
401   memset(buf, 0, sizeof(buf));
402   /* read data from rfcomm; if bad status, we're done */
403   while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
404                        &len) == PORT_SUCCESS) {
405     /* if no data, we're done */
406     if (len == 0) {
407       break;
408     }
409 
410     bta_hf_client_at_parse(client_cb, buf, len);
411 
412     /* no more data to read, we're done */
413     if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
414       break;
415     }
416   }
417 }
418 
419 /*******************************************************************************
420  *
421  * Function         bta_hf_client_svc_conn_open
422  *
423  * Description      Service level connection opened
424  *
425  *
426  * Returns          void
427  *
428  ******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)429 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
430   APPL_TRACE_DEBUG("%s", __func__);
431   tBTA_HF_CLIENT_CB* client_cb =
432       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
433   if (client_cb == NULL) {
434     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
435                      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