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