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