1 /******************************************************************************
2 *
3 * Copyright (C) 2003-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains action functions for the audio gateway.
22 *
23 ******************************************************************************/
24
25 #include "bta_api.h"
26 #include "bd.h"
27 #include "bta_sys.h"
28 #include "bta_ag_api.h"
29 #include "bta_ag_co.h"
30 #include "bta_ag_int.h"
31 #include "port_api.h"
32 #include "utl.h"
33 #include <string.h>
34 #include "bta_dm_int.h"
35 #include "l2c_api.h"
36
37 /*****************************************************************************
38 ** Constants
39 *****************************************************************************/
40
41 /* maximum length of data to read from RFCOMM */
42 #define BTA_AG_RFC_READ_MAX 512
43
44 /* maximum AT command length */
45 #define BTA_AG_CMD_MAX 512
46
47 const UINT16 bta_ag_uuid[BTA_AG_NUM_IDX] =
48 {
49 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
50 UUID_SERVCLASS_AG_HANDSFREE
51 };
52
53 const UINT8 bta_ag_sec_id[BTA_AG_NUM_IDX] =
54 {
55 BTM_SEC_SERVICE_HEADSET_AG,
56 BTM_SEC_SERVICE_AG_HANDSFREE
57 };
58
59 const tBTA_SERVICE_ID bta_ag_svc_id[BTA_AG_NUM_IDX] =
60 {
61 BTA_HSP_SERVICE_ID,
62 BTA_HFP_SERVICE_ID
63 };
64
65 const tBTA_SERVICE_MASK bta_ag_svc_mask[BTA_AG_NUM_IDX] =
66 {
67 BTA_HSP_SERVICE_MASK,
68 BTA_HFP_SERVICE_MASK
69 };
70
71 typedef void (*tBTA_AG_ATCMD_CBACK)(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
72 char *p_arg, INT16 int_arg);
73
74 const tBTA_AG_ATCMD_CBACK bta_ag_at_cback_tbl[BTA_AG_NUM_IDX] =
75 {
76 bta_ag_at_hsp_cback,
77 bta_ag_at_hfp_cback
78 };
79
80 /*******************************************************************************
81 **
82 ** Function bta_ag_cback_open
83 **
84 ** Description Send open callback event to application.
85 **
86 **
87 ** Returns void
88 **
89 *******************************************************************************/
bta_ag_cback_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data,tBTA_AG_STATUS status)90 static void bta_ag_cback_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data, tBTA_AG_STATUS status)
91 {
92 tBTA_AG_OPEN open;
93
94 /* call app callback with open event */
95 open.hdr.handle = bta_ag_scb_to_idx(p_scb);
96 open.hdr.app_id = p_scb->app_id;
97 open.status = status;
98 open.service_id = bta_ag_svc_id[p_scb->conn_service];
99 if(p_data)
100 {
101 /* if p_data is provided then we need to pick the bd address from the open api structure */
102 bdcpy(open.bd_addr, p_data->api_open.bd_addr);
103 }
104 else
105 {
106 bdcpy(open.bd_addr, p_scb->peer_addr);
107 }
108
109 (*bta_ag_cb.p_cback)(BTA_AG_OPEN_EVT, (tBTA_AG *) &open);
110 }
111
112 /*******************************************************************************
113 **
114 ** Function bta_ag_register
115 **
116 ** Description This function initializes values of the AG cb and sets up
117 ** the SDP record for the services.
118 **
119 **
120 ** Returns void
121 **
122 *******************************************************************************/
bta_ag_register(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)123 void bta_ag_register(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
124 {
125 tBTA_AG_REGISTER reg;
126
127 /* initialize control block */
128 p_scb->reg_services = p_data->api_register.services;
129 p_scb->serv_sec_mask = p_data->api_register.sec_mask;
130 p_scb->features = p_data->api_register.features;
131 p_scb->app_id = p_data->api_register.app_id;
132
133 /* create SDP records */
134 bta_ag_create_records(p_scb, p_data);
135
136 /* start RFCOMM servers */
137 bta_ag_start_servers(p_scb, p_scb->reg_services);
138
139 /* call app callback with register event */
140 reg.hdr.handle = bta_ag_scb_to_idx(p_scb);
141 reg.hdr.app_id = p_scb->app_id;
142 reg.status = BTA_AG_SUCCESS;
143 (*bta_ag_cb.p_cback)(BTA_AG_REGISTER_EVT, (tBTA_AG *) ®);
144 }
145
146 /*******************************************************************************
147 **
148 ** Function bta_ag_deregister
149 **
150 ** Description This function removes the sdp records, closes the RFCOMM
151 ** servers, and deallocates the service control block.
152 **
153 **
154 ** Returns void
155 **
156 *******************************************************************************/
bta_ag_deregister(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)157 void bta_ag_deregister(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
158 {
159 /* set dealloc */
160 p_scb->dealloc = TRUE;
161
162 /* remove sdp records */
163 bta_ag_del_records(p_scb, p_data);
164
165 /* remove rfcomm servers */
166 bta_ag_close_servers(p_scb, p_scb->reg_services);
167
168 /* dealloc */
169 bta_ag_scb_dealloc(p_scb);
170 }
171
172 /*******************************************************************************
173 **
174 ** Function bta_ag_start_dereg
175 **
176 ** Description Start a deregister event.
177 **
178 **
179 ** Returns void
180 **
181 *******************************************************************************/
bta_ag_start_dereg(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)182 void bta_ag_start_dereg(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
183 {
184 /* set dealloc */
185 p_scb->dealloc = TRUE;
186
187 /* remove sdp records */
188 bta_ag_del_records(p_scb, p_data);
189 }
190
191 /*******************************************************************************
192 **
193 ** Function bta_ag_start_open
194 **
195 ** Description This starts an AG open.
196 **
197 **
198 ** Returns void
199 **
200 *******************************************************************************/
bta_ag_start_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)201 void bta_ag_start_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
202 {
203 BD_ADDR pending_bd_addr;
204
205 /* store parameters */
206 if (p_data)
207 {
208 bdcpy(p_scb->peer_addr, p_data->api_open.bd_addr);
209 p_scb->open_services = p_data->api_open.services;
210 p_scb->cli_sec_mask = p_data->api_open.sec_mask;
211 }
212
213 /* Check if RFCOMM has any incoming connection to avoid collision. */
214 if (PORT_IsOpening (pending_bd_addr))
215 {
216 /* Let the incoming connection goes through. */
217 /* Issue collision for this scb for now. */
218 /* We will decide what to do when we find incoming connetion later. */
219 bta_ag_collision_cback (0, BTA_ID_AG, 0, p_scb->peer_addr);
220 return;
221 }
222
223 /* close servers */
224 bta_ag_close_servers(p_scb, p_scb->reg_services);
225
226 /* set role */
227 p_scb->role = BTA_AG_INT;
228
229 /* do service search */
230 bta_ag_do_disc(p_scb, p_scb->open_services);
231 }
232
233 /*******************************************************************************
234 **
235 ** Function bta_ag_disc_int_res
236 **
237 ** Description This function handles a discovery result when initiator.
238 **
239 **
240 ** Returns void
241 **
242 *******************************************************************************/
bta_ag_disc_int_res(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)243 void bta_ag_disc_int_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
244 {
245 UINT16 event = BTA_AG_DISC_FAIL_EVT;
246
247 APPL_TRACE_DEBUG1 ("bta_ag_disc_int_res: Status: %d", p_data->disc_result.status);
248
249 /* if found service */
250 if (p_data->disc_result.status == SDP_SUCCESS ||
251 p_data->disc_result.status == SDP_DB_FULL)
252 {
253 /* get attributes */
254 if (bta_ag_sdp_find_attr(p_scb, p_scb->open_services))
255 {
256 /* set connected service */
257 p_scb->conn_service = bta_ag_service_to_idx(p_scb->open_services);
258
259 /* send ourselves sdp ok event */
260 event = BTA_AG_DISC_OK_EVT;
261 }
262 }
263
264 /* free discovery db */
265 bta_ag_free_db(p_scb, p_data);
266
267 /* if service not found check if we should search for other service */
268 if ((event == BTA_AG_DISC_FAIL_EVT) &&
269 (p_data->disc_result.status == SDP_SUCCESS ||
270 p_data->disc_result.status == SDP_DB_FULL ||
271 p_data->disc_result.status == SDP_NO_RECS_MATCH))
272 {
273 if ((p_scb->open_services & BTA_HFP_SERVICE_MASK) &&
274 (p_scb->open_services & BTA_HSP_SERVICE_MASK))
275 {
276 /* search for HSP */
277 p_scb->open_services &= ~BTA_HFP_SERVICE_MASK;
278 bta_ag_do_disc(p_scb, p_scb->open_services);
279 }
280 else if ((p_scb->open_services & BTA_HSP_SERVICE_MASK) &&
281 (p_scb->hsp_version == HSP_VERSION_1_2))
282 {
283 /* search for UUID_SERVCLASS_HEADSET for HSP 1.0 device */
284 p_scb->hsp_version = HSP_VERSION_1_0;
285 bta_ag_do_disc(p_scb, p_scb->open_services);
286 }
287 else
288 {
289 /* send ourselves sdp ok/fail event */
290 bta_ag_sm_execute(p_scb, event, p_data);
291 }
292 }
293 else
294 {
295 /* send ourselves sdp ok/fail event */
296 bta_ag_sm_execute(p_scb, event, p_data);
297 }
298
299 }
300
301 /*******************************************************************************
302 **
303 ** Function bta_ag_disc_acp_res
304 **
305 ** Description This function handles a discovery result when acceptor.
306 **
307 **
308 ** Returns void
309 **
310 *******************************************************************************/
bta_ag_disc_acp_res(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)311 void bta_ag_disc_acp_res(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
312 {
313 /* if found service */
314 if (p_data->disc_result.status == SDP_SUCCESS ||
315 p_data->disc_result.status == SDP_DB_FULL)
316 {
317 /* get attributes */
318 bta_ag_sdp_find_attr(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
319 }
320
321 /* free discovery db */
322 bta_ag_free_db(p_scb, p_data);
323 }
324
325 /*******************************************************************************
326 **
327 ** Function bta_ag_disc_fail
328 **
329 ** Description This function handles a discovery failure.
330 **
331 **
332 ** Returns void
333 **
334 *******************************************************************************/
bta_ag_disc_fail(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)335 void bta_ag_disc_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
336 {
337 /* reopen registered servers */
338 bta_ag_start_servers(p_scb, p_scb->reg_services);
339
340 /* reinitialize stuff */
341
342 /* call open cback w. failure */
343 bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_SDP);
344 }
345
346 /*******************************************************************************
347 **
348 ** Function bta_ag_open_fail
349 **
350 ** Description open connection failed.
351 **
352 **
353 ** Returns void
354 **
355 *******************************************************************************/
bta_ag_open_fail(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)356 void bta_ag_open_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
357 {
358 /* call open cback w. failure */
359 bta_ag_cback_open(p_scb, p_data, BTA_AG_FAIL_RESOURCES);
360 }
361
362 /*******************************************************************************
363 **
364 ** Function bta_ag_rfc_fail
365 **
366 ** Description RFCOMM connection failed.
367 **
368 **
369 ** Returns void
370 **
371 *******************************************************************************/
bta_ag_rfc_fail(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)372 void bta_ag_rfc_fail(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
373 {
374 /* reinitialize stuff */
375 p_scb->conn_handle = 0;
376 p_scb->conn_service = 0;
377 p_scb->peer_features = 0;
378 #if (BTM_WBS_INCLUDED == TRUE )
379 p_scb->peer_codecs = BTA_AG_CODEC_NONE;
380 p_scb->sco_codec = BTA_AG_CODEC_NONE;
381 #endif
382 p_scb->role = 0;
383 p_scb->svc_conn = FALSE;
384 p_scb->hsp_version = HSP_VERSION_1_2;
385
386 /* reopen registered servers */
387 bta_ag_start_servers(p_scb, p_scb->reg_services);
388
389 /* call open cback w. failure */
390 bta_ag_cback_open(p_scb, NULL, BTA_AG_FAIL_RFCOMM);
391 }
392
393 /*******************************************************************************
394 **
395 ** Function bta_ag_rfc_close
396 **
397 ** Description RFCOMM connection closed.
398 **
399 **
400 ** Returns void
401 **
402 *******************************************************************************/
bta_ag_rfc_close(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)403 void bta_ag_rfc_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
404 {
405 tBTA_AG_HDR close;
406 tBTA_SERVICE_MASK services;
407 int i, num_active_conn = 0;
408
409 #ifdef _WIN32_WCE
410 /* The BTE RFCOMM automatically removes the connection when closed, but BTW does not */
411 if (p_scb->conn_handle != 0)
412 RFCOMM_RemoveConnection (p_scb->conn_handle);
413 #endif
414
415 /* reinitialize stuff */
416 p_scb->conn_service = 0;
417 p_scb->peer_features = 0;
418 #if (BTM_WBS_INCLUDED == TRUE )
419 p_scb->peer_codecs = BTA_AG_CODEC_NONE;
420 p_scb->sco_codec = BTA_AG_CODEC_NONE;
421 #endif
422 p_scb->role = 0;
423 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
424 p_scb->svc_conn = FALSE;
425 p_scb->hsp_version = HSP_VERSION_1_2;
426 bta_ag_at_reinit(&p_scb->at_cb);
427
428 /* stop timers */
429 bta_sys_stop_timer(&p_scb->act_timer);
430 #if (BTM_WBS_INCLUDED == TRUE)
431 bta_sys_stop_timer(&p_scb->cn_timer);
432 #endif
433
434 close.handle = bta_ag_scb_to_idx(p_scb);
435 close.app_id = p_scb->app_id;
436
437 bta_sys_conn_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
438
439 /* call close call-out */
440 bta_ag_co_data_close(close.handle);
441
442 /* call close cback */
443 (*bta_ag_cb.p_cback)(BTA_AG_CLOSE_EVT, (tBTA_AG *) &close);
444
445 /* if not deregistering (deallocating) reopen registered servers */
446 if (p_scb->dealloc == FALSE)
447 {
448 /* Clear peer bd_addr so instance can be reused */
449 bdcpy(p_scb->peer_addr, bd_addr_null);
450
451 /* start only unopened server */
452 services = p_scb->reg_services;
453 for (i = 0; i < BTA_AG_NUM_IDX && services != 0; i++)
454 {
455 if(p_scb->serv_handle[i])
456 services &= ~((tBTA_SERVICE_MASK)1 << (BTA_HSP_SERVICE_ID + i));
457 }
458 bta_ag_start_servers(p_scb, services);
459
460 p_scb->conn_handle = 0;
461
462 /* Make sure SCO state is BTA_AG_SCO_SHUTDOWN_ST */
463 bta_ag_sco_shutdown(p_scb, NULL);
464
465 /* Check if all the SLCs are down */
466 for (i = 0; i < BTA_AG_NUM_SCB; i++)
467 {
468 if (bta_ag_cb.scb[i].in_use && bta_ag_cb.scb[i].svc_conn)
469 num_active_conn++;
470 }
471
472 if(!num_active_conn)
473 {
474 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
475 }
476
477 }
478 /* else close port and deallocate scb */
479 else
480 {
481 RFCOMM_RemoveServer(p_scb->conn_handle);
482 bta_ag_scb_dealloc(p_scb);
483 }
484 }
485
486 /*******************************************************************************
487 **
488 ** Function bta_ag_rfc_open
489 **
490 ** Description Handle RFCOMM channel open.
491 **
492 **
493 ** Returns void
494 **
495 *******************************************************************************/
bta_ag_rfc_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)496 void bta_ag_rfc_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
497 {
498 /* initialize AT feature variables */
499 p_scb->clip_enabled = FALSE;
500 p_scb->ccwa_enabled = FALSE;
501 p_scb->cmer_enabled = FALSE;
502 p_scb->cmee_enabled = FALSE;
503 p_scb->inband_enabled = ((p_scb->features & BTA_AG_FEAT_INBAND) == BTA_AG_FEAT_INBAND);
504
505 /* set up AT command interpreter */
506 p_scb->at_cb.p_at_tbl = (tBTA_AG_AT_CMD *) bta_ag_at_tbl[p_scb->conn_service];
507 p_scb->at_cb.p_cmd_cback = (tBTA_AG_AT_CMD_CBACK *) bta_ag_at_cback_tbl[p_scb->conn_service];
508 p_scb->at_cb.p_err_cback = (tBTA_AG_AT_ERR_CBACK *) bta_ag_at_err_cback;
509 p_scb->at_cb.p_user = p_scb;
510 p_scb->at_cb.cmd_max_len = BTA_AG_CMD_MAX;
511 bta_ag_at_init(&p_scb->at_cb);
512
513 /* call app open call-out */
514 bta_ag_co_data_open(bta_ag_scb_to_idx(p_scb), bta_ag_svc_id[p_scb->conn_service]);
515
516 bta_sys_conn_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
517
518 bta_ag_cback_open(p_scb, NULL, BTA_AG_SUCCESS);
519
520 if (p_scb->conn_service == BTA_AG_HFP)
521 {
522 /* if hfp start timer for service level conn */
523 bta_sys_start_timer(&p_scb->act_timer, BTA_AG_SVC_TOUT_EVT, p_bta_ag_cfg->conn_tout);
524 }
525 else
526 {
527 /* else service level conn is open */
528 bta_ag_svc_conn_open(p_scb, p_data);
529 }
530 }
531
532 /*******************************************************************************
533 **
534 ** Function bta_ag_rfc_acp_open
535 **
536 ** Description Handle RFCOMM channel open when accepting connection.
537 **
538 **
539 ** Returns void
540 **
541 *******************************************************************************/
bta_ag_rfc_acp_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)542 void bta_ag_rfc_acp_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
543 {
544 UINT16 lcid;
545 int i;
546 tBTA_AG_SCB *ag_scb, *other_scb;
547 BD_ADDR dev_addr;
548 int status;
549
550 /* set role */
551 p_scb->role = BTA_AG_ACP;
552
553 APPL_TRACE_DEBUG2 ("bta_ag_rfc_acp_open: serv_handle0 = %d serv_handle1 = %d",
554 p_scb->serv_handle[0], p_scb->serv_handle[1]);
555
556 /* get bd addr of peer */
557 if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
558 {
559 APPL_TRACE_DEBUG1 ("bta_ag_rfc_acp_open error PORT_CheckConnection returned status %d", status);
560 }
561
562 /* Collision Handling */
563 for (i = 0, ag_scb = &bta_ag_cb.scb[0]; i < BTA_AG_NUM_SCB; i++, ag_scb++)
564 {
565 if ((ag_scb->in_use) && (ag_scb->colli_tmr_on))
566 {
567 /* stop collision timer */
568 ag_scb->colli_tmr_on = FALSE;
569 bta_sys_stop_timer (&ag_scb->colli_timer);
570
571 if (bdcmp (dev_addr, ag_scb->peer_addr) == 0)
572 {
573 /* If incoming and outgoing device are same, nothing more to do. */
574 /* Outgoing conn will be aborted because we have successful incoming conn. */
575 }
576 else
577 {
578 /* Resume outgoing connection. */
579 other_scb = bta_ag_get_other_idle_scb (p_scb);
580 if (other_scb)
581 {
582 bdcpy(other_scb->peer_addr, ag_scb->peer_addr);
583 other_scb->open_services = ag_scb->open_services;
584 other_scb->cli_sec_mask = ag_scb->cli_sec_mask;
585
586 bta_ag_resume_open (other_scb);
587 }
588 }
589
590 break;
591 }
592 }
593
594 bdcpy (p_scb->peer_addr, dev_addr);
595
596 /* determine connected service from port handle */
597 for (i = 0; i < BTA_AG_NUM_IDX; i++)
598 {
599 APPL_TRACE_DEBUG3 ("bta_ag_rfc_acp_open: i = %d serv_handle = %d port_handle = %d",
600 i, p_scb->serv_handle[i], p_data->rfc.port_handle);
601
602 if (p_scb->serv_handle[i] == p_data->rfc.port_handle)
603 {
604 p_scb->conn_service = i;
605 p_scb->conn_handle = p_data->rfc.port_handle;
606 break;
607 }
608 }
609
610 APPL_TRACE_DEBUG2 ("bta_ag_rfc_acp_open: conn_service = %d conn_handle = %d",
611 p_scb->conn_service, p_scb->conn_handle);
612
613 /* close any unopened server */
614 bta_ag_close_servers(p_scb, (p_scb->reg_services & ~bta_ag_svc_mask[p_scb->conn_service]));
615
616 /* do service discovery to get features */
617 bta_ag_do_disc(p_scb, bta_ag_svc_mask[p_scb->conn_service]);
618
619 /* continue with common open processing */
620 bta_ag_rfc_open(p_scb, p_data);
621
622
623
624 }
625
626 /*******************************************************************************
627 **
628 ** Function bta_ag_rfc_data
629 **
630 ** Description Read and process data from RFCOMM.
631 **
632 **
633 ** Returns void
634 **
635 *******************************************************************************/
bta_ag_rfc_data(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)636 void bta_ag_rfc_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
637 {
638 UINT16 len;
639 char buf[BTA_AG_RFC_READ_MAX];
640
641 memset(buf, 0, BTA_AG_RFC_READ_MAX);
642
643 /* do the following */
644 for(;;)
645 {
646 /* read data from rfcomm; if bad status, we're done */
647 if (PORT_ReadData(p_scb->conn_handle, buf, BTA_AG_RFC_READ_MAX, &len) != PORT_SUCCESS)
648 {
649 break;
650 }
651
652 /* if no data, we're done */
653 if (len == 0)
654 {
655 break;
656 }
657
658 /* run AT command interpreter on data */
659 bta_ag_at_parse(&p_scb->at_cb, buf, len);
660
661 /* no more data to read, we're done */
662 if (len < BTA_AG_RFC_READ_MAX)
663 {
664 break;
665 }
666 }
667 }
668
669 /*******************************************************************************
670 **
671 ** Function bta_ag_start_close
672 **
673 ** Description Start the process of closing SCO and RFCOMM connection.
674 **
675 **
676 ** Returns void
677 **
678 *******************************************************************************/
bta_ag_start_close(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)679 void bta_ag_start_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
680 {
681 /* Take the link out of sniff and set L2C idle time to 0 */
682 bta_dm_pm_active(p_scb->peer_addr);
683 L2CA_SetIdleTimeoutByBdAddr(p_scb->peer_addr, 0);
684
685 /* if SCO is open close SCO and wait on RFCOMM close */
686 if (bta_ag_sco_is_open(p_scb))
687 {
688 p_scb->post_sco = BTA_AG_POST_SCO_CLOSE_RFC;
689 }
690 else
691 {
692 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
693 bta_ag_rfc_do_close(p_scb, p_data);
694 }
695
696 /* always do SCO shutdown to handle all SCO corner cases */
697 bta_ag_sco_shutdown(p_scb, p_data);
698 }
699
700 /*******************************************************************************
701 **
702 ** Function bta_ag_post_sco_open
703 **
704 ** Description Perform post-SCO open action, if any
705 **
706 **
707 ** Returns void
708 **
709 *******************************************************************************/
bta_ag_post_sco_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)710 void bta_ag_post_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
711 {
712 switch (p_scb->post_sco)
713 {
714 case BTA_AG_POST_SCO_RING:
715 bta_ag_send_ring(p_scb, p_data);
716 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
717 break;
718
719 case BTA_AG_POST_SCO_CALL_CONN:
720 bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
721 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
722 break;
723
724 default:
725 break;
726 }
727 }
728
729 /*******************************************************************************
730 **
731 ** Function bta_ag_post_sco_close
732 **
733 ** Description Perform post-SCO close action, if any
734 **
735 **
736 ** Returns void
737 **
738 *******************************************************************************/
bta_ag_post_sco_close(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)739 void bta_ag_post_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
740 {
741 switch (p_scb->post_sco)
742 {
743 case BTA_AG_POST_SCO_CLOSE_RFC:
744 bta_ag_rfc_do_close(p_scb, p_data);
745 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
746 break;
747
748 case BTA_AG_POST_SCO_CALL_CONN:
749 bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_CONN_RES);
750 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
751 break;
752
753 case BTA_AG_POST_SCO_CALL_ORIG:
754 bta_ag_send_call_inds(p_scb, BTA_AG_OUT_CALL_ORIG_RES);
755 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
756 break;
757
758 case BTA_AG_POST_SCO_CALL_END:
759 bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
760 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
761 break;
762
763 case BTA_AG_POST_SCO_CALL_END_INCALL:
764 bta_ag_send_call_inds(p_scb, BTA_AG_END_CALL_RES);
765
766 /* Sending callsetup IND and Ring were defered to after SCO close. */
767 bta_ag_send_call_inds(p_scb, BTA_AG_IN_CALL_RES);
768
769 if (bta_ag_inband_enabled(p_scb) && !(p_scb->features & BTA_AG_FEAT_NOSCO))
770 {
771 p_scb->post_sco = BTA_AG_POST_SCO_RING;
772 bta_ag_sco_open(p_scb, p_data);
773 }
774 else
775 {
776 p_scb->post_sco = BTA_AG_POST_SCO_NONE;
777 bta_ag_send_ring(p_scb, p_data);
778 }
779 break;
780
781 default:
782 break;
783 }
784 }
785
786 /*******************************************************************************
787 **
788 ** Function bta_ag_svc_conn_open
789 **
790 ** Description Service level connection opened
791 **
792 **
793 ** Returns void
794 **
795 *******************************************************************************/
bta_ag_svc_conn_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)796 void bta_ag_svc_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
797 {
798 tBTA_AG_CONN evt;
799
800 if (!p_scb->svc_conn)
801 {
802 /* set state variable */
803 p_scb->svc_conn = TRUE;
804
805 /* Clear AT+BIA mask from previous SLC if any. */
806 p_scb->bia_masked_out = 0;
807
808 /* stop timer */
809 bta_sys_stop_timer(&p_scb->act_timer);
810
811 /* call callback */
812 evt.hdr.handle = bta_ag_scb_to_idx(p_scb);
813 evt.hdr.app_id = p_scb->app_id;
814 evt.peer_feat = p_scb->peer_features;
815 #if (BTM_WBS_INCLUDED == TRUE )
816 evt.peer_codec = p_scb->peer_codecs;
817 #endif
818
819 if ((p_scb->call_ind != BTA_AG_CALL_INACTIVE) ||
820 (p_scb->callsetup_ind != BTA_AG_CALLSETUP_NONE))
821 {
822 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
823 }
824
825 (*bta_ag_cb.p_cback)(BTA_AG_CONN_EVT, (tBTA_AG *) &evt);
826 }
827 }
828
829 /*******************************************************************************
830 **
831 ** Function bta_ag_ci_rx_data
832 **
833 ** Description Send result code
834 **
835 ** Returns void
836 **
837 *******************************************************************************/
bta_ag_ci_rx_data(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)838 void bta_ag_ci_rx_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
839 {
840 UINT16 len;
841 tBTA_AG_CI_RX_WRITE *p_rx_write_msg = (tBTA_AG_CI_RX_WRITE *)p_data;
842 char *p_data_area = (char *)(p_rx_write_msg+1); /* Point to data area after header */
843
844 /* send to RFCOMM */
845 PORT_WriteData(p_scb->conn_handle, p_data_area, strlen(p_data_area), &len);
846 }
847
848 /*******************************************************************************
849 **
850 ** Function bta_ag_rcvd_slc_ready
851 **
852 ** Description Handles SLC ready call-in in case of pass-through mode.
853 **
854 ** Returns void
855 **
856 *******************************************************************************/
bta_ag_rcvd_slc_ready(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)857 void bta_ag_rcvd_slc_ready(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
858 {
859 APPL_TRACE_DEBUG1("bta_ag_rcvd_slc_ready: handle = %d", bta_ag_scb_to_idx(p_scb));
860
861 if (bta_ag_cb.parse_mode == BTA_AG_PASS_THROUGH)
862 {
863 /* In pass-through mode, BTA knows that SLC is ready only through call-in. */
864 bta_ag_svc_conn_open(p_scb, NULL);
865 }
866 }
867
868