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