• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
42 static 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 *******************************************************************************/
BTA_AvEnable(tBTA_SEC sec_mask,tBTA_AV_FEAT features,tBTA_AV_CBACK * p_cback)61 void 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     GKI_sched_lock();
67     bta_sys_register(BTA_ID_AV, &bta_av_reg);
68     GKI_sched_unlock();
69 
70     if ((p_buf = (tBTA_AV_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL)
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         bta_sys_sendmsg(p_buf);
77     }
78 }
79 
80 /*******************************************************************************
81 **
82 ** Function         BTA_AvDisable
83 **
84 ** Description      Disable the advanced audio/video service.
85 **
86 ** Returns          void
87 **
88 *******************************************************************************/
BTA_AvDisable(void)89 void BTA_AvDisable(void)
90 {
91     BT_HDR  *p_buf;
92 
93     bta_sys_deregister(BTA_ID_AV);
94     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
95     {
96         p_buf->event = BTA_AV_API_DISABLE_EVT;
97         bta_sys_sendmsg(p_buf);
98     }
99 }
100 
101 /*******************************************************************************
102 **
103 ** Function         BTA_AvRegister
104 **
105 ** Description      Register the audio or video service to stack. When the
106 **                  operation is complete the callback function will be
107 **                  called with a BTA_AV_REGISTER_EVT. This function must
108 **                  be called before AVDT stream is open.
109 **
110 **
111 ** Returns          void
112 **
113 *******************************************************************************/
BTA_AvRegister(tBTA_AV_CHNL chnl,const char * p_service_name,UINT8 app_id)114 void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id)
115 {
116     tBTA_AV_API_REG  *p_buf;
117 
118 
119     if ((p_buf = (tBTA_AV_API_REG *) GKI_getbuf(sizeof(tBTA_AV_API_REG))) != NULL)
120     {
121         p_buf->hdr.layer_specific   = chnl;
122         p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
123         if(p_service_name)
124         {
125             BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
126             p_buf->p_service_name[BTA_SERVICE_NAME_LEN-1] = 0;
127         }
128         else
129         {
130             p_buf->p_service_name[0] = 0;
131         }
132         p_buf->app_id = app_id;
133         bta_sys_sendmsg(p_buf);
134     }
135 }
136 
137 /*******************************************************************************
138 **
139 ** Function         BTA_AvDeregister
140 **
141 ** Description      Deregister the audio or video service
142 **
143 ** Returns          void
144 **
145 *******************************************************************************/
BTA_AvDeregister(tBTA_AV_HNDL hndl)146 void BTA_AvDeregister(tBTA_AV_HNDL hndl)
147 {
148     BT_HDR  *p_buf;
149 
150     if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
151     {
152         p_buf->layer_specific   = hndl;
153         p_buf->event = BTA_AV_API_DEREGISTER_EVT;
154         bta_sys_sendmsg(p_buf);
155     }
156 }
157 
158 /*******************************************************************************
159 **
160 ** Function         BTA_AvOpen
161 **
162 ** Description      Opens an advanced audio/video connection to a peer device.
163 **                  When connection is open callback function is called
164 **                  with a BTA_AV_OPEN_EVT.
165 **
166 ** Returns          void
167 **
168 *******************************************************************************/
BTA_AvOpen(BD_ADDR bd_addr,tBTA_AV_HNDL handle,BOOLEAN use_rc,tBTA_SEC sec_mask)169 void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask)
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         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 *******************************************************************************/
BTA_AvClose(tBTA_AV_HNDL handle)194 void 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 *******************************************************************************/
BTA_AvDisconnect(BD_ADDR bd_addr)215 void 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 *******************************************************************************/
BTA_AvStart(void)236 void 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_AvStop
250 **
251 ** Description      Stop audio/video stream data transfer.
252 **                  If suspend is TRUE, this function sends AVDT suspend signal
253 **                  to the connected peer(s).
254 **
255 ** Returns          void
256 **
257 *******************************************************************************/
BTA_AvStop(BOOLEAN suspend)258 void BTA_AvStop(BOOLEAN suspend)
259 {
260     tBTA_AV_API_STOP  *p_buf;
261 
262     if ((p_buf = (tBTA_AV_API_STOP *) GKI_getbuf(sizeof(tBTA_AV_API_STOP))) != NULL)
263     {
264         p_buf->hdr.event = BTA_AV_API_STOP_EVT;
265         p_buf->flush   = TRUE;
266         p_buf->suspend = suspend;
267         bta_sys_sendmsg(p_buf);
268     }
269 }
270 
271 /*******************************************************************************
272 **
273 ** Function         BTA_AvReconfig
274 **
275 ** Description      Reconfigure the audio/video stream.
276 **                  If suspend is TRUE, this function tries the suspend/reconfigure
277 **                  procedure first.
278 **                  If suspend is FALSE or when suspend/reconfigure fails,
279 **                  this function closes and re-opens the AVDT connection.
280 **
281 ** Returns          void
282 **
283 *******************************************************************************/
BTA_AvReconfig(tBTA_AV_HNDL hndl,BOOLEAN suspend,UINT8 sep_info_idx,UINT8 * p_codec_info,UINT8 num_protect,UINT8 * p_protect_info)284 void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
285                     UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info)
286 {
287     tBTA_AV_API_RCFG  *p_buf;
288 
289     if ((p_buf = (tBTA_AV_API_RCFG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_RCFG) + num_protect))) != NULL)
290     {
291         p_buf->hdr.layer_specific   = hndl;
292         p_buf->hdr.event    = BTA_AV_API_RECONFIG_EVT;
293         p_buf->num_protect  = num_protect;
294         p_buf->suspend      = suspend;
295         p_buf->sep_info_idx = sep_info_idx;
296         p_buf->p_protect_info = (UINT8 *)(p_buf + 1);
297         memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
298         memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
299         bta_sys_sendmsg(p_buf);
300     }
301 }
302 
303 /*******************************************************************************
304 **
305 ** Function         BTA_AvProtectReq
306 **
307 ** Description      Send a content protection request.  This function can only
308 **                  be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
309 **
310 ** Returns          void
311 **
312 *******************************************************************************/
BTA_AvProtectReq(tBTA_AV_HNDL hndl,UINT8 * p_data,UINT16 len)313 void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len)
314 {
315     tBTA_AV_API_PROTECT_REQ  *p_buf;
316 
317     if ((p_buf = (tBTA_AV_API_PROTECT_REQ *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_REQ) + len))) != NULL)
318     {
319         p_buf->hdr.layer_specific   = hndl;
320         p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT;
321         p_buf->len       = len;
322         if (p_data == NULL)
323         {
324             p_buf->p_data = NULL;
325         }
326         else
327         {
328             p_buf->p_data = (UINT8 *) (p_buf + 1);
329             memcpy(p_buf->p_data, p_data, len);
330         }
331         bta_sys_sendmsg(p_buf);
332     }
333 }
334 
335 /*******************************************************************************
336 **
337 ** Function         BTA_AvProtectRsp
338 **
339 ** Description      Send a content protection response.  This function must
340 **                  be called if a BTA_AV_PROTECT_REQ_EVT is received.
341 **                  This function can only be used if AV is enabled with
342 **                  feature BTA_AV_FEAT_PROTECT.
343 **
344 ** Returns          void
345 **
346 *******************************************************************************/
BTA_AvProtectRsp(tBTA_AV_HNDL hndl,UINT8 error_code,UINT8 * p_data,UINT16 len)347 void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len)
348 {
349     tBTA_AV_API_PROTECT_RSP  *p_buf;
350 
351     if ((p_buf = (tBTA_AV_API_PROTECT_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_RSP) + len))) != NULL)
352     {
353         p_buf->hdr.layer_specific   = hndl;
354         p_buf->hdr.event    = BTA_AV_API_PROTECT_RSP_EVT;
355         p_buf->len          = len;
356         p_buf->error_code   = error_code;
357         if (p_data == NULL)
358         {
359             p_buf->p_data = NULL;
360         }
361         else
362         {
363             p_buf->p_data = (UINT8 *) (p_buf + 1);
364             memcpy(p_buf->p_data, p_data, len);
365         }
366         bta_sys_sendmsg(p_buf);
367     }
368 }
369 
370 /*******************************************************************************
371 **
372 ** Function         BTA_AvRemoteCmd
373 **
374 ** Description      Send a remote control command.  This function can only
375 **                  be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
376 **
377 ** Returns          void
378 **
379 *******************************************************************************/
BTA_AvRemoteCmd(UINT8 rc_handle,UINT8 label,tBTA_AV_RC rc_id,tBTA_AV_STATE key_state)380 void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, tBTA_AV_STATE key_state)
381 {
382     tBTA_AV_API_REMOTE_CMD  *p_buf;
383 
384     if ((p_buf = (tBTA_AV_API_REMOTE_CMD *) GKI_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD))) != NULL)
385     {
386         p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
387         p_buf->hdr.layer_specific   = rc_handle;
388         p_buf->msg.op_id = rc_id;
389         p_buf->msg.state = key_state;
390         p_buf->msg.p_pass_data = NULL;
391         p_buf->msg.pass_len = 0;
392         p_buf->label = label;
393         bta_sys_sendmsg(p_buf);
394     }
395 }
396 
397 /*******************************************************************************
398 **
399 ** Function         BTA_AvVendorCmd
400 **
401 ** Description      Send a vendor dependent remote control command.  This
402 **                  function can only be used if AV is enabled with feature
403 **                  BTA_AV_FEAT_VENDOR.
404 **
405 ** Returns          void
406 **
407 *******************************************************************************/
BTA_AvVendorCmd(UINT8 rc_handle,UINT8 label,tBTA_AV_CODE cmd_code,UINT8 * p_data,UINT16 len)408 void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, UINT8 *p_data, UINT16 len)
409 {
410     tBTA_AV_API_VENDOR  *p_buf;
411 
412     if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL)
413     {
414         p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT;
415         p_buf->hdr.layer_specific   = rc_handle;
416         p_buf->msg.hdr.ctype = cmd_code;
417         p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
418         p_buf->msg.hdr.subunit_id = 0;
419         p_buf->msg.company_id = p_bta_av_cfg->company_id;
420         p_buf->label = label;
421         p_buf->msg.vendor_len = len;
422         if (p_data == NULL)
423         {
424             p_buf->msg.p_vendor_data = NULL;
425         }
426         else
427         {
428             p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
429             memcpy(p_buf->msg.p_vendor_data, p_data, len);
430         }
431         bta_sys_sendmsg(p_buf);
432     }
433 }
434 
435 /*******************************************************************************
436 **
437 ** Function         BTA_AvVendorRsp
438 **
439 ** Description      Send a vendor dependent remote control response.
440 **                  This function must be called if a BTA_AV_VENDOR_CMD_EVT
441 **                  is received. This function can only be used if AV is
442 **                  enabled with feature BTA_AV_FEAT_VENDOR.
443 **
444 ** Returns          void
445 **
446 *******************************************************************************/
BTA_AvVendorRsp(UINT8 rc_handle,UINT8 label,tBTA_AV_CODE rsp_code,UINT8 * p_data,UINT16 len,UINT32 company_id)447 void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, UINT8 *p_data, UINT16 len, UINT32 company_id)
448 {
449     tBTA_AV_API_VENDOR  *p_buf;
450 
451     if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL)
452     {
453         p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT;
454         p_buf->hdr.layer_specific   = rc_handle;
455         p_buf->msg.hdr.ctype = rsp_code;
456         p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
457         p_buf->msg.hdr.subunit_id = 0;
458         if(company_id)
459             p_buf->msg.company_id = company_id;
460         else
461             p_buf->msg.company_id = p_bta_av_cfg->company_id;
462         p_buf->label = label;
463         p_buf->msg.vendor_len = len;
464         if (p_data == NULL)
465         {
466             p_buf->msg.p_vendor_data = NULL;
467         }
468         else
469         {
470             p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
471             memcpy(p_buf->msg.p_vendor_data, p_data, len);
472         }
473         bta_sys_sendmsg(p_buf);
474     }
475 }
476 
477 /*******************************************************************************
478 **
479 ** Function         BTA_AvOpenRc
480 **
481 ** Description      Open an AVRCP connection toward the device with the
482 **                  specified handle
483 **
484 ** Returns          void
485 **
486 *******************************************************************************/
BTA_AvOpenRc(tBTA_AV_HNDL handle)487 void BTA_AvOpenRc(tBTA_AV_HNDL handle)
488 {
489     tBTA_AV_API_OPEN_RC  *p_buf;
490 
491     if ((p_buf = (tBTA_AV_API_OPEN_RC *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN_RC))) != NULL)
492     {
493         p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT;
494         p_buf->hdr.layer_specific   = handle;
495         bta_sys_sendmsg(p_buf);
496     }
497 }
498 
499 /*******************************************************************************
500 **
501 ** Function         BTA_AvCloseRc
502 **
503 ** Description      Close an AVRCP connection
504 **
505 ** Returns          void
506 **
507 *******************************************************************************/
BTA_AvCloseRc(UINT8 rc_handle)508 void BTA_AvCloseRc(UINT8 rc_handle)
509 {
510     tBTA_AV_API_CLOSE_RC  *p_buf;
511 
512     if ((p_buf = (tBTA_AV_API_CLOSE_RC *) GKI_getbuf(sizeof(tBTA_AV_API_CLOSE_RC))) != NULL)
513     {
514         p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT;
515         p_buf->hdr.layer_specific   = rc_handle;
516         bta_sys_sendmsg(p_buf);
517     }
518 }
519 
520 /*******************************************************************************
521 **
522 ** Function         BTA_AvMetaRsp
523 **
524 ** Description      Send a Metadata/Advanced Control response. The message contained
525 **                  in p_pkt can be composed with AVRC utility functions.
526 **                  This function can only be used if AV is enabled with feature
527 **                  BTA_AV_FEAT_METADATA.
528 **
529 ** Returns          void
530 **
531 *******************************************************************************/
BTA_AvMetaRsp(UINT8 rc_handle,UINT8 label,tBTA_AV_CODE rsp_code,BT_HDR * p_pkt)532 void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
533                                BT_HDR *p_pkt)
534 {
535     tBTA_AV_API_META_RSP  *p_buf;
536 
537     if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL)
538     {
539         p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
540         p_buf->hdr.layer_specific   = rc_handle;
541         p_buf->rsp_code = rsp_code;
542         p_buf->p_pkt = p_pkt;
543         p_buf->is_rsp = TRUE;
544         p_buf->label = label;
545 
546         bta_sys_sendmsg(p_buf);
547     }
548 }
549 
550 /*******************************************************************************
551 **
552 ** Function         BTA_AvMetaCmd
553 **
554 ** Description      Send a Metadata/Advanced Control command. The message contained
555 **                  in p_pkt can be composed with AVRC utility functions.
556 **                  This function can only be used if AV is enabled with feature
557 **                  BTA_AV_FEAT_METADATA.
558 **                  This message is sent only when the peer supports the TG role.
559 *8                  The only command makes sense right now is the absolute volume command.
560 **
561 ** Returns          void
562 **
563 *******************************************************************************/
BTA_AvMetaCmd(UINT8 rc_handle,UINT8 label,tBTA_AV_CMD cmd_code,BT_HDR * p_pkt)564 void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt)
565 {
566     tBTA_AV_API_META_RSP  *p_buf;
567 
568     if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL)
569     {
570         p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
571         p_buf->hdr.layer_specific   = rc_handle;
572         p_buf->p_pkt = p_pkt;
573         p_buf->rsp_code = cmd_code;
574         p_buf->is_rsp = FALSE;
575         p_buf->label = label;
576 
577         bta_sys_sendmsg(p_buf);
578     }
579 }
580 
581 #endif /* BTA_AV_INCLUDED */
582