1/******************************************************************************
2 *
3 *  Copyright (c) 2014 The Android Open Source Project
4 *  Copyright (C) 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 "bta_api.h"
27#include "bd.h"
28#include "bta_hf_client_api.h"
29#include "bta_hf_client_int.h"
30#include "bta_dm_int.h"
31#include "l2c_api.h"
32#include "port_api.h"
33#include "bta_sys.h"
34#include "utl.h"
35#include "bt_utils.h"
36#include <string.h>
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_register
48**
49** Description      This function initializes values of the scb and sets up
50**                  the SDP record for the services.
51**
52**
53** Returns          void
54**
55*******************************************************************************/
56void bta_hf_client_register(tBTA_HF_CLIENT_DATA *p_data)
57{
58    tBTA_HF_CLIENT evt;
59    tBTA_UTL_COD   cod;
60
61    memset(&evt, 0, sizeof(evt));
62
63    /* initialize control block */
64    bta_hf_client_scb_init();
65
66    bta_hf_client_cb.scb.serv_sec_mask = p_data->api_register.sec_mask;
67    bta_hf_client_cb.scb.features = p_data->api_register.features;
68
69    /* initialize AT control block */
70    bta_hf_client_at_init();
71
72    /* create SDP records */
73    bta_hf_client_create_record(p_data);
74
75    /* Set the Audio service class bit */
76    cod.service = BTM_COD_SERVICE_AUDIO;
77    utl_set_device_class(&cod, BTA_UTL_SET_COD_SERVICE_CLASS);
78
79    /* start RFCOMM server */
80    bta_hf_client_start_server();
81
82    /* call app callback with register event */
83    evt.reg.status = BTA_HF_CLIENT_SUCCESS;
84    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_REGISTER_EVT, &evt);
85}
86
87/*******************************************************************************
88**
89** Function         bta_hf_client_deregister
90**
91** Description      This function removes the sdp records, closes the RFCOMM
92**                  servers, and deallocates the service control block.
93**
94**
95** Returns          void
96**
97*******************************************************************************/
98void bta_hf_client_deregister(tBTA_HF_CLIENT_DATA *p_data)
99{
100    bta_hf_client_cb.scb.deregister = TRUE;
101
102    /* remove sdp record */
103    bta_hf_client_del_record(p_data);
104
105    /* remove rfcomm server */
106    bta_hf_client_close_server();
107
108    /* disable */
109    bta_hf_client_scb_disable();
110}
111
112/*******************************************************************************
113**
114** Function         bta_hf_client_start_dereg
115**
116** Description      Start a deregister event.
117**
118**
119** Returns          void
120**
121*******************************************************************************/
122void bta_hf_client_start_dereg(tBTA_HF_CLIENT_DATA *p_data)
123{
124    bta_hf_client_cb.scb.deregister = TRUE;
125
126    /* remove sdp record */
127    bta_hf_client_del_record(p_data);
128}
129
130/*******************************************************************************
131**
132** Function         bta_hf_client_start_close
133**
134** Description      Start the process of closing SCO and RFCOMM connection.
135**
136**
137** Returns          void
138**
139*******************************************************************************/
140void bta_hf_client_start_close(tBTA_HF_CLIENT_DATA *p_data)
141{
142    /* Take the link out of sniff and set L2C idle time to 0 */
143    bta_dm_pm_active(bta_hf_client_cb.scb.peer_addr);
144    L2CA_SetIdleTimeoutByBdAddr(bta_hf_client_cb.scb.peer_addr, 0);
145
146    /* if SCO is open close SCO and wait on RFCOMM close */
147    if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_OPEN_ST)
148    {
149        bta_hf_client_cb.scb.sco_close_rfc = TRUE;
150    }
151    else
152    {
153        bta_hf_client_rfc_do_close(p_data);
154    }
155
156    /* always do SCO shutdown to handle all SCO corner cases */
157    bta_hf_client_sco_shutdown(NULL);
158}
159
160/*******************************************************************************
161**
162** Function         bta_hf_client_start_open
163**
164** Description      This starts an HF Client open.
165**
166**
167** Returns          void
168**
169*******************************************************************************/
170void bta_hf_client_start_open(tBTA_HF_CLIENT_DATA *p_data)
171{
172    BD_ADDR pending_bd_addr;
173
174    /* store parameters */
175    if (p_data)
176    {
177        bdcpy(bta_hf_client_cb.scb.peer_addr, p_data->api_open.bd_addr);
178        bta_hf_client_cb.scb.cli_sec_mask = p_data->api_open.sec_mask;
179    }
180
181    /* Check if RFCOMM has any incoming connection to avoid collision. */
182    if (PORT_IsOpening (pending_bd_addr))
183    {
184        /* Let the incoming connection goes through.                        */
185        /* Issue collision for now.                                         */
186        /* We will decide what to do when we find incoming connection later.*/
187        bta_hf_client_collision_cback (0, BTA_ID_HS, 0, bta_hf_client_cb.scb.peer_addr);
188        return;
189    }
190
191    /* close server */
192    bta_hf_client_close_server();
193
194    /* set role */
195    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_INT;
196
197    /* do service search */
198    bta_hf_client_do_disc();
199}
200
201/*******************************************************************************
202**
203** Function         bta_hf_client_cback_open
204**
205** Description      Send open callback event to application.
206**
207**
208** Returns          void
209**
210*******************************************************************************/
211static void bta_hf_client_cback_open(tBTA_HF_CLIENT_DATA *p_data, tBTA_HF_CLIENT_STATUS status)
212{
213    tBTA_HF_CLIENT evt;
214
215    memset(&evt, 0, sizeof(evt));
216
217    /* call app callback with open event */
218    evt.open.status = status;
219    if(p_data)
220    {
221        /* if p_data is provided then we need to pick the bd address from the open api structure */
222        bdcpy(evt.open.bd_addr, p_data->api_open.bd_addr);
223    }
224    else
225    {
226        bdcpy(evt.open.bd_addr, bta_hf_client_cb.scb.peer_addr);
227    }
228
229    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPEN_EVT, &evt);
230}
231
232/*******************************************************************************
233**
234** Function         bta_hf_client_rfc_open
235**
236** Description      Handle RFCOMM channel open.
237**
238**
239** Returns          void
240**
241*******************************************************************************/
242void bta_hf_client_rfc_open(tBTA_HF_CLIENT_DATA *p_data)
243{
244    UNUSED(p_data);
245
246    bta_sys_conn_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
247
248    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_SUCCESS);
249
250    /* start SLC procedure */
251    bta_hf_client_slc_seq(FALSE);
252}
253
254/*******************************************************************************
255**
256** Function         bta_hf_client_rfc_acp_open
257**
258** Description      Handle RFCOMM channel open when accepting connection.
259**
260**
261** Returns          void
262**
263*******************************************************************************/
264void bta_hf_client_rfc_acp_open(tBTA_HF_CLIENT_DATA *p_data)
265{
266    UINT16          lcid;
267    int             i;
268    BD_ADDR         dev_addr;
269    int             status;
270
271    /* set role */
272    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
273
274    APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open: serv_handle = %d rfc.port_handle = %d",
275            bta_hf_client_cb.scb.serv_handle, p_data->rfc.port_handle);
276
277    /* get bd addr of peer */
278    if (PORT_SUCCESS != (status=PORT_CheckConnection(p_data->rfc.port_handle, dev_addr, &lcid)))
279    {
280        APPL_TRACE_DEBUG ("bta_hf_client_rfc_acp_open error PORT_CheckConnection returned status %d", status);
281    }
282
283    /* Collision Handling */
284    if (bta_hf_client_cb.scb.colli_tmr_on)
285    {
286        /* stop collision timer */
287        bta_hf_client_cb.scb.colli_tmr_on = FALSE;
288        bta_sys_stop_timer (&bta_hf_client_cb.scb.colli_timer);
289
290        if (bdcmp (dev_addr, bta_hf_client_cb.scb.peer_addr) == 0)
291        {
292            /* If incoming and outgoing device are same, nothing more to do.            */
293            /* Outgoing conn will be aborted because we have successful incoming conn.  */
294        }
295        else
296        {
297            /* Resume outgoing connection. */
298            bta_hf_client_resume_open ();
299        }
300    }
301
302    bdcpy (bta_hf_client_cb.scb.peer_addr, dev_addr);
303    bta_hf_client_cb.scb.conn_handle = p_data->rfc.port_handle;
304
305    /* do service discovery to get features */
306    bta_hf_client_do_disc();
307
308    /* continue with open processing */
309    bta_hf_client_rfc_open(p_data);
310}
311
312/*******************************************************************************
313**
314** Function         bta_hf_client_rfc_fail
315**
316** Description      RFCOMM connection failed.
317**
318**
319** Returns          void
320**
321*******************************************************************************/
322void bta_hf_client_rfc_fail(tBTA_HF_CLIENT_DATA *p_data)
323{
324    UNUSED(p_data);
325
326    /* reinitialize stuff */
327    bta_hf_client_cb.scb.conn_handle = 0;
328    bta_hf_client_cb.scb.peer_features = 0;
329    bta_hf_client_cb.scb.chld_features = 0;
330    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
331    bta_hf_client_cb.scb.svc_conn = FALSE;
332    bta_hf_client_cb.scb.send_at_reply = FALSE;
333    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
334
335    bta_hf_client_at_reset();
336
337    /* reopen server */
338    bta_hf_client_start_server();
339
340    /* call open cback w. failure */
341    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_RFCOMM);
342}
343
344/*******************************************************************************
345**
346** Function         bta_hf_client_disc_fail
347**
348** Description      This function handles a discovery failure.
349**
350**
351** Returns          void
352**
353*******************************************************************************/
354void bta_hf_client_disc_fail(tBTA_HF_CLIENT_DATA *p_data)
355{
356    UNUSED(p_data);
357
358    /* reopen server */
359    bta_hf_client_start_server();
360
361    /* reinitialize stuff */
362
363    /* call open cback w. failure */
364    bta_hf_client_cback_open(NULL, BTA_HF_CLIENT_FAIL_SDP);
365}
366
367/*******************************************************************************
368**
369** Function         bta_hf_client_open_fail
370**
371** Description      open connection failed.
372**
373**
374** Returns          void
375**
376*******************************************************************************/
377void bta_hf_client_open_fail(tBTA_HF_CLIENT_DATA *p_data)
378{
379    /* call open cback w. failure */
380    bta_hf_client_cback_open(p_data, BTA_HF_CLIENT_FAIL_RESOURCES);
381}
382
383/*******************************************************************************
384**
385** Function         bta_hf_client_rfc_close
386**
387** Description      RFCOMM connection closed.
388**
389**
390** Returns          void
391**
392*******************************************************************************/
393void bta_hf_client_rfc_close(tBTA_HF_CLIENT_DATA *p_data)
394{
395    int i, num_active_conn = 0;
396    UNUSED(p_data);
397
398    /* reinitialize stuff */
399    bta_hf_client_cb.scb.peer_features = 0;
400    bta_hf_client_cb.scb.chld_features = 0;
401    bta_hf_client_cb.scb.role = BTA_HF_CLIENT_ACP;
402    bta_hf_client_cb.scb.svc_conn = FALSE;
403    bta_hf_client_cb.scb.send_at_reply = FALSE;
404    bta_hf_client_cb.scb.negotiated_codec = BTM_SCO_CODEC_CVSD;
405
406    bta_hf_client_at_reset();
407
408    bta_sys_conn_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
409
410    /* call close cback */
411    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLOSE_EVT, NULL);
412
413    /* if not deregistering reopen server */
414    if (bta_hf_client_cb.scb.deregister == FALSE)
415    {
416        /* Clear peer bd_addr so instance can be reused */
417        bdcpy(bta_hf_client_cb.scb.peer_addr, bd_addr_null);
418
419        /* start server as it might got closed on open*/
420        bta_hf_client_start_server();
421
422        bta_hf_client_cb.scb.conn_handle = 0;
423
424        /* Make sure SCO is shutdown */
425        bta_hf_client_sco_shutdown(NULL);
426
427        bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
428    }
429    /* else close port and deallocate scb */
430    else
431    {
432        bta_hf_client_close_server();
433        bta_hf_client_scb_disable();
434    }
435}
436
437/*******************************************************************************
438**
439** Function         bta_hf_client_disc_int_res
440**
441** Description      This function handles a discovery result when initiator.
442**
443**
444** Returns          void
445**
446*******************************************************************************/
447void bta_hf_client_disc_int_res(tBTA_HF_CLIENT_DATA *p_data)
448{
449    UINT16 event = BTA_HF_CLIENT_DISC_FAIL_EVT;
450
451    APPL_TRACE_DEBUG ("bta_hf_client_disc_int_res: Status: %d", p_data->disc_result.status);
452
453    /* if found service */
454    if (p_data->disc_result.status == SDP_SUCCESS ||
455        p_data->disc_result.status == SDP_DB_FULL)
456    {
457        /* get attributes */
458        if (bta_hf_client_sdp_find_attr())
459        {
460            event = BTA_HF_CLIENT_DISC_OK_EVT;
461        }
462    }
463
464    /* free discovery db */
465    bta_hf_client_free_db(p_data);
466
467    /* send ourselves sdp ok/fail event */
468    bta_hf_client_sm_execute(event, p_data);
469}
470
471/*******************************************************************************
472**
473** Function         bta_hf_client_disc_acp_res
474**
475** Description      This function handles a discovery result when acceptor.
476**
477**
478** Returns          void
479**
480*******************************************************************************/
481void bta_hf_client_disc_acp_res(tBTA_HF_CLIENT_DATA *p_data)
482{
483    /* if found service */
484    if (p_data->disc_result.status == SDP_SUCCESS ||
485        p_data->disc_result.status == SDP_DB_FULL)
486    {
487        /* get attributes */
488        bta_hf_client_sdp_find_attr();
489    }
490
491    /* free discovery db */
492    bta_hf_client_free_db(p_data);
493}
494
495/*******************************************************************************
496**
497** Function         bta_hf_client_rfc_data
498**
499** Description      Read and process data from RFCOMM.
500**
501**
502** Returns          void
503**
504*******************************************************************************/
505void bta_hf_client_rfc_data(tBTA_HF_CLIENT_DATA *p_data)
506{
507    UINT16  len;
508    char    buf[BTA_HF_CLIENT_RFC_READ_MAX];
509    UNUSED(p_data);
510
511    memset(buf, 0, sizeof(buf));
512
513    /* read data from rfcomm; if bad status, we're done */
514    while (PORT_ReadData(bta_hf_client_cb.scb.conn_handle, buf, BTA_HF_CLIENT_RFC_READ_MAX, &len) == PORT_SUCCESS)
515    {
516        /* if no data, we're done */
517        if (len == 0)
518        {
519            break;
520        }
521
522        bta_hf_client_at_parse(buf, len);
523
524        /* no more data to read, we're done */
525        if (len < BTA_HF_CLIENT_RFC_READ_MAX)
526        {
527            break;
528        }
529    }
530}
531
532/*******************************************************************************
533**
534** Function         bta_hf_client_svc_conn_open
535**
536** Description      Service level connection opened
537**
538**
539** Returns          void
540**
541*******************************************************************************/
542void bta_hf_client_svc_conn_open(tBTA_HF_CLIENT_DATA *p_data)
543{
544    tBTA_HF_CLIENT evt;
545    UNUSED(p_data);
546
547    memset(&evt, 0, sizeof(evt));
548
549    if (!bta_hf_client_cb.scb.svc_conn)
550    {
551        /* set state variable */
552        bta_hf_client_cb.scb.svc_conn = TRUE;
553
554        /* call callback */
555        evt.conn.peer_feat = bta_hf_client_cb.scb.peer_features;
556        evt.conn.chld_feat = bta_hf_client_cb.scb.chld_features;
557
558        (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CONN_EVT, &evt);
559    }
560}
561
562/*******************************************************************************
563**
564** Function         bta_hf_client_cback_ind
565**
566** Description      Send indicator callback event to application.
567**
568** Returns          void
569**
570*******************************************************************************/
571void bta_hf_client_ind(tBTA_HF_CLIENT_IND_TYPE type, UINT16 value)
572{
573    tBTA_HF_CLIENT evt;
574
575    memset(&evt, 0, sizeof(evt));
576
577    evt.ind.type = type;
578    evt.ind.value = value;
579
580    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_IND_EVT, &evt);
581}
582
583/*******************************************************************************
584**
585** Function         bta_hf_client_evt_val
586**
587** Description      Send event to application.
588**                  This is a generic helper for events with common data.
589**
590**
591** Returns          void
592**
593*******************************************************************************/
594void bta_hf_client_evt_val(tBTA_HF_CLIENT_EVT type, UINT16 value)
595{
596    tBTA_HF_CLIENT evt;
597
598    memset(&evt, 0, sizeof(evt));
599
600    evt.val.value = value;
601
602    (*bta_hf_client_cb.p_cback)(type, &evt);
603}
604
605/*******************************************************************************
606**
607** Function         bta_hf_client_operator_name
608**
609** Description      Send operator name event to application.
610**
611**
612** Returns          void
613**
614*******************************************************************************/
615void bta_hf_client_operator_name(char *name)
616{
617    tBTA_HF_CLIENT evt;
618
619    memset(&evt, 0, sizeof(evt));
620
621    strlcpy(evt.operator.name, name, BTA_HF_CLIENT_OPERATOR_NAME_LEN + 1);
622    evt.operator.name[BTA_HF_CLIENT_OPERATOR_NAME_LEN] = '\0';
623
624    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_OPERATOR_NAME_EVT, &evt);
625}
626
627
628/*******************************************************************************
629**
630** Function         bta_hf_client_clip
631**
632** Description      Send CLIP event to application.
633**
634**
635** Returns          void
636**
637*******************************************************************************/
638void bta_hf_client_clip(char *number)
639{
640    tBTA_HF_CLIENT evt;
641
642    memset(&evt, 0, sizeof(evt));
643
644    strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
645    evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
646
647    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLIP_EVT, &evt);
648}
649
650/*******************************************************************************
651**
652** Function         bta_hf_client_ccwa
653**
654** Description      Send CLIP event to application.
655**
656**
657** Returns          void
658**
659*******************************************************************************/
660void bta_hf_client_ccwa(char *number)
661{
662    tBTA_HF_CLIENT evt;
663
664    memset(&evt, 0, sizeof(evt));
665
666    strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
667    evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
668
669    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CCWA_EVT, &evt);
670}
671
672/*******************************************************************************
673**
674** Function         bta_hf_client_at_result
675**
676** Description      Send AT result event to application.
677**
678**
679** Returns          void
680**
681*******************************************************************************/
682void bta_hf_client_at_result(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT16 cme)
683{
684    tBTA_HF_CLIENT evt;
685
686    memset(&evt, 0, sizeof(evt));
687
688    evt.result.type = type;
689    evt.result.cme = cme;
690
691    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_AT_RESULT_EVT, &evt);
692}
693
694/*******************************************************************************
695**
696** Function         bta_hf_client_clcc
697**
698** Description      Send clcc event to application.
699**
700**
701** Returns          void
702**
703*******************************************************************************/
704void bta_hf_client_clcc(UINT32 idx, BOOLEAN incoming, UINT8 status, BOOLEAN mpty, char *number)
705{
706    tBTA_HF_CLIENT evt;
707
708    memset(&evt, 0, sizeof(evt));
709
710    evt.clcc.idx = idx;
711    evt.clcc.inc = incoming;
712    evt.clcc.status = status;
713    evt.clcc.mpty = mpty;
714
715    if (number)
716    {
717        evt.clcc.number_present = TRUE;
718        strlcpy(evt.clcc.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
719        evt.clcc.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
720    }
721
722    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CLCC_EVT, &evt);
723}
724
725/*******************************************************************************
726**
727** Function         bta_hf_client_cnum
728**
729** Description      Send cnum event to application.
730**
731**
732** Returns          void
733**
734*******************************************************************************/
735void bta_hf_client_cnum(char *number, UINT16 service)
736{
737    tBTA_HF_CLIENT evt;
738
739    memset(&evt, 0, sizeof(evt));
740
741    evt.cnum.service = service;
742    strlcpy(evt.cnum.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
743    evt.cnum.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
744
745    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_CNUM_EVT, &evt);
746}
747
748/*******************************************************************************
749**
750** Function         bta_hf_client_binp
751**
752** Description      Send BINP event to application.
753**
754**
755** Returns          void
756**
757*******************************************************************************/
758void bta_hf_client_binp(char *number)
759{
760    tBTA_HF_CLIENT evt;
761
762    memset(&evt, 0, sizeof(evt));
763
764    strlcpy(evt.number.number, number, BTA_HF_CLIENT_NUMBER_LEN + 1);
765    evt.number.number[BTA_HF_CLIENT_NUMBER_LEN] = '\0';
766
767    (*bta_hf_client_cb.p_cback)(BTA_HF_CLIENT_BINP_EVT, &evt);
768}
769