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