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 is the implementation of the API for the audio gateway (AG)
22 *  subsystem of BTA, Broadcom's Bluetooth application layer for mobile
23 *  phones.
24 *
25 ******************************************************************************/
26
27#include "bta_api.h"
28#include "bta_sys.h"
29#include "bta_ag_api.h"
30#include "bta_ag_int.h"
31#include "gki.h"
32#include <string.h>
33
34/*****************************************************************************
35**  Constants
36*****************************************************************************/
37
38static const tBTA_SYS_REG bta_ag_reg =
39{
40    bta_ag_hdl_event,
41    BTA_AgDisable
42};
43
44/*******************************************************************************
45**
46** Function         BTA_AgEnable
47**
48** Description      Enable the audio gateway service. When the enable
49**                  operation is complete the callback function will be
50**                  called with a BTA_AG_ENABLE_EVT. This function must
51**                  be called before other function in the AG API are
52**                  called.
53**
54** Returns          BTA_SUCCESS if OK, BTA_FAILURE otherwise.
55**
56*******************************************************************************/
57tBTA_STATUS BTA_AgEnable(tBTA_AG_PARSE_MODE parse_mode, tBTA_AG_CBACK *p_cback)
58{
59    tBTA_AG_API_ENABLE  *p_buf;
60    UINT8       idx;
61
62    /* Error if AG is already enabled, or AG is in the middle of disabling. */
63    for (idx = 0; idx < BTA_AG_NUM_SCB; idx++)
64    {
65        if (bta_ag_cb.scb[idx].in_use)
66        {
67            APPL_TRACE_ERROR ("BTA_AgEnable: FAILED, AG already enabled.");
68            return BTA_FAILURE;
69        }
70    }
71
72    /* register with BTA system manager */
73    bta_sys_register(BTA_ID_AG, &bta_ag_reg);
74
75    if ((p_buf = (tBTA_AG_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AG_API_ENABLE))) != NULL)
76    {
77        p_buf->hdr.event = BTA_AG_API_ENABLE_EVT;
78        p_buf->parse_mode = parse_mode;
79        p_buf->p_cback = p_cback;
80        bta_sys_sendmsg(p_buf);
81    }
82
83    return BTA_SUCCESS;
84
85}
86
87/*******************************************************************************
88**
89** Function         BTA_AgDisable
90**
91** Description      Disable the audio gateway service
92**
93**
94** Returns          void
95**
96*******************************************************************************/
97void BTA_AgDisable(void)
98{
99    BT_HDR  *p_buf;
100
101    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
102    {
103        p_buf->event = BTA_AG_API_DISABLE_EVT;
104        bta_sys_sendmsg(p_buf);
105    }
106}
107
108/*******************************************************************************
109**
110** Function         BTA_AgRegister
111**
112** Description      Register an Audio Gateway service.
113**
114**
115** Returns          void
116**
117*******************************************************************************/
118void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_SEC sec_mask,tBTA_AG_FEAT features,
119                  char * p_service_names[], UINT8 app_id)
120{
121    tBTA_AG_API_REGISTER    *p_buf;
122    int                     i;
123
124    if ((p_buf = (tBTA_AG_API_REGISTER *) GKI_getbuf(sizeof(tBTA_AG_API_REGISTER))) != NULL)
125    {
126        p_buf->hdr.event = BTA_AG_API_REGISTER_EVT;
127        p_buf->features = features;
128        p_buf->sec_mask = sec_mask;
129        p_buf->services = services;
130        p_buf->app_id = app_id;
131        for (i = 0; i < BTA_AG_NUM_IDX; i++)
132        {
133            if(p_service_names[i])
134            {
135                BCM_STRNCPY_S(p_buf->p_name[i], BTA_SERVICE_NAME_LEN+1, p_service_names[i], BTA_SERVICE_NAME_LEN);
136                p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = 0;
137            }
138            else
139            {
140                p_buf->p_name[i][0] = 0;
141            }
142        }
143        bta_sys_sendmsg(p_buf);
144    }
145}
146
147/*******************************************************************************
148**
149** Function         BTA_AgDeregister
150**
151** Description      Deregister an audio gateway service.
152**
153**
154** Returns          void
155**
156*******************************************************************************/
157void BTA_AgDeregister(UINT16 handle)
158{
159    BT_HDR  *p_buf;
160
161    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
162    {
163        p_buf->event = BTA_AG_API_DEREGISTER_EVT;
164        p_buf->layer_specific = handle;
165        bta_sys_sendmsg(p_buf);
166    }
167}
168
169/*******************************************************************************
170**
171** Function         BTA_AgOpen
172**
173** Description      Opens a connection to a headset or hands-free device.
174**                  When connection is open callback function is called
175**                  with a BTA_AG_OPEN_EVT. Only the data connection is
176**                  opened. The audio connection is not opened.
177**
178**
179** Returns          void
180**
181*******************************************************************************/
182void BTA_AgOpen(UINT16 handle, BD_ADDR bd_addr, tBTA_SEC sec_mask, tBTA_SERVICE_MASK services)
183{
184    tBTA_AG_API_OPEN  *p_buf;
185
186    if ((p_buf = (tBTA_AG_API_OPEN *) GKI_getbuf(sizeof(tBTA_AG_API_OPEN))) != NULL)
187    {
188        p_buf->hdr.event = BTA_AG_API_OPEN_EVT;
189        p_buf->hdr.layer_specific = handle;
190        bdcpy(p_buf->bd_addr, bd_addr);
191        p_buf->services = services;
192        p_buf->sec_mask = sec_mask;
193        bta_sys_sendmsg(p_buf);
194    }
195}
196
197/*******************************************************************************
198**
199** Function         BTA_AgClose
200**
201** Description      Close the current connection to a headset or a handsfree
202**                  Any current audio connection will also be closed.
203**
204**
205** Returns          void
206**
207*******************************************************************************/
208void BTA_AgClose(UINT16 handle)
209{
210    BT_HDR  *p_buf;
211
212    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
213    {
214        p_buf->event = BTA_AG_API_CLOSE_EVT;
215        p_buf->layer_specific = handle;
216        bta_sys_sendmsg(p_buf);
217    }
218}
219
220/*******************************************************************************
221**
222** Function         BTA_AgAudioOpen
223**
224** Description      Opens an audio connection to the currently connected
225**                  headset or hnadsfree.
226**
227**
228** Returns          void
229**
230*******************************************************************************/
231void BTA_AgAudioOpen(UINT16 handle)
232{
233    BT_HDR  *p_buf;
234
235    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
236    {
237        p_buf->event = BTA_AG_API_AUDIO_OPEN_EVT;
238        p_buf->layer_specific = handle;
239        bta_sys_sendmsg(p_buf);
240    }
241}
242
243/*******************************************************************************
244**
245** Function         BTA_AgAudioClose
246**
247** Description      Close the currently active audio connection to a headset
248**                  or hnadsfree. The data connection remains open
249**
250**
251** Returns          void
252**
253*******************************************************************************/
254void BTA_AgAudioClose(UINT16 handle)
255{
256    BT_HDR  *p_buf;
257
258    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
259    {
260        p_buf->event = BTA_AG_API_AUDIO_CLOSE_EVT;
261        p_buf->layer_specific = handle;
262        bta_sys_sendmsg(p_buf);
263    }
264}
265
266
267/*******************************************************************************
268**
269** Function         BTA_AgResult
270**
271** Description      Send an AT result code to a headset or hands-free device.
272**                  This function is only used when the AG parse mode is set
273**                  to BTA_AG_PARSE.
274**
275**
276** Returns          void
277**
278*******************************************************************************/
279void BTA_AgResult(UINT16 handle, tBTA_AG_RES result, tBTA_AG_RES_DATA *p_data)
280{
281    tBTA_AG_API_RESULT  *p_buf;
282
283    if ((p_buf = (tBTA_AG_API_RESULT *) GKI_getbuf(sizeof(tBTA_AG_API_RESULT))) != NULL)
284    {
285        p_buf->hdr.event = BTA_AG_API_RESULT_EVT;
286        p_buf->hdr.layer_specific = handle;
287        p_buf->result = result;
288        if(p_data)
289        {
290            memcpy(&p_buf->data, p_data, sizeof(p_buf->data));
291        }
292        bta_sys_sendmsg(p_buf);
293    }
294}
295
296/*******************************************************************************
297**
298** Function         BTA_AgSetCodec
299**
300** Description      Specify the codec type to be used for the subsequent
301**                  audio connection.
302**
303**
304**
305** Returns          void
306**
307*******************************************************************************/
308void BTA_AgSetCodec(UINT16 handle, tBTA_AG_PEER_CODEC codec)
309{
310    tBTA_AG_API_SETCODEC    *p_buf;
311
312    if ((p_buf = (tBTA_AG_API_SETCODEC *) GKI_getbuf(sizeof(tBTA_AG_API_SETCODEC))) != NULL)
313    {
314        p_buf->hdr.event = BTA_AG_API_SETCODEC_EVT;
315        p_buf->hdr.layer_specific = handle;
316        p_buf->codec = codec;
317        bta_sys_sendmsg(p_buf);
318    }
319}
320
321