bta_av_api.c revision 794f3b5f126fffc3dd1129a710187591348bbf23
1/******************************************************************************
2 *
3 *  Copyright (C) 2011-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 advanced audio/video (AV)
22 *  subsystem of BTA, Broadcom's Bluetooth application layer for mobile
23 *  phones.
24 *
25 ******************************************************************************/
26
27#include "bt_target.h"
28#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
29
30#include "bta_api.h"
31#include "bta_sys.h"
32#include "bta_av_api.h"
33#include "bta_av_int.h"
34#include "gki.h"
35#include <string.h>
36
37/*****************************************************************************
38**  Constants
39*****************************************************************************/
40
41static const tBTA_SYS_REG bta_av_reg =
42{
43    bta_av_hdl_event,
44    BTA_AvDisable
45};
46
47/*******************************************************************************
48**
49** Function         BTA_AvEnable
50**
51** Description      Enable the advanced audio/video service. When the enable
52**                  operation is complete the callback function will be
53**                  called with a BTA_AV_ENABLE_EVT. This function must
54**                  be called before other function in the AV API are
55**                  called.
56**
57** Returns          void
58**
59*******************************************************************************/
60void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features, tBTA_AV_CBACK *p_cback)
61{
62    tBTA_AV_API_ENABLE  *p_buf;
63
64    /* register with BTA system manager */
65    bta_sys_register(BTA_ID_AV, &bta_av_reg);
66
67    if ((p_buf = (tBTA_AV_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL)
68    {
69        p_buf->hdr.event = BTA_AV_API_ENABLE_EVT;
70        p_buf->p_cback  = p_cback;
71        p_buf->features = features;
72        p_buf->sec_mask = sec_mask;
73        bta_sys_sendmsg(p_buf);
74    }
75}
76
77/*******************************************************************************
78**
79** Function         BTA_AvDisable
80**
81** Description      Disable the advanced audio/video service.
82**
83** Returns          void
84**
85*******************************************************************************/
86void BTA_AvDisable(void)
87{
88    BT_HDR  *p_buf;
89
90    bta_sys_deregister(BTA_ID_AV);
91    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
92    {
93        p_buf->event = BTA_AV_API_DISABLE_EVT;
94        bta_sys_sendmsg(p_buf);
95    }
96}
97
98/*******************************************************************************
99**
100** Function         BTA_AvRegister
101**
102** Description      Register the audio or video service to stack. When the
103**                  operation is complete the callback function will be
104**                  called with a BTA_AV_REGISTER_EVT. This function must
105**                  be called before AVDT stream is open.
106**
107**
108** Returns          void
109**
110*******************************************************************************/
111void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK  *p_data_cback)
112{
113    tBTA_AV_API_REG  *p_buf;
114
115
116    if ((p_buf = (tBTA_AV_API_REG *) GKI_getbuf(sizeof(tBTA_AV_API_REG))) != NULL)
117    {
118        p_buf->hdr.layer_specific   = chnl;
119        p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
120        if(p_service_name)
121        {
122            BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
123            p_buf->p_service_name[BTA_SERVICE_NAME_LEN-1] = 0;
124        }
125        else
126        {
127            p_buf->p_service_name[0] = 0;
128        }
129        p_buf->app_id = app_id;
130        p_buf->p_app_data_cback = p_data_cback;
131        bta_sys_sendmsg(p_buf);
132    }
133}
134
135/*******************************************************************************
136**
137** Function         BTA_AvDeregister
138**
139** Description      Deregister the audio or video service
140**
141** Returns          void
142**
143*******************************************************************************/
144void BTA_AvDeregister(tBTA_AV_HNDL hndl)
145{
146    BT_HDR  *p_buf;
147
148    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
149    {
150        p_buf->layer_specific   = hndl;
151        p_buf->event = BTA_AV_API_DEREGISTER_EVT;
152        bta_sys_sendmsg(p_buf);
153    }
154}
155
156/*******************************************************************************
157**
158** Function         BTA_AvOpen
159**
160** Description      Opens an advanced audio/video connection to a peer device.
161**                  When connection is open callback function is called
162**                  with a BTA_AV_OPEN_EVT.
163**
164** Returns          void
165**
166*******************************************************************************/
167void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask,
168                                                                             UINT16 uuid)
169{
170    tBTA_AV_API_OPEN  *p_buf;
171
172    if ((p_buf = (tBTA_AV_API_OPEN *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL)
173    {
174        p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
175        p_buf->hdr.layer_specific   = handle;
176        bdcpy(p_buf->bd_addr, bd_addr);
177        p_buf->use_rc = use_rc;
178        p_buf->sec_mask = sec_mask;
179        p_buf->switch_res = BTA_AV_RS_NONE;
180        p_buf->uuid = uuid;
181        bta_sys_sendmsg(p_buf);
182    }
183}
184
185/*******************************************************************************
186**
187** Function         BTA_AvClose
188**
189** Description      Close the current streams.
190**
191** Returns          void
192**
193*******************************************************************************/
194void BTA_AvClose(tBTA_AV_HNDL handle)
195{
196    BT_HDR  *p_buf;
197
198    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
199    {
200        p_buf->event = BTA_AV_API_CLOSE_EVT;
201        p_buf->layer_specific   = handle;
202        bta_sys_sendmsg(p_buf);
203    }
204}
205
206/*******************************************************************************
207**
208** Function         BTA_AvDisconnect
209**
210** Description      Close the connection to the address.
211**
212** Returns          void
213**
214*******************************************************************************/
215void BTA_AvDisconnect(BD_ADDR bd_addr)
216{
217    tBTA_AV_API_DISCNT  *p_buf;
218
219    if ((p_buf = (tBTA_AV_API_DISCNT *) GKI_getbuf(sizeof(tBTA_AV_API_DISCNT))) != NULL)
220    {
221        p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT;
222        bdcpy(p_buf->bd_addr, bd_addr);
223        bta_sys_sendmsg(p_buf);
224    }
225}
226
227/*******************************************************************************
228**
229** Function         BTA_AvStart
230**
231** Description      Start audio/video stream data transfer.
232**
233** Returns          void
234**
235*******************************************************************************/
236void BTA_AvStart(void)
237{
238    BT_HDR  *p_buf;
239
240    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
241    {
242        p_buf->event = BTA_AV_API_START_EVT;
243        bta_sys_sendmsg(p_buf);
244    }
245}
246
247/*******************************************************************************
248**
249** Function         BTA_AvEnable_Sink
250**
251** Description      Enable/Disable A2DP Sink..
252**
253** Returns          void
254**
255*******************************************************************************/
256void BTA_AvEnable_Sink(int enable)
257{
258    BT_HDR  *p_buf;
259
260#if (BTA_AV_SINK_INCLUDED == TRUE)
261    if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
262    {
263        p_buf->event = BTA_AV_API_SINK_ENABLE_EVT;
264        p_buf->layer_specific = enable;
265        bta_sys_sendmsg(p_buf);
266    }
267#else
268    return;
269#endif
270}
271
272/*******************************************************************************
273**
274** Function         BTA_AvStop
275**
276** Description      Stop audio/video stream data transfer.
277**                  If suspend is TRUE, this function sends AVDT suspend signal
278**                  to the connected peer(s).
279**
280** Returns          void
281**
282*******************************************************************************/
283void BTA_AvStop(BOOLEAN suspend)
284{
285    tBTA_AV_API_STOP  *p_buf;
286
287    if ((p_buf = (tBTA_AV_API_STOP *) GKI_getbuf(sizeof(tBTA_AV_API_STOP))) != NULL)
288    {
289        p_buf->hdr.event = BTA_AV_API_STOP_EVT;
290        p_buf->flush   = TRUE;
291        p_buf->suspend = suspend;
292        bta_sys_sendmsg(p_buf);
293    }
294}
295
296/*******************************************************************************
297**
298** Function         BTA_AvReconfig
299**
300** Description      Reconfigure the audio/video stream.
301**                  If suspend is TRUE, this function tries the suspend/reconfigure
302**                  procedure first.
303**                  If suspend is FALSE or when suspend/reconfigure fails,
304**                  this function closes and re-opens the AVDT connection.
305**
306** Returns          void
307**
308*******************************************************************************/
309void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
310                    UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info)
311{
312    tBTA_AV_API_RCFG  *p_buf;
313
314    if ((p_buf = (tBTA_AV_API_RCFG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_RCFG) + num_protect))) != NULL)
315    {
316        p_buf->hdr.layer_specific   = hndl;
317        p_buf->hdr.event    = BTA_AV_API_RECONFIG_EVT;
318        p_buf->num_protect  = num_protect;
319        p_buf->suspend      = suspend;
320        p_buf->sep_info_idx = sep_info_idx;
321        p_buf->p_protect_info = (UINT8 *)(p_buf + 1);
322        memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
323        memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
324        bta_sys_sendmsg(p_buf);
325    }
326}
327
328/*******************************************************************************
329**
330** Function         BTA_AvProtectReq
331**
332** Description      Send a content protection request.  This function can only
333**                  be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
334**
335** Returns          void
336**
337*******************************************************************************/
338void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len)
339{
340    tBTA_AV_API_PROTECT_REQ  *p_buf;
341
342    if ((p_buf = (tBTA_AV_API_PROTECT_REQ *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_REQ) + len))) != NULL)
343    {
344        p_buf->hdr.layer_specific   = hndl;
345        p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT;
346        p_buf->len       = len;
347        if (p_data == NULL)
348        {
349            p_buf->p_data = NULL;
350        }
351        else
352        {
353            p_buf->p_data = (UINT8 *) (p_buf + 1);
354            memcpy(p_buf->p_data, p_data, len);
355        }
356        bta_sys_sendmsg(p_buf);
357    }
358}
359
360/*******************************************************************************
361**
362** Function         BTA_AvProtectRsp
363**
364** Description      Send a content protection response.  This function must
365**                  be called if a BTA_AV_PROTECT_REQ_EVT is received.
366**                  This function can only be used if AV is enabled with
367**                  feature BTA_AV_FEAT_PROTECT.
368**
369** Returns          void
370**
371*******************************************************************************/
372void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len)
373{
374    tBTA_AV_API_PROTECT_RSP  *p_buf;
375
376    if ((p_buf = (tBTA_AV_API_PROTECT_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_RSP) + len))) != NULL)
377    {
378        p_buf->hdr.layer_specific   = hndl;
379        p_buf->hdr.event    = BTA_AV_API_PROTECT_RSP_EVT;
380        p_buf->len          = len;
381        p_buf->error_code   = error_code;
382        if (p_data == NULL)
383        {
384            p_buf->p_data = NULL;
385        }
386        else
387        {
388            p_buf->p_data = (UINT8 *) (p_buf + 1);
389            memcpy(p_buf->p_data, p_data, len);
390        }
391        bta_sys_sendmsg(p_buf);
392    }
393}
394
395/*******************************************************************************
396**
397** Function         BTA_AvRemoteCmd
398**
399** Description      Send a remote control command.  This function can only
400**                  be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
401**
402** Returns          void
403**
404*******************************************************************************/
405void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, tBTA_AV_STATE key_state)
406{
407    tBTA_AV_API_REMOTE_CMD  *p_buf;
408
409    if ((p_buf = (tBTA_AV_API_REMOTE_CMD *) GKI_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD))) != NULL)
410    {
411        p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
412        p_buf->hdr.layer_specific   = rc_handle;
413        p_buf->msg.op_id = rc_id;
414        p_buf->msg.state = key_state;
415        p_buf->msg.p_pass_data = NULL;
416        p_buf->msg.pass_len = 0;
417        p_buf->label = label;
418        bta_sys_sendmsg(p_buf);
419    }
420}
421
422/*******************************************************************************
423**
424** Function         BTA_AvVendorCmd
425**
426** Description      Send a vendor dependent remote control command.  This
427**                  function can only be used if AV is enabled with feature
428**                  BTA_AV_FEAT_VENDOR.
429**
430** Returns          void
431**
432*******************************************************************************/
433void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, UINT8 *p_data, UINT16 len)
434{
435    tBTA_AV_API_VENDOR  *p_buf;
436
437    if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL)
438    {
439        p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT;
440        p_buf->hdr.layer_specific   = rc_handle;
441        p_buf->msg.hdr.ctype = cmd_code;
442        p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
443        p_buf->msg.hdr.subunit_id = 0;
444        p_buf->msg.company_id = p_bta_av_cfg->company_id;
445        p_buf->label = label;
446        p_buf->msg.vendor_len = len;
447        if (p_data == NULL)
448        {
449            p_buf->msg.p_vendor_data = NULL;
450        }
451        else
452        {
453            p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
454            memcpy(p_buf->msg.p_vendor_data, p_data, len);
455        }
456        bta_sys_sendmsg(p_buf);
457    }
458}
459
460/*******************************************************************************
461**
462** Function         BTA_AvVendorRsp
463**
464** Description      Send a vendor dependent remote control response.
465**                  This function must be called if a BTA_AV_VENDOR_CMD_EVT
466**                  is received. This function can only be used if AV is
467**                  enabled with feature BTA_AV_FEAT_VENDOR.
468**
469** Returns          void
470**
471*******************************************************************************/
472void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, UINT8 *p_data, UINT16 len, UINT32 company_id)
473{
474    tBTA_AV_API_VENDOR  *p_buf;
475
476    if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL)
477    {
478        p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT;
479        p_buf->hdr.layer_specific   = rc_handle;
480        p_buf->msg.hdr.ctype = rsp_code;
481        p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
482        p_buf->msg.hdr.subunit_id = 0;
483        if(company_id)
484            p_buf->msg.company_id = company_id;
485        else
486            p_buf->msg.company_id = p_bta_av_cfg->company_id;
487        p_buf->label = label;
488        p_buf->msg.vendor_len = len;
489        if (p_data == NULL)
490        {
491            p_buf->msg.p_vendor_data = NULL;
492        }
493        else
494        {
495            p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
496            memcpy(p_buf->msg.p_vendor_data, p_data, len);
497        }
498        bta_sys_sendmsg(p_buf);
499    }
500}
501
502/*******************************************************************************
503**
504** Function         BTA_AvOpenRc
505**
506** Description      Open an AVRCP connection toward the device with the
507**                  specified handle
508**
509** Returns          void
510**
511*******************************************************************************/
512void BTA_AvOpenRc(tBTA_AV_HNDL handle)
513{
514    tBTA_AV_API_OPEN_RC  *p_buf;
515
516    if ((p_buf = (tBTA_AV_API_OPEN_RC *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN_RC))) != NULL)
517    {
518        p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT;
519        p_buf->hdr.layer_specific   = handle;
520        bta_sys_sendmsg(p_buf);
521    }
522}
523
524/*******************************************************************************
525**
526** Function         BTA_AvCloseRc
527**
528** Description      Close an AVRCP connection
529**
530** Returns          void
531**
532*******************************************************************************/
533void BTA_AvCloseRc(UINT8 rc_handle)
534{
535    tBTA_AV_API_CLOSE_RC  *p_buf;
536
537    if ((p_buf = (tBTA_AV_API_CLOSE_RC *) GKI_getbuf(sizeof(tBTA_AV_API_CLOSE_RC))) != NULL)
538    {
539        p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT;
540        p_buf->hdr.layer_specific   = rc_handle;
541        bta_sys_sendmsg(p_buf);
542    }
543}
544
545/*******************************************************************************
546**
547** Function         BTA_AvMetaRsp
548**
549** Description      Send a Metadata/Advanced Control response. The message contained
550**                  in p_pkt can be composed with AVRC utility functions.
551**                  This function can only be used if AV is enabled with feature
552**                  BTA_AV_FEAT_METADATA.
553**
554** Returns          void
555**
556*******************************************************************************/
557void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
558                               BT_HDR *p_pkt)
559{
560    tBTA_AV_API_META_RSP  *p_buf;
561
562    if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL)
563    {
564        p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
565        p_buf->hdr.layer_specific   = rc_handle;
566        p_buf->rsp_code = rsp_code;
567        p_buf->p_pkt = p_pkt;
568        p_buf->is_rsp = TRUE;
569        p_buf->label = label;
570
571        bta_sys_sendmsg(p_buf);
572    } else if (p_pkt) {
573        GKI_freebuf(p_pkt);
574    }
575}
576
577/*******************************************************************************
578**
579** Function         BTA_AvMetaCmd
580**
581** Description      Send a Metadata/Advanced Control command. The message contained
582**                  in p_pkt can be composed with AVRC utility functions.
583**                  This function can only be used if AV is enabled with feature
584**                  BTA_AV_FEAT_METADATA.
585**                  This message is sent only when the peer supports the TG role.
586*8                  The only command makes sense right now is the absolute volume command.
587**
588** Returns          void
589**
590*******************************************************************************/
591void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt)
592{
593    tBTA_AV_API_META_RSP  *p_buf;
594
595    if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL)
596    {
597        p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
598        p_buf->hdr.layer_specific   = rc_handle;
599        p_buf->p_pkt = p_pkt;
600        p_buf->rsp_code = cmd_code;
601        p_buf->is_rsp = FALSE;
602        p_buf->label = label;
603
604        bta_sys_sendmsg(p_buf);
605    }
606}
607
608#endif /* BTA_AV_INCLUDED */
609