• 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 <string.h>
27 #include "bt_utils.h"
28 #include "bta_api.h"
29 #include "bta_dm_api.h"
30 #include "bta_hf_client_api.h"
31 #include "bta_hf_client_int.h"
32 #include "bta_sys.h"
33 #include "l2c_api.h"
34 #include "osi/include/compat.h"
35 #include "osi/include/osi.h"
36 #include "port_api.h"
37 #include "utl.h"
38 
39 /*****************************************************************************
40  *  Constants
41  ****************************************************************************/
42 
43 /* maximum length of data to read from RFCOMM */
44 #define BTA_HF_CLIENT_RFC_READ_MAX 512
45 
46 /*******************************************************************************
47  *
48  * Function         bta_hf_client_start_close
49  *
50  * Description      Start the process of closing SCO and RFCOMM connection.
51  *
52  *
53  * Returns          void
54  *
55  ******************************************************************************/
bta_hf_client_start_close(tBTA_HF_CLIENT_DATA * p_data)56 void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA* p_data) {
57   tBTA_HF_CLIENT_CB* client_cb =
58       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
59   if (client_cb == NULL) {
60     APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
61                      p_data->hdr.layer_specific);
62     return;
63   }
64 
65   /* Take the link out of sniff and set L2C idle time to 0 */
66   bta_dm_pm_active(client_cb->peer_addr);
67   L2CA_SetIdleTimeoutByBdAddr(client_cb->peer_addr, 0, BT_TRANSPORT_BR_EDR);
68 
69   /* if SCO is open close SCO and wait on RFCOMM close */
70   if (client_cb->sco_state == BTA_HF_CLIENT_SCO_OPEN_ST) {
71     client_cb->sco_close_rfc = true;
72   } else {
73     bta_hf_client_rfc_do_close(p_data);
74   }
75 
76   /* always do SCO shutdown to handle all SCO corner cases */
77   bta_hf_client_sco_shutdown(client_cb);
78 }
79 
80 /*******************************************************************************
81  *
82  * Function         bta_hf_client_start_open
83  *
84  * Description      This starts an HF Client open.
85  *
86  *
87  * Returns          void
88  *
89  ******************************************************************************/
bta_hf_client_start_open(tBTA_HF_CLIENT_DATA * p_data)90 void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA* p_data) {
91   tBTA_HF_CLIENT_CB* client_cb =
92       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
93   if (client_cb == NULL) {
94     APPL_TRACE_ERROR("%s: wrong handle to control block %d", __func__,
95                      p_data->hdr.layer_specific);
96     return;
97   }
98 
99   /* store parameters */
100   if (p_data) {
101     client_cb->peer_addr = p_data->api_open.bd_addr;
102     client_cb->cli_sec_mask = p_data->api_open.sec_mask;
103   }
104 
105   /* Check if RFCOMM has any incoming connection to avoid collision. */
106   RawAddress pending_bd_addr = RawAddress::kEmpty;
107   if (PORT_IsOpening(&pending_bd_addr)) {
108     /* Let the incoming connection goes through.                        */
109     /* Issue collision for now.                                         */
110     /* We will decide what to do when we find incoming connection later.*/
111     bta_hf_client_collision_cback(0, BTA_ID_HS, 0, client_cb->peer_addr);
112     return;
113   }
114 
115   /* set role */
116   client_cb->role = BTA_HF_CLIENT_INT;
117 
118   /* do service search */
119   bta_hf_client_do_disc(client_cb);
120 }
121 
122 /*******************************************************************************
123  *
124  * Function         bta_hf_client_rfc_open
125  *
126  * Description      Handle RFCOMM channel open.
127  *
128  *
129  * Returns          void
130  *
131  ******************************************************************************/
bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA * p_data)132 void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA* p_data) {
133   APPL_TRACE_DEBUG("%s", __func__);
134   tBTA_HF_CLIENT_CB* client_cb =
135       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
136   if (client_cb == NULL) {
137     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
138                      p_data->hdr.layer_specific);
139     return;
140   }
141 
142   bta_sys_conn_open(BTA_ID_HS, 1, client_cb->peer_addr);
143 
144   /* start SLC procedure */
145   bta_hf_client_slc_seq(client_cb, false);
146 }
147 
148 /*******************************************************************************
149  *
150  * Function         bta_hf_client_rfc_acp_open
151  *
152  * Description      Handle RFCOMM channel open when accepting connection.
153  *
154  *
155  * Returns          void
156  *
157  ******************************************************************************/
bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA * p_data)158 void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA* p_data) {
159   APPL_TRACE_DEBUG("%s", __func__);
160   tBTA_HF_CLIENT_CB* client_cb =
161       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
162   if (client_cb == NULL) {
163     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
164                      p_data->hdr.layer_specific);
165     return;
166   }
167   /* set role */
168   client_cb->role = BTA_HF_CLIENT_ACP;
169 
170   APPL_TRACE_DEBUG("%s: conn_handle %d", __func__, 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) << __func__ << ": PORT_CheckConnection returned " << 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     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
218                      p_data->hdr.layer_specific);
219     return;
220   }
221 
222   /* reinitialize stuff */
223   client_cb->peer_features = 0;
224   client_cb->chld_features = 0;
225   client_cb->role = BTA_HF_CLIENT_ACP;
226   client_cb->svc_conn = false;
227   client_cb->send_at_reply = false;
228   client_cb->negotiated_codec = BTM_SCO_CODEC_CVSD;
229 
230   bta_hf_client_at_reset(client_cb);
231 }
232 
233 /*******************************************************************************
234  *
235  * Function         bta_hf_client_disc_fail
236  *
237  * Description      This function handles a discovery failure.
238  *
239  *
240  * Returns          void
241  *
242  ******************************************************************************/
bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA * p_data)243 void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA* p_data) {
244   tBTA_HF_CLIENT_CB* client_cb =
245       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
246   if (client_cb == NULL) {
247     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
248                      p_data->hdr.layer_specific);
249     return;
250   }
251 }
252 
253 /*******************************************************************************
254  *
255  * Function         bta_hf_client_open_fail
256  *
257  * Description      open connection failed.
258  *
259  *
260  * Returns          void
261  *
262  ******************************************************************************/
bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA * p_data)263 void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA* p_data) {
264   tBTA_HF_CLIENT_CB* client_cb =
265       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
266   if (client_cb == NULL) {
267     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
268                      p_data->hdr.layer_specific);
269     return;
270   }
271 }
272 
273 /*******************************************************************************
274  *
275  * Function         bta_hf_client_rfc_close
276  *
277  * Description      RFCOMM connection closed.
278  *
279  *
280  * Returns          void
281  *
282  ******************************************************************************/
bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA * p_data)283 void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA* p_data) {
284   tBTA_HF_CLIENT_CB* client_cb =
285       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
286   if (client_cb == NULL) {
287     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
288                      p_data->hdr.layer_specific);
289     return;
290   }
291 
292   bta_hf_client_at_reset(client_cb);
293 
294   bta_sys_conn_close(BTA_ID_HS, 1, client_cb->peer_addr);
295 
296   /* call close cback */
297   tBTA_HF_CLIENT evt;
298   memset(&evt, 0, sizeof(evt));
299   evt.conn.bd_addr = client_cb->peer_addr;
300 
301   /* if not deregistering reopen server */
302   if (!bta_hf_client_cb_arr.deregister) {
303     /* Make sure SCO is shutdown */
304     bta_hf_client_sco_shutdown(client_cb);
305 
306     bta_sys_sco_unuse(BTA_ID_HS, 1, client_cb->peer_addr);
307   }
308   /* else close port and deallocate scb */
309   else {
310     tBTA_HF_CLIENT evt;
311     memset(&evt, 0, sizeof(evt));
312     evt.reg.bd_addr = client_cb->peer_addr;
313     bta_hf_client_app_callback(BTA_HF_CLIENT_DISABLE_EVT, &evt);
314   }
315 }
316 
317 /*******************************************************************************
318  *
319  * Function         bta_hf_client_disc_int_res
320  *
321  * Description      This function handles a discovery result when initiator.
322  *
323  *
324  * Returns          void
325  *
326  ******************************************************************************/
bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA * p_data)327 void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA* p_data) {
328   uint16_t event = BTA_HF_CLIENT_DISC_FAIL_EVT;
329 
330   APPL_TRACE_DEBUG("%s: Status: %d", __func__, p_data->disc_result.status);
331   tBTA_HF_CLIENT_CB* client_cb =
332       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
333   if (client_cb == NULL) {
334     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
335                      p_data->hdr.layer_specific);
336     return;
337   }
338 
339   /* if found service */
340   if (p_data->disc_result.status == SDP_SUCCESS ||
341       p_data->disc_result.status == SDP_DB_FULL) {
342     /* get attributes */
343     if (bta_hf_client_sdp_find_attr(client_cb)) {
344       event = BTA_HF_CLIENT_DISC_OK_EVT;
345     }
346   }
347 
348   /* free discovery db */
349   bta_hf_client_free_db(p_data);
350 
351   /* send ourselves sdp ok/fail event */
352   bta_hf_client_sm_execute(event, p_data);
353 }
354 
355 /*******************************************************************************
356  *
357  * Function         bta_hf_client_disc_acp_res
358  *
359  * Description      This function handles a discovery result when acceptor.
360  *
361  *
362  * Returns          void
363  *
364  ******************************************************************************/
bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA * p_data)365 void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA* p_data) {
366   tBTA_HF_CLIENT_CB* client_cb =
367       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
368   if (client_cb == NULL) {
369     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
370                      p_data->hdr.layer_specific);
371     return;
372   }
373 
374   /* if found service */
375   if (p_data->disc_result.status == SDP_SUCCESS ||
376       p_data->disc_result.status == SDP_DB_FULL) {
377     /* get attributes */
378     bta_hf_client_sdp_find_attr(client_cb);
379   }
380 
381   /* free discovery db */
382   bta_hf_client_free_db(p_data);
383 }
384 
385 /*******************************************************************************
386  *
387  * Function         bta_hf_client_rfc_data
388  *
389  * Description      Read and process data from RFCOMM.
390  *
391  *
392  * Returns          void
393  *
394  ******************************************************************************/
bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA * p_data)395 void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA* p_data) {
396   tBTA_HF_CLIENT_CB* client_cb =
397       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
398   if (client_cb == NULL) {
399     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
400                      p_data->hdr.layer_specific);
401     return;
402   }
403 
404   uint16_t len;
405   char buf[BTA_HF_CLIENT_RFC_READ_MAX];
406   memset(buf, 0, sizeof(buf));
407   /* read data from rfcomm; if bad status, we're done */
408   while (PORT_ReadData(client_cb->conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX,
409                        &len) == PORT_SUCCESS) {
410     /* if no data, we're done */
411     if (len == 0) {
412       break;
413     }
414 
415     bta_hf_client_at_parse(client_cb, buf, len);
416 
417     /* no more data to read, we're done */
418     if (len < BTA_HF_CLIENT_RFC_READ_MAX) {
419       break;
420     }
421   }
422 }
423 
424 /*******************************************************************************
425  *
426  * Function         bta_hf_client_svc_conn_open
427  *
428  * Description      Service level connection opened
429  *
430  *
431  * Returns          void
432  *
433  ******************************************************************************/
bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA * p_data)434 void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA* p_data) {
435   APPL_TRACE_DEBUG("%s", __func__);
436   tBTA_HF_CLIENT_CB* client_cb =
437       bta_hf_client_find_cb_by_handle(p_data->hdr.layer_specific);
438   if (client_cb == NULL) {
439     APPL_TRACE_ERROR("%s: cb not found for handle %d", __func__,
440                      p_data->hdr.layer_specific);
441     return;
442   }
443 
444   tBTA_HF_CLIENT evt;
445 
446   memset(&evt, 0, sizeof(evt));
447 
448   if (!client_cb->svc_conn) {
449     /* set state variable */
450     client_cb->svc_conn = true;
451 
452     /* call callback */
453     evt.conn.bd_addr = client_cb->peer_addr;
454     evt.conn.peer_feat = client_cb->peer_features;
455     evt.conn.chld_feat = client_cb->chld_features;
456 
457     bta_hf_client_app_callback(BTA_HF_CLIENT_CONN_EVT, &evt);
458   }
459 }
460