1 /******************************************************************************
2 *
3 * Copyright (C) 2004-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 file contains action functions for advanced audio/video main state
22 * machine.
23 *
24 ******************************************************************************/
25
26 #include "common/bt_target.h"
27 #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
28
29 #include <string.h>
30 #include "bta/bta_av_api.h"
31 #include "bta_av_int.h"
32 #include "stack/avdt_api.h"
33 #include "bta/utl.h"
34 #include "stack/l2c_api.h"
35 #include "osi/allocator.h"
36 #include "osi/list.h"
37 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
38 #include "bta/bta_ar_api.h"
39 #endif
40
41 #define LOG_TAG "bt_bta_av"
42 // #include "osi/include/log.h"
43 #include "common/bt_trace.h"
44
45 /*****************************************************************************
46 ** Constants
47 *****************************************************************************/
48 /* the timer in milliseconds to wait for open req after setconfig for incoming connections */
49 #ifndef BTA_AV_SIG_TIME_VAL
50 #define BTA_AV_SIG_TIME_VAL 8000
51 #endif
52
53 /* In millisec to wait for signalling from SNK when it is initiated from SNK. */
54 /* If not, we will start signalling from SRC. */
55 #ifndef BTA_AV_ACP_SIG_TIME_VAL
56 #define BTA_AV_ACP_SIG_TIME_VAL 2000
57 #endif
58
59 static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle);
60
61 /*******************************************************************************
62 **
63 ** Function bta_av_get_rcb_by_shdl
64 **
65 ** Description find the RCB associated with the given SCB handle.
66 **
67 ** Returns tBTA_AV_RCB
68 **
69 *******************************************************************************/
bta_av_get_rcb_by_shdl(UINT8 shdl)70 tBTA_AV_RCB *bta_av_get_rcb_by_shdl(UINT8 shdl)
71 {
72 tBTA_AV_RCB *p_rcb = NULL;
73 int i;
74
75 for (i = 0; i < BTA_AV_NUM_RCB; i++) {
76 if (bta_av_cb.rcb[i].shdl == shdl && bta_av_cb.rcb[i].handle != BTA_AV_RC_HANDLE_NONE) {
77 p_rcb = &bta_av_cb.rcb[i];
78 break;
79 }
80 }
81 return p_rcb;
82 }
83 #define BTA_AV_STS_NO_RSP 0xFF /* a number not used by tAVRC_STS */
84
85 /*******************************************************************************
86 **
87 ** Function bta_av_del_rc
88 **
89 ** Description delete the given AVRC handle.
90 **
91 ** Returns void
92 **
93 *******************************************************************************/
bta_av_del_rc(tBTA_AV_RCB * p_rcb)94 void bta_av_del_rc(tBTA_AV_RCB *p_rcb)
95 {
96 tBTA_AV_SCB *p_scb;
97 UINT8 rc_handle; /* connected AVRCP handle */
98
99 p_scb = NULL;
100 if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
101 if (p_rcb->shdl) {
102 /* Validate array index*/
103 if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
104 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
105 }
106 if (p_scb) {
107 APPL_TRACE_DEBUG("bta_av_del_rc shdl:%d, srch:%d rc_handle:%d", p_rcb->shdl,
108 p_scb->rc_handle, p_rcb->handle);
109 if (p_scb->rc_handle == p_rcb->handle) {
110 p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
111 }
112 /* just in case the RC timer is active
113 if(bta_av_cb.features & BTA_AV_FEAT_RCCT && p_scb->chnl == BTA_AV_CHNL_AUDIO) */
114 bta_sys_stop_timer(&p_scb->timer);
115 }
116 }
117
118 APPL_TRACE_EVENT("bta_av_del_rc handle: %d status=0x%x, rc_acp_handle:%d, idx:%d",
119 p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, bta_av_cb.rc_acp_idx);
120 rc_handle = p_rcb->handle;
121 if (!(p_rcb->status & BTA_AV_RC_CONN_MASK) ||
122 ((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) ) {
123 p_rcb->status = 0;
124 p_rcb->handle = BTA_AV_RC_HANDLE_NONE;
125 p_rcb->shdl = 0;
126 p_rcb->lidx = 0;
127 }
128 /* else ACP && connected. do not clear the handle yet */
129 AVRC_Close(rc_handle);
130 if (rc_handle == bta_av_cb.rc_acp_handle) {
131 bta_av_cb.rc_acp_handle = BTA_AV_RC_HANDLE_NONE;
132 }
133 APPL_TRACE_EVENT("end del_rc handle: %d status=0x%x, rc_acp_handle:%d, lidx:%d",
134 p_rcb->handle, p_rcb->status, bta_av_cb.rc_acp_handle, p_rcb->lidx);
135 }
136 }
137
138
139 /*******************************************************************************
140 **
141 ** Function bta_av_close_all_rc
142 **
143 ** Description close the all AVRC handle.
144 **
145 ** Returns void
146 **
147 *******************************************************************************/
bta_av_close_all_rc(tBTA_AV_CB * p_cb)148 static void bta_av_close_all_rc(tBTA_AV_CB *p_cb)
149 {
150 int i;
151
152 for (i = 0; i < BTA_AV_NUM_RCB; i++) {
153 if ((p_cb->disabling == TRUE) || (bta_av_cb.rcb[i].shdl != 0)) {
154 bta_av_del_rc(&bta_av_cb.rcb[i]);
155 }
156 }
157 }
158
159 /*******************************************************************************
160 **
161 ** Function bta_av_del_sdp_rec
162 **
163 ** Description delete the given SDP record handle.
164 **
165 ** Returns void
166 **
167 *******************************************************************************/
bta_av_del_sdp_rec(UINT32 * p_sdp_handle)168 static void bta_av_del_sdp_rec(UINT32 *p_sdp_handle)
169 {
170 if (*p_sdp_handle != 0) {
171 SDP_DeleteRecord(*p_sdp_handle);
172 *p_sdp_handle = 0;
173 }
174 }
175
176 /*******************************************************************************
177 **
178 ** Function bta_av_avrc_sdp_cback
179 **
180 ** Description AVRCP service discovery callback.
181 **
182 ** Returns void
183 **
184 *******************************************************************************/
bta_av_avrc_sdp_cback(UINT16 status)185 static void bta_av_avrc_sdp_cback(UINT16 status)
186 {
187 BT_HDR *p_msg;
188 UNUSED(status);
189
190 if ((p_msg = (BT_HDR *) osi_malloc(sizeof(BT_HDR))) != NULL) {
191 p_msg->event = BTA_AV_SDP_AVRC_DISC_EVT;
192 bta_sys_sendmsg(p_msg);
193 }
194 }
195
196 /*******************************************************************************
197 **
198 ** Function bta_av_rc_ctrl_cback
199 **
200 ** Description AVRCP control callback.
201 **
202 ** Returns void
203 **
204 *******************************************************************************/
bta_av_rc_ctrl_cback(UINT8 handle,UINT8 event,UINT16 result,BD_ADDR peer_addr)205 static void bta_av_rc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result, BD_ADDR peer_addr)
206 {
207 tBTA_AV_RC_CONN_CHG *p_msg;
208 UINT16 msg_event = 0;
209 UNUSED(result);
210
211 APPL_TRACE_EVENT("%s handle: %d event: 0x%x",__func__, handle, event);
212
213 if (event == AVRC_OPEN_IND_EVT) {
214 /* save handle of opened connection
215 bta_av_cb.rc_handle = handle;*/
216
217 msg_event = BTA_AV_AVRC_OPEN_EVT;
218 } else if (event == AVRC_CLOSE_IND_EVT) {
219 msg_event = BTA_AV_AVRC_CLOSE_EVT;
220 }
221
222 if (msg_event) {
223 if ((p_msg = (tBTA_AV_RC_CONN_CHG *) osi_malloc(sizeof(tBTA_AV_RC_CONN_CHG))) != NULL) {
224 p_msg->hdr.event = msg_event;
225 p_msg->handle = handle;
226 if (peer_addr) {
227 bdcpy(p_msg->peer_addr, peer_addr);
228 }
229 bta_sys_sendmsg(p_msg);
230 }
231 }
232 }
233
234 /*******************************************************************************
235 **
236 ** Function bta_av_rc_msg_cback
237 **
238 ** Description AVRCP message callback.
239 **
240 ** Returns void
241 **
242 *******************************************************************************/
bta_av_rc_msg_cback(UINT8 handle,UINT8 label,UINT8 opcode,tAVRC_MSG * p_msg)243 static void bta_av_rc_msg_cback(UINT8 handle, UINT8 label, UINT8 opcode, tAVRC_MSG *p_msg)
244 {
245 UINT8 *p_data_src = NULL;
246 UINT16 data_len = 0;
247
248 APPL_TRACE_DEBUG("%s handle: %u opcode=0x%x", __func__, handle, opcode);
249
250 /* Determine the size of the buffer we need */
251 if (opcode == AVRC_OP_VENDOR && p_msg->vendor.p_vendor_data != NULL) {
252 p_data_src = p_msg->vendor.p_vendor_data;
253 data_len = (UINT16) p_msg->vendor.vendor_len;
254 } else if (opcode == AVRC_OP_PASS_THRU && p_msg->pass.p_pass_data != NULL) {
255 p_data_src = p_msg->pass.p_pass_data;
256 data_len = (UINT16) p_msg->pass.pass_len;
257 }
258
259 /* Create a copy of the message */
260 tBTA_AV_RC_MSG *p_buf =
261 (tBTA_AV_RC_MSG *)osi_malloc((UINT16)(sizeof(tBTA_AV_RC_MSG) + data_len));
262 if (p_buf != NULL) {
263 p_buf->hdr.event = BTA_AV_AVRC_MSG_EVT;
264 p_buf->handle = handle;
265 p_buf->label = label;
266 p_buf->opcode = opcode;
267 memcpy(&p_buf->msg, p_msg, sizeof(tAVRC_MSG));
268 /* Copy the data payload, and set the pointer to it */
269 if (p_data_src != NULL) {
270 UINT8 *p_data_dst = (UINT8 *)(p_buf + 1);
271 memcpy(p_data_dst, p_data_src, data_len);
272 if (opcode == AVRC_OP_VENDOR) {
273 p_buf->msg.vendor.p_vendor_data = p_data_dst;
274 } else if (opcode == AVRC_OP_PASS_THRU) {
275 p_buf->msg.pass.p_pass_data = p_data_dst;
276 }
277 }
278 bta_sys_sendmsg(p_buf);
279 }
280 }
281
282 /*******************************************************************************
283 **
284 ** Function bta_av_rc_create
285 **
286 ** Description alloc RCB and call AVRC_Open
287 **
288 ** Returns the created rc handle
289 **
290 *******************************************************************************/
bta_av_rc_create(tBTA_AV_CB * p_cb,UINT8 role,UINT8 shdl,UINT8 lidx)291 UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx)
292 {
293 tAVRC_CONN_CB ccb;
294 BD_ADDR_PTR bda = (BD_ADDR_PTR)bd_addr_any;
295 UINT8 status = BTA_AV_RC_ROLE_ACP;
296 tBTA_AV_SCB *p_scb = p_cb->p_scb[shdl - 1];
297 int i;
298 UINT8 rc_handle;
299 tBTA_AV_RCB *p_rcb;
300
301 if (role == AVCT_INT) {
302 bda = p_scb->peer_addr;
303 status = BTA_AV_RC_ROLE_INT;
304 } else {
305 if ((p_rcb = bta_av_get_rcb_by_shdl(shdl)) != NULL ) {
306 APPL_TRACE_ERROR("bta_av_rc_create ACP handle exist for shdl:%d", shdl);
307 return p_rcb->handle;
308 }
309 }
310
311 ccb.p_ctrl_cback = bta_av_rc_ctrl_cback;
312 ccb.p_msg_cback = bta_av_rc_msg_cback;
313 ccb.company_id = p_bta_av_cfg->company_id;
314 ccb.conn = role;
315 /* note: BTA_AV_FEAT_RCTG = AVRC_CT_TARGET, BTA_AV_FEAT_RCCT = AVRC_CT_CONTROL */
316 ccb.control = p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_RCCT | AVRC_CT_PASSIVE);
317
318
319 if (AVRC_Open(&rc_handle, &ccb, bda) != AVRC_SUCCESS) {
320 return BTA_AV_RC_HANDLE_NONE;
321 }
322
323 i = rc_handle;
324 p_rcb = &p_cb->rcb[i];
325
326 if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
327 APPL_TRACE_ERROR("bta_av_rc_create found duplicated handle:%d", rc_handle);
328 }
329
330 p_rcb->handle = rc_handle;
331 p_rcb->status = status;
332 p_rcb->shdl = shdl;
333 p_rcb->lidx = lidx;
334 p_rcb->peer_features = 0;
335 p_rcb->peer_ct_features = 0;
336 p_rcb->peer_tg_features = 0;
337 if (lidx == (BTA_AV_NUM_LINKS + 1)) {
338 /* this LIDX is reserved for the AVRCP ACP connection */
339 p_cb->rc_acp_handle = p_rcb->handle;
340 p_cb->rc_acp_idx = (i + 1);
341 APPL_TRACE_DEBUG("rc_acp_handle:%d idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
342 }
343 APPL_TRACE_DEBUG("create %d, role: %d, shdl:%d, rc_handle:%d, lidx:%d, status:0x%x",
344 i, role, shdl, p_rcb->handle, lidx, p_rcb->status);
345
346 return rc_handle;
347 }
348
349 /*******************************************************************************
350 **
351 ** Function bta_av_valid_group_navi_msg
352 **
353 ** Description Check if it is Group Navigation Msg for Metadata
354 **
355 ** Returns BTA_AV_RSP_ACCEPT or BTA_AV_RSP_NOT_IMPL.
356 **
357 *******************************************************************************/
bta_av_group_navi_supported(UINT8 len,UINT8 * p_data,BOOLEAN is_inquiry)358 static tBTA_AV_CODE bta_av_group_navi_supported(UINT8 len, UINT8 *p_data, BOOLEAN is_inquiry)
359 {
360 tBTA_AV_CODE ret = BTA_AV_RSP_NOT_IMPL;
361 UINT8 *p_ptr = p_data;
362 UINT16 u16;
363 UINT32 u32;
364
365 if (p_bta_av_cfg->avrc_group && len == BTA_GROUP_NAVI_MSG_OP_DATA_LEN) {
366 BTA_AV_BE_STREAM_TO_CO_ID(u32, p_ptr);
367 BE_STREAM_TO_UINT16(u16, p_ptr);
368
369 if (u32 == AVRC_CO_METADATA) {
370 if (is_inquiry) {
371 if (u16 <= AVRC_PDU_PREV_GROUP) {
372 ret = BTA_AV_RSP_IMPL_STBL;
373 }
374 } else {
375 if (u16 <= AVRC_PDU_PREV_GROUP) {
376 ret = BTA_AV_RSP_ACCEPT;
377 } else {
378 ret = BTA_AV_RSP_REJ;
379 }
380 }
381 }
382 }
383
384 return ret;
385 }
386
387 /*******************************************************************************
388 **
389 ** Function bta_av_op_supported
390 **
391 ** Description Check if remote control operation is supported.
392 **
393 ** Returns BTA_AV_RSP_ACCEPT of supported, BTA_AV_RSP_NOT_IMPL if not.
394 **
395 *******************************************************************************/
bta_av_op_supported(tBTA_AV_RC rc_id,BOOLEAN is_inquiry)396 static tBTA_AV_CODE bta_av_op_supported(tBTA_AV_RC rc_id, BOOLEAN is_inquiry)
397 {
398 tBTA_AV_CODE ret_code = BTA_AV_RSP_NOT_IMPL;
399 BOOLEAN rc_id_allowed = FALSE;
400 if (bta_av_cb.p_rc_cos && bta_av_cb.p_rc_cos->rc_cmd) {
401 rc_id_allowed = bta_av_cb.p_rc_cos->rc_cmd(rc_id);
402 }
403
404 if (rc_id_allowed == TRUE) {
405 ret_code = is_inquiry ? BTA_AV_RSP_IMPL_STBL : BTA_AV_RSP_ACCEPT;
406 }
407 return ret_code;
408 }
409
410 /*******************************************************************************
411 **
412 ** Function bta_av_find_lcb
413 **
414 ** Description Given BD_addr, find the associated LCB.
415 **
416 ** Returns NULL, if not found.
417 **
418 *******************************************************************************/
bta_av_find_lcb(BD_ADDR addr,UINT8 op)419 tBTA_AV_LCB *bta_av_find_lcb(BD_ADDR addr, UINT8 op)
420 {
421 tBTA_AV_CB *p_cb = &bta_av_cb;
422 int xx;
423 UINT8 mask;
424 tBTA_AV_LCB *p_lcb = NULL;
425
426 for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
427 mask = 1 << xx; /* the used mask for this lcb */
428 if ((mask & p_cb->conn_lcb) && 0 == ( bdcmp(p_cb->lcb[xx].addr, addr))) {
429 p_lcb = &p_cb->lcb[xx];
430 if (op == BTA_AV_LCB_FREE) {
431 p_cb->conn_lcb &= ~mask; /* clear the connect mask */
432 APPL_TRACE_DEBUG("conn_lcb: 0x%x", p_cb->conn_lcb);
433 }
434 break;
435 }
436 }
437 return p_lcb;
438 }
439
440 /*******************************************************************************
441 **
442 ** Function bta_av_rc_opened
443 **
444 ** Description Set AVRCP state to opened.
445 **
446 ** Returns void
447 **
448 *******************************************************************************/
bta_av_rc_opened(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)449 void bta_av_rc_opened(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
450 {
451 tBTA_AV_RC_OPEN rc_open;
452 tBTA_AV_SCB *p_scb;
453 int i;
454 UINT8 shdl = 0;
455 tBTA_AV_LCB *p_lcb;
456 tBTA_AV_RCB *p_rcb;
457 UINT8 tmp;
458 UINT8 disc = 0;
459
460 /* find the SCB & stop the timer */
461 for (i = 0; i < BTA_AV_NUM_STRS; i++) {
462 p_scb = p_cb->p_scb[i];
463 if (p_scb && bdcmp(p_scb->peer_addr, p_data->rc_conn_chg.peer_addr) == 0) {
464 p_scb->rc_handle = p_data->rc_conn_chg.handle;
465 APPL_TRACE_DEBUG("bta_av_rc_opened shdl:%d, srch %d", i + 1, p_scb->rc_handle);
466 shdl = i + 1;
467 APPL_TRACE_EVENT("%s allow incoming AVRCP connections:%d", __func__, p_scb->use_rc);
468 bta_sys_stop_timer(&p_scb->timer);
469 disc = p_scb->hndl;
470 break;
471 }
472 }
473
474 i = p_data->rc_conn_chg.handle;
475 if (p_cb->rcb[i].handle == BTA_AV_RC_HANDLE_NONE) {
476 APPL_TRACE_ERROR("not a valid handle:%d any more", i);
477 return;
478 }
479
480
481 if (p_cb->rcb[i].lidx == (BTA_AV_NUM_LINKS + 1) && shdl != 0) {
482 /* rc is opened on the RC only ACP channel, but is for a specific
483 * SCB -> need to switch RCBs */
484 p_rcb = bta_av_get_rcb_by_shdl(shdl);
485 if (p_rcb) {
486 p_rcb->shdl = p_cb->rcb[i].shdl;
487 tmp = p_rcb->lidx;
488 p_rcb->lidx = p_cb->rcb[i].lidx;
489 p_cb->rcb[i].lidx = tmp;
490 p_cb->rc_acp_handle = p_rcb->handle;
491 p_cb->rc_acp_idx = (p_rcb - p_cb->rcb) + 1;
492 APPL_TRACE_DEBUG("switching RCB rc_acp_handle:%d idx:%d",
493 p_cb->rc_acp_handle, p_cb->rc_acp_idx);
494 }
495 }
496
497 p_cb->rcb[i].shdl = shdl;
498 rc_open.rc_handle = i;
499 APPL_TRACE_EVENT("bta_av_rc_opened rcb[%d] shdl:%d lidx:%d/%d",
500 i, shdl, p_cb->rcb[i].lidx, p_cb->lcb[BTA_AV_NUM_LINKS].lidx);
501 p_cb->rcb[i].status |= BTA_AV_RC_CONN_MASK;
502
503 if (!shdl && 0 == p_cb->lcb[BTA_AV_NUM_LINKS].lidx) {
504 /* no associated SCB -> connected to an RC only device
505 * update the index to the extra LCB */
506 p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
507 bdcpy(p_lcb->addr, p_data->rc_conn_chg.peer_addr);
508 APPL_TRACE_DEBUG("rc_only bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
509 p_lcb->addr[0], p_lcb->addr[1],
510 p_lcb->addr[2], p_lcb->addr[3],
511 p_lcb->addr[4], p_lcb->addr[5]);
512 p_lcb->lidx = BTA_AV_NUM_LINKS + 1;
513 p_cb->rcb[i].lidx = p_lcb->lidx;
514 p_lcb->conn_msk = 1;
515 APPL_TRACE_ERROR("rcb[%d].lidx=%d, lcb.conn_msk=x%x",
516 i, p_cb->rcb[i].lidx, p_lcb->conn_msk);
517 disc = p_data->rc_conn_chg.handle | BTA_AV_CHNL_MSK;
518 }
519
520 bdcpy(rc_open.peer_addr, p_data->rc_conn_chg.peer_addr);
521 rc_open.peer_features = p_cb->rcb[i].peer_features;
522 rc_open.peer_ct_features = p_cb->rcb[i].peer_ct_features;
523 rc_open.peer_tg_features = p_cb->rcb[i].peer_tg_features;
524 rc_open.sdp_disc_done = TRUE;
525 rc_open.status = BTA_AV_SUCCESS;
526 APPL_TRACE_DEBUG("local features:x%x peer_features:x%x", p_cb->features,
527 rc_open.peer_features);
528 if (rc_open.peer_features == 0) {
529 /* we have not done SDP on peer RC capabilities.
530 * peer must have initiated the RC connection */
531 rc_open.peer_features = BTA_AV_FEAT_RCCT;
532 rc_open.sdp_disc_done = FALSE;
533 bta_av_rc_disc(disc);
534 }
535 (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);
536
537 }
538
539
540 /*******************************************************************************
541 **
542 ** Function bta_av_rc_remote_cmd
543 **
544 ** Description Send an AVRCP remote control command.
545 **
546 ** Returns void
547 **
548 *******************************************************************************/
bta_av_rc_remote_cmd(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)549 void bta_av_rc_remote_cmd(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
550 {
551 tBTA_AV_RCB *p_rcb;
552 if (p_cb->features & BTA_AV_FEAT_RCCT) {
553 if (p_data->hdr.layer_specific < BTA_AV_NUM_RCB) {
554 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
555 if (p_rcb->status & BTA_AV_RC_CONN_MASK) {
556 AVRC_PassCmd(p_rcb->handle, p_data->api_remote_cmd.label,
557 &p_data->api_remote_cmd.msg);
558 }
559 }
560 }
561 }
562
563 /*******************************************************************************
564 **
565 ** Function bta_av_rc_vendor_cmd
566 **
567 ** Description Send an AVRCP vendor specific command.
568 **
569 ** Returns void
570 **
571 *******************************************************************************/
bta_av_rc_vendor_cmd(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)572 void bta_av_rc_vendor_cmd(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
573 {
574 tBTA_AV_RCB *p_rcb;
575 if ( (p_cb->features & (BTA_AV_FEAT_RCCT | BTA_AV_FEAT_VENDOR)) ==
576 (BTA_AV_FEAT_RCCT | BTA_AV_FEAT_VENDOR)) {
577 if (p_data->hdr.layer_specific < BTA_AV_NUM_RCB) {
578 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
579 AVRC_VendorCmd(p_rcb->handle, p_data->api_vendor.label, &p_data->api_vendor.msg);
580 }
581 }
582 }
583
584 /*******************************************************************************
585 **
586 ** Function bta_av_rc_vendor_rsp
587 **
588 ** Description Send an AVRCP vendor specific response.
589 **
590 ** Returns void
591 **
592 *******************************************************************************/
bta_av_rc_vendor_rsp(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)593 void bta_av_rc_vendor_rsp(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
594 {
595 tBTA_AV_RCB *p_rcb;
596 if ( (p_cb->features & (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_VENDOR)) ==
597 (BTA_AV_FEAT_RCTG | BTA_AV_FEAT_VENDOR)) {
598 if (p_data->hdr.layer_specific < BTA_AV_NUM_RCB) {
599 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
600 AVRC_VendorRsp(p_rcb->handle, p_data->api_vendor.label, &p_data->api_vendor.msg);
601 }
602 }
603 }
604
605 /*******************************************************************************
606 **
607 ** Function bta_av_rc_meta_rsp
608 **
609 ** Description Send an AVRCP metadata/advanced control command/response.
610 **
611 ** Returns void
612 **
613 *******************************************************************************/
bta_av_rc_meta_rsp(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)614 void bta_av_rc_meta_rsp(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
615 {
616 tBTA_AV_RCB *p_rcb;
617 BOOLEAN do_free = TRUE;
618
619 if ((p_cb->features & BTA_AV_FEAT_METADATA) && (p_data->hdr.layer_specific < BTA_AV_NUM_RCB)) {
620 if ((p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCTG)) ||
621 (!p_data->api_meta_rsp.is_rsp && (p_cb->features & BTA_AV_FEAT_RCCT)) ) {
622 p_rcb = &p_cb->rcb[p_data->hdr.layer_specific];
623 if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
624 AVRC_MsgReq(p_rcb->handle, p_data->api_meta_rsp.label,
625 p_data->api_meta_rsp.rsp_code,
626 p_data->api_meta_rsp.p_pkt);
627 do_free = FALSE;
628 }
629 }
630 }
631
632 if (do_free) {
633 osi_free (p_data->api_meta_rsp.p_pkt);
634 }
635 }
636
637 /*******************************************************************************
638 **
639 ** Function bta_av_rc_free_rsp
640 **
641 ** Description free an AVRCP metadata command buffer.
642 **
643 ** Returns void
644 **
645 *******************************************************************************/
bta_av_rc_free_rsp(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)646 void bta_av_rc_free_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
647 {
648 UNUSED(p_cb);
649
650 osi_free (p_data->api_meta_rsp.p_pkt);
651 }
652
653 /*******************************************************************************
654 **
655 ** Function bta_av_rc_meta_req
656 **
657 ** Description Send an AVRCP metadata command.
658 **
659 ** Returns void
660 **
661 *******************************************************************************/
bta_av_rc_free_msg(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)662 void bta_av_rc_free_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
663 {
664 UNUSED(p_cb);
665 UNUSED(p_data);
666 }
667
668
669
670 /*******************************************************************************
671 **
672 ** Function bta_av_chk_notif_evt_id
673 **
674 ** Description make sure the requested player id is valid.
675 **
676 ** Returns BTA_AV_STS_NO_RSP, if no error
677 **
678 *******************************************************************************/
bta_av_chk_notif_evt_id(tAVRC_MSG_VENDOR * p_vendor)679 static tAVRC_STS bta_av_chk_notif_evt_id(tAVRC_MSG_VENDOR *p_vendor)
680 {
681 tAVRC_STS status = BTA_AV_STS_NO_RSP;
682 UINT16 u16;
683 UINT8 *p = p_vendor->p_vendor_data + 2;
684
685 BE_STREAM_TO_UINT16 (u16, p);
686 /* double check the fixed length */
687 if ((u16 != 5) || (p_vendor->vendor_len != 9)) {
688 status = AVRC_STS_INTERNAL_ERR;
689 } else {
690 /* make sure the event_id is valid */
691 status = AVRC_STS_BAD_PARAM;
692 if (bta_av_cb.p_rc_cos && bta_av_cb.p_rc_cos->rn_evt_supported) {
693 if (bta_av_cb.p_rc_cos->rn_evt_supported(*p) == TRUE) {
694 status = BTA_AV_STS_NO_RSP;
695 }
696 }
697 }
698
699 return status;
700 }
701
702 /*******************************************************************************
703 **
704 ** Function bta_av_proc_meta_cmd
705 **
706 ** Description Process an AVRCP metadata command from the peer.
707 **
708 ** Returns TRUE to respond immediately
709 **
710 *******************************************************************************/
bta_av_proc_meta_cmd(tAVRC_RESPONSE * p_rc_rsp,tBTA_AV_RC_MSG * p_msg,UINT8 * p_ctype)711 tBTA_AV_EVT bta_av_proc_meta_cmd(tAVRC_RESPONSE *p_rc_rsp, tBTA_AV_RC_MSG *p_msg, UINT8 *p_ctype)
712 {
713 tBTA_AV_EVT evt = BTA_AV_META_MSG_EVT;
714 UINT8 u8, pdu, *p;
715 UINT16 u16;
716 tAVRC_MSG_VENDOR *p_vendor = &p_msg->msg.vendor;
717
718 #if (AVRC_METADATA_INCLUDED == TRUE)
719
720 pdu = *(p_vendor->p_vendor_data);
721 p_rc_rsp->pdu = pdu;
722 *p_ctype = AVRC_RSP_REJ;
723 /* Metadata messages only use PANEL sub-unit type */
724 if (p_vendor->hdr.subunit_type != AVRC_SUB_PANEL) {
725 APPL_TRACE_DEBUG("SUBUNIT must be PANEL");
726 /* reject it */
727 evt = 0;
728 p_vendor->hdr.ctype = BTA_AV_RSP_NOT_IMPL;
729 AVRC_VendorRsp(p_msg->handle, p_msg->label, &p_msg->msg.vendor);
730 } else if (!AVRC_IsValidAvcType(pdu, p_vendor->hdr.ctype) ) {
731 APPL_TRACE_DEBUG("Invalid pdu/ctype: 0x%x, %d", pdu, p_vendor->hdr.ctype);
732 /* reject invalid message without reporting to app */
733 evt = 0;
734 p_rc_rsp->rsp.status = AVRC_STS_BAD_CMD;
735 } else {
736 switch (pdu) {
737 case AVRC_PDU_GET_CAPABILITIES:
738 /* process GetCapabilities command without reporting the event to app */
739 evt = 0;
740 u8 = *(p_vendor->p_vendor_data + 4);
741 p = p_vendor->p_vendor_data + 2;
742 p_rc_rsp->get_caps.capability_id = u8;
743 BE_STREAM_TO_UINT16 (u16, p);
744 if ((u16 != 1) || (p_vendor->vendor_len != 5)) {
745 p_rc_rsp->get_caps.status = AVRC_STS_INTERNAL_ERR;
746 } else {
747 p_rc_rsp->get_caps.status = AVRC_STS_NO_ERROR;
748 if (u8 == AVRC_CAP_COMPANY_ID) {
749 *p_ctype = AVRC_RSP_IMPL_STBL;
750 p_rc_rsp->get_caps.count = p_bta_av_cfg->num_co_ids;
751 memcpy(p_rc_rsp->get_caps.param.company_id, p_bta_av_cfg->p_meta_co_ids,
752 (p_bta_av_cfg->num_co_ids << 2));
753 } else if (u8 == AVRC_CAP_EVENTS_SUPPORTED) {
754 *p_ctype = AVRC_RSP_IMPL_STBL;
755 if (bta_av_cb.p_rc_cos && bta_av_cb.p_rc_cos->rn_evt_cap) {
756 p_rc_rsp->get_caps.count = bta_av_cb.p_rc_cos->rn_evt_cap(
757 p_rc_rsp->get_caps.param.event_id);
758 } else {
759 p_rc_rsp->get_caps.count = 0;
760 }
761 } else {
762 APPL_TRACE_DEBUG("Invalid capability ID: 0x%x", u8);
763 /* reject - unknown capability ID */
764 p_rc_rsp->get_caps.status = AVRC_STS_BAD_PARAM;
765 }
766 }
767 break;
768
769 case AVRC_PDU_REGISTER_NOTIFICATION:
770 /* make sure the event_id is implemented */
771 p_rc_rsp->rsp.status = bta_av_chk_notif_evt_id (p_vendor);
772 if (p_rc_rsp->rsp.status != BTA_AV_STS_NO_RSP) {
773 evt = 0;
774 }
775 break;
776
777 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
778 p_rc_rsp->rsp.status = BTA_AV_STS_NO_RSP;
779 break;
780 case AVRC_PDU_SET_PLAYER_APP_VALUE:
781 /* Setting of a value by CT does not implicitly mean that the setting will take effect on TG. */
782 /* The setting shall take effect after a play command from CT. */
783 break;
784 default:
785 APPL_TRACE_WARNING("%s unhandled RC vendor PDU: 0x%x", __FUNCTION__, pdu);
786 break;
787 }
788 }
789 #else
790 APPL_TRACE_DEBUG("AVRCP 1.3 Metadata not supporteed. Reject command.");
791 /* reject invalid message without reporting to app */
792 evt = 0;
793 p_rc_rsp->rsp.status = AVRC_STS_BAD_CMD;
794 #endif
795
796 return evt;
797 }
798
799
800 /*******************************************************************************
801 **
802 ** Function bta_av_rc_msg
803 **
804 ** Description Process an AVRCP message from the peer.
805 **
806 ** Returns void
807 **
808 *******************************************************************************/
bta_av_rc_msg(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)809 void bta_av_rc_msg(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
810 {
811 tBTA_AV_EVT evt = 0;
812 tBTA_AV av;
813 BT_HDR *p_pkt = NULL;
814 tAVRC_MSG_VENDOR *p_vendor = &p_data->rc_msg.msg.vendor;
815 BOOLEAN is_inquiry = ((p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_SPEC_INQ) || p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_GEN_INQ);
816 #if (AVRC_METADATA_INCLUDED == TRUE)
817 UINT8 ctype = 0;
818 tAVRC_RESPONSE rc_rsp;
819
820 rc_rsp.rsp.status = BTA_AV_STS_NO_RSP;
821 #endif
822
823 if (p_data->rc_msg.opcode == AVRC_OP_PASS_THRU) {
824 /* if this is a pass thru command */
825 if ((p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_CTRL) ||
826 (p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_SPEC_INQ) ||
827 (p_data->rc_msg.msg.hdr.ctype == AVRC_CMD_GEN_INQ)
828 ) {
829 /* check if operation is supported */
830 if (p_data->rc_msg.msg.pass.op_id == AVRC_ID_VENDOR) {
831 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_NOT_IMPL;
832 #if (AVRC_METADATA_INCLUDED == TRUE)
833 if (p_cb->features & BTA_AV_FEAT_METADATA) {
834 p_data->rc_msg.msg.hdr.ctype =
835 bta_av_group_navi_supported(p_data->rc_msg.msg.pass.pass_len,
836 p_data->rc_msg.msg.pass.p_pass_data, is_inquiry);
837 }
838 #endif
839 } else {
840 p_data->rc_msg.msg.hdr.ctype = bta_av_op_supported(p_data->rc_msg.msg.pass.op_id, is_inquiry);
841 }
842
843 APPL_TRACE_DEBUG("ctype %d", p_data->rc_msg.msg.hdr.ctype)
844
845 /* send response */
846 if (p_data->rc_msg.msg.hdr.ctype != BTA_AV_RSP_INTERIM) {
847 AVRC_PassRsp(p_data->rc_msg.handle, p_data->rc_msg.label, &p_data->rc_msg.msg.pass);
848 }
849
850 /* set up for callback if supported */
851 if (p_data->rc_msg.msg.hdr.ctype == BTA_AV_RSP_ACCEPT || p_data->rc_msg.msg.hdr.ctype == BTA_AV_RSP_INTERIM) {
852 evt = BTA_AV_REMOTE_CMD_EVT;
853 av.remote_cmd.rc_id = p_data->rc_msg.msg.pass.op_id;
854 av.remote_cmd.key_state = p_data->rc_msg.msg.pass.state;
855 av.remote_cmd.p_data = p_data->rc_msg.msg.pass.p_pass_data;
856 av.remote_cmd.len = p_data->rc_msg.msg.pass.pass_len;
857 memcpy(&av.remote_cmd.hdr, &p_data->rc_msg.msg.hdr, sizeof (tAVRC_HDR));
858 av.remote_cmd.label = p_data->rc_msg.label;
859 }
860 }
861 /* else if this is a pass thru respone that TG doesn't implement thie command */
862 else if (p_data->rc_msg.msg.hdr.ctype == AVRC_RSP_NOT_IMPL) {
863 /* do nothing, no need to setup for callback */
864 }
865 /* else if this is a pass thru response */
866 else if (p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_ACCEPT) {
867 /* set up for callback */
868 evt = BTA_AV_REMOTE_RSP_EVT;
869 av.remote_rsp.rc_id = p_data->rc_msg.msg.pass.op_id;
870 av.remote_rsp.key_state = p_data->rc_msg.msg.pass.state;
871 av.remote_rsp.rsp_code = p_data->rc_msg.msg.hdr.ctype;
872 av.remote_rsp.label = p_data->rc_msg.label;
873 }
874 /* must be a bad ctype -> reject*/
875 else {
876 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_REJ;
877 AVRC_PassRsp(p_data->rc_msg.handle, p_data->rc_msg.label, &p_data->rc_msg.msg.pass);
878 }
879 }
880 /* else if this is a vendor specific command or response */
881 else if (p_data->rc_msg.opcode == AVRC_OP_VENDOR) {
882 /* set up for callback */
883 av.vendor_cmd.code = p_data->rc_msg.msg.hdr.ctype;
884 av.vendor_cmd.company_id = p_vendor->company_id;
885 av.vendor_cmd.label = p_data->rc_msg.label;
886 av.vendor_cmd.p_data = p_vendor->p_vendor_data;
887 av.vendor_cmd.len = p_vendor->vendor_len;
888
889 /* if configured to support vendor specific and it's a command */
890 if ((p_cb->features & BTA_AV_FEAT_VENDOR) &&
891 p_data->rc_msg.msg.hdr.ctype <= AVRC_CMD_GEN_INQ) {
892 #if (AVRC_METADATA_INCLUDED == TRUE)
893 if ((p_cb->features & BTA_AV_FEAT_METADATA) &&
894 (p_vendor->company_id == AVRC_CO_METADATA)) {
895 av.meta_msg.p_msg = &p_data->rc_msg.msg;
896 evt = bta_av_proc_meta_cmd (&rc_rsp, &p_data->rc_msg, &ctype);
897 } else
898 #endif
899 {
900 evt = BTA_AV_VENDOR_CMD_EVT;
901 }
902 }
903 /* else if configured to support vendor specific and it's a response */
904 else if ((p_cb->features & BTA_AV_FEAT_VENDOR) &&
905 p_data->rc_msg.msg.hdr.ctype >= AVRC_RSP_ACCEPT) {
906 #if (AVRC_METADATA_INCLUDED == TRUE)
907 if ((p_cb->features & BTA_AV_FEAT_METADATA) &&
908 (p_vendor->company_id == AVRC_CO_METADATA)) {
909 av.meta_msg.p_msg = &p_data->rc_msg.msg;
910 evt = BTA_AV_META_MSG_EVT;
911 } else
912 #endif
913 {
914 evt = BTA_AV_VENDOR_RSP_EVT;
915 }
916
917 }
918 /* else if not configured to support vendor specific and it's a command */
919 else if (!(p_cb->features & BTA_AV_FEAT_VENDOR) &&
920 p_data->rc_msg.msg.hdr.ctype <= AVRC_CMD_GEN_INQ) {
921 if (p_data->rc_msg.msg.vendor.p_vendor_data[0] == AVRC_PDU_INVALID) {
922 /* reject it */
923 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_REJ;
924 p_data->rc_msg.msg.vendor.p_vendor_data[4] = AVRC_STS_BAD_CMD;
925 } else {
926 p_data->rc_msg.msg.hdr.ctype = BTA_AV_RSP_NOT_IMPL;
927 }
928 AVRC_VendorRsp(p_data->rc_msg.handle, p_data->rc_msg.label, &p_data->rc_msg.msg.vendor);
929 }
930 }
931 #if (AVRC_METADATA_INCLUDED == TRUE)
932 if (evt == 0 && rc_rsp.rsp.status != BTA_AV_STS_NO_RSP) {
933 if (!p_pkt) {
934 rc_rsp.rsp.opcode = p_data->rc_msg.opcode;
935 AVRC_BldResponse (0, &rc_rsp, &p_pkt);
936 }
937 if (p_pkt) {
938 AVRC_MsgReq (p_data->rc_msg.handle, p_data->rc_msg.label, ctype, p_pkt);
939 }
940 }
941 #endif
942
943 /* call callback */
944 if (evt != 0) {
945 av.remote_cmd.rc_handle = p_data->rc_msg.handle;
946 (*p_cb->p_cback)(evt, &av);
947 }
948 }
949
950 /*******************************************************************************
951 **
952 ** Function bta_av_rc_close
953 **
954 ** Description close the specified AVRC handle.
955 **
956 ** Returns void
957 **
958 *******************************************************************************/
bta_av_rc_close(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)959 void bta_av_rc_close (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
960 {
961 UINT16 handle = p_data->hdr.layer_specific;
962 tBTA_AV_SCB *p_scb;
963 tBTA_AV_RCB *p_rcb;
964
965 if (handle < BTA_AV_NUM_RCB) {
966 p_rcb = &p_cb->rcb[handle];
967
968 APPL_TRACE_DEBUG("bta_av_rc_close handle: %d, status=0x%x", p_rcb->handle, p_rcb->status);
969 if (p_rcb->handle != BTA_AV_RC_HANDLE_NONE) {
970 if (p_rcb->shdl) {
971 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
972 if (p_scb) {
973 /* just in case the RC timer is active
974 if(bta_av_cb.features & BTA_AV_FEAT_RCCT &&
975 p_scb->chnl == BTA_AV_CHNL_AUDIO) */
976 bta_sys_stop_timer(&p_scb->timer);
977 }
978 }
979
980 AVRC_Close(p_rcb->handle);
981 }
982 }
983 }
984
985 /*******************************************************************************
986 **
987 ** Function bta_av_get_shdl
988 **
989 ** Returns The index to p_scb[]
990 **
991 *******************************************************************************/
bta_av_get_shdl(tBTA_AV_SCB * p_scb)992 static UINT8 bta_av_get_shdl(tBTA_AV_SCB *p_scb)
993 {
994 int i;
995 UINT8 shdl = 0;
996 /* find the SCB & stop the timer */
997 for (i = 0; i < BTA_AV_NUM_STRS; i++) {
998 if (p_scb == bta_av_cb.p_scb[i]) {
999 shdl = i + 1;
1000 break;
1001 }
1002 }
1003 return shdl;
1004 }
1005
1006 /*******************************************************************************
1007 **
1008 ** Function bta_av_stream_chg
1009 **
1010 ** Description audio streaming status changed.
1011 **
1012 ** Returns void
1013 **
1014 *******************************************************************************/
bta_av_stream_chg(tBTA_AV_SCB * p_scb,BOOLEAN started)1015 void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started)
1016 {
1017 UINT8 started_msk;
1018 int i;
1019 UINT8 *p_streams;
1020 BOOLEAN no_streams = FALSE;
1021 tBTA_AV_SCB *p_scbi;
1022
1023 started_msk = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
1024 APPL_TRACE_DEBUG ("bta_av_stream_chg started:%d started_msk:x%x chnl:x%x", started,
1025 started_msk, p_scb->chnl);
1026 if (BTA_AV_CHNL_AUDIO == p_scb->chnl) {
1027 p_streams = &bta_av_cb.audio_streams;
1028 } else {
1029 p_streams = &bta_av_cb.video_streams;
1030 }
1031
1032 if (started) {
1033 /* Let L2CAP know this channel is processed with high priority */
1034 L2CA_SetAclPriority(p_scb->peer_addr, L2CAP_PRIORITY_HIGH);
1035 (*p_streams) |= started_msk;
1036 } else {
1037 (*p_streams) &= ~started_msk;
1038 }
1039
1040 if (!started) {
1041 i = 0;
1042 if (BTA_AV_CHNL_AUDIO == p_scb->chnl) {
1043 if (bta_av_cb.video_streams == 0) {
1044 no_streams = TRUE;
1045 }
1046 } else {
1047 no_streams = TRUE;
1048 if ( bta_av_cb.audio_streams ) {
1049 for (; i < BTA_AV_NUM_STRS; i++) {
1050 p_scbi = bta_av_cb.p_scb[i];
1051 /* scb is used and started */
1052 if ( p_scbi && (bta_av_cb.audio_streams & BTA_AV_HNDL_TO_MSK(i))
1053 && bdcmp(p_scbi->peer_addr, p_scb->peer_addr) == 0) {
1054 no_streams = FALSE;
1055 break;
1056 }
1057 }
1058
1059 }
1060 }
1061
1062 APPL_TRACE_DEBUG ("no_streams:%d i:%d, audio_streams:x%x, video_streams:x%x", no_streams, i,
1063 bta_av_cb.audio_streams, bta_av_cb.video_streams);
1064 if (no_streams) {
1065 /* Let L2CAP know this channel is processed with low priority */
1066 L2CA_SetAclPriority(p_scb->peer_addr, L2CAP_PRIORITY_NORMAL);
1067 }
1068 }
1069 }
1070
1071
1072 /*******************************************************************************
1073 **
1074 ** Function bta_av_conn_chg
1075 **
1076 ** Description connection status changed.
1077 ** Open an AVRCP acceptor channel, if new conn.
1078 **
1079 ** Returns void
1080 **
1081 *******************************************************************************/
bta_av_conn_chg(tBTA_AV_DATA * p_data)1082 void bta_av_conn_chg(tBTA_AV_DATA *p_data)
1083 {
1084 tBTA_AV_CB *p_cb = &bta_av_cb;
1085 tBTA_AV_SCB *p_scb = NULL;
1086 tBTA_AV_SCB *p_scbi;
1087 UINT8 mask;
1088 UINT8 conn_msk;
1089 UINT8 old_msk;
1090 int i;
1091 int index = (p_data->hdr.layer_specific & BTA_AV_HNDL_MSK) - 1;
1092 tBTA_AV_LCB *p_lcb;
1093 tBTA_AV_LCB *p_lcb_rc;
1094 tBTA_AV_RCB *p_rcb, *p_rcb2;
1095 BOOLEAN chk_restore = FALSE;
1096
1097 /* Validate array index*/
1098 if (index < BTA_AV_NUM_STRS) {
1099 p_scb = p_cb->p_scb[index];
1100 }
1101 mask = BTA_AV_HNDL_TO_MSK(index);
1102 p_lcb = bta_av_find_lcb(p_data->conn_chg.peer_addr, BTA_AV_LCB_FIND);
1103 conn_msk = 1 << (index + 1);
1104 if (p_data->conn_chg.is_up) {
1105 /* set the conned mask for this channel */
1106 if (p_scb) {
1107 if (p_lcb) {
1108 p_lcb->conn_msk |= conn_msk;
1109 for (i = 0; i < BTA_AV_NUM_RCB; i++) {
1110 if (bta_av_cb.rcb[i].lidx == p_lcb->lidx) {
1111 bta_av_cb.rcb[i].shdl = index + 1;
1112 APPL_TRACE_DEBUG("conn_chg up[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
1113 bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
1114 bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
1115 break;
1116 }
1117 }
1118 }
1119 if (p_scb->chnl == BTA_AV_CHNL_AUDIO) {
1120 old_msk = p_cb->conn_audio;
1121 p_cb->conn_audio |= mask;
1122 } else {
1123 old_msk = p_cb->conn_video;
1124 p_cb->conn_video |= mask;
1125 }
1126
1127 if ((old_msk & mask) == 0) {
1128 /* increase the audio open count, if not set yet */
1129 bta_av_cb.audio_open_cnt++;
1130 }
1131
1132
1133 APPL_TRACE_DEBUG("rc_acp_handle:%d rc_acp_idx:%d", p_cb->rc_acp_handle, p_cb->rc_acp_idx);
1134 /* check if the AVRCP ACP channel is already connected */
1135 if (p_lcb && p_cb->rc_acp_handle != BTA_AV_RC_HANDLE_NONE && p_cb->rc_acp_idx) {
1136 p_lcb_rc = &p_cb->lcb[BTA_AV_NUM_LINKS];
1137 APPL_TRACE_DEBUG("rc_acp is connected && conn_chg on same addr p_lcb_rc->conn_msk:x%x",
1138 p_lcb_rc->conn_msk);
1139 /* check if the RC is connected to the scb addr */
1140 APPL_TRACE_DEBUG ("p_lcb_rc->addr: %02x:%02x:%02x:%02x:%02x:%02x",
1141 p_lcb_rc->addr[0], p_lcb_rc->addr[1], p_lcb_rc->addr[2], p_lcb_rc->addr[3],
1142 p_lcb_rc->addr[4], p_lcb_rc->addr[5]);
1143 APPL_TRACE_DEBUG ("conn_chg.peer_addr: %02x:%02x:%02x:%02x:%02x:%02x",
1144 p_data->conn_chg.peer_addr[0], p_data->conn_chg.peer_addr[1],
1145 p_data->conn_chg.peer_addr[2],
1146 p_data->conn_chg.peer_addr[3], p_data->conn_chg.peer_addr[4],
1147 p_data->conn_chg.peer_addr[5]);
1148 if (p_lcb_rc->conn_msk && bdcmp(p_lcb_rc->addr, p_data->conn_chg.peer_addr) == 0) {
1149 /* AVRCP is already connected.
1150 * need to update the association betwen SCB and RCB */
1151 p_lcb_rc->conn_msk = 0; /* indicate RC ONLY is not connected */
1152 p_lcb_rc->lidx = 0;
1153 p_scb->rc_handle = p_cb->rc_acp_handle;
1154 p_rcb = &p_cb->rcb[p_cb->rc_acp_idx - 1];
1155 p_rcb->shdl = bta_av_get_shdl(p_scb);
1156 APPL_TRACE_DEBUG("update rc_acp shdl:%d/%d srch:%d", index + 1, p_rcb->shdl,
1157 p_scb->rc_handle );
1158
1159 p_rcb2 = bta_av_get_rcb_by_shdl(p_rcb->shdl);
1160 if (p_rcb2) {
1161 /* found the RCB that was created to associated with this SCB */
1162 p_cb->rc_acp_handle = p_rcb2->handle;
1163 p_cb->rc_acp_idx = (p_rcb2 - p_cb->rcb) + 1;
1164 APPL_TRACE_DEBUG("new rc_acp_handle:%d, idx:%d", p_cb->rc_acp_handle,
1165 p_cb->rc_acp_idx);
1166 p_rcb2->lidx = (BTA_AV_NUM_LINKS + 1);
1167 APPL_TRACE_DEBUG("rc2 handle:%d lidx:%d/%d", p_rcb2->handle, p_rcb2->lidx,
1168 p_cb->lcb[p_rcb2->lidx - 1].lidx);
1169 }
1170 p_rcb->lidx = p_lcb->lidx;
1171 APPL_TRACE_DEBUG("rc handle:%d lidx:%d/%d", p_rcb->handle, p_rcb->lidx,
1172 p_cb->lcb[p_rcb->lidx - 1].lidx);
1173 }
1174 }
1175 }
1176 } else {
1177 if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) {
1178 /* this channel is still marked as open. decrease the count */
1179 bta_av_cb.audio_open_cnt--;
1180 }
1181
1182 /* clear the conned mask for this channel */
1183 p_cb->conn_audio &= ~mask;
1184 p_cb->conn_video &= ~mask;
1185 if (p_scb) {
1186 /* the stream is closed.
1187 * clear the peer address, so it would not mess up the AVRCP for the next round of operation */
1188 bdcpy(p_scb->peer_addr, bd_addr_null);
1189 if (p_scb->chnl == BTA_AV_CHNL_AUDIO) {
1190 if (p_lcb) {
1191 p_lcb->conn_msk &= ~conn_msk;
1192 }
1193 /* audio channel is down. make sure the INT channel is down */
1194 /* just in case the RC timer is active
1195 if(p_cb->features & BTA_AV_FEAT_RCCT) */
1196 {
1197 bta_sys_stop_timer(&p_scb->timer);
1198 }
1199 /* one audio channel goes down. check if we need to restore high priority */
1200 chk_restore = TRUE;
1201 }
1202 }
1203
1204 APPL_TRACE_DEBUG("bta_av_conn_chg shdl:%d", index + 1);
1205 for (i = 0; i < BTA_AV_NUM_RCB; i++) {
1206 APPL_TRACE_DEBUG("conn_chg dn[%d]: %d, status=0x%x, shdl:%d, lidx:%d", i,
1207 bta_av_cb.rcb[i].handle, bta_av_cb.rcb[i].status,
1208 bta_av_cb.rcb[i].shdl, bta_av_cb.rcb[i].lidx);
1209 if (bta_av_cb.rcb[i].shdl == index + 1) {
1210 bta_av_del_rc(&bta_av_cb.rcb[i]);
1211 break;
1212 }
1213 }
1214
1215 if (p_cb->conn_audio == 0 && p_cb->conn_video == 0) {
1216 /* if both channels are not connected,
1217 * close all RC channels */
1218 bta_av_close_all_rc(p_cb);
1219 }
1220
1221 /* if the AVRCP is no longer listening, create the listening channel */
1222 if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) {
1223 bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
1224 }
1225 }
1226
1227 APPL_TRACE_DEBUG("bta_av_conn_chg audio:%x video:%x up:%d conn_msk:0x%x chk_restore:%d audio_open_cnt:%d",
1228 p_cb->conn_audio, p_cb->conn_video, p_data->conn_chg.is_up, conn_msk, chk_restore, p_cb->audio_open_cnt);
1229
1230 if (chk_restore) {
1231 if (p_cb->audio_open_cnt == 1) {
1232 /* one audio channel goes down and there's one audio channel remains open.
1233 * restore the switch role in default link policy */
1234 bta_sys_set_default_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH);
1235 /* allow role switch, if this is the last connection */
1236 bta_av_restore_switch();
1237 }
1238 if (p_cb->audio_open_cnt) {
1239 /* adjust flush timeout settings to longer period */
1240 for (i = 0; i < BTA_AV_NUM_STRS; i++) {
1241 p_scbi = bta_av_cb.p_scb[i];
1242 if (p_scbi && p_scbi->chnl == BTA_AV_CHNL_AUDIO && p_scbi->co_started) {
1243 /* may need to update the flush timeout of this already started stream */
1244 if (p_scbi->co_started != bta_av_cb.audio_open_cnt) {
1245 p_scbi->co_started = bta_av_cb.audio_open_cnt;
1246 L2CA_SetFlushTimeout(p_scbi->peer_addr, p_bta_av_cfg->p_audio_flush_to[p_scbi->co_started - 1] );
1247 }
1248 }
1249 }
1250 }
1251 }
1252 }
1253
1254 /*******************************************************************************
1255 **
1256 ** Function bta_av_disable
1257 **
1258 ** Description disable AV.
1259 **
1260 ** Returns void
1261 **
1262 *******************************************************************************/
bta_av_disable(tBTA_AV_CB * p_cb,tBTA_AV_DATA * p_data)1263 void bta_av_disable(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
1264 {
1265 BT_HDR hdr;
1266 UINT16 xx;
1267 UNUSED(p_data);
1268
1269 p_cb->disabling = TRUE;
1270
1271 bta_av_close_all_rc(p_cb);
1272
1273 utl_freebuf((void **) &p_cb->p_disc_db);
1274
1275 /* disable audio/video - de-register all channels,
1276 * expect BTA_AV_DEREG_COMP_EVT when deregister is complete */
1277 for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
1278 hdr.layer_specific = xx + 1;
1279 bta_av_api_deregister((tBTA_AV_DATA *)&hdr);
1280 }
1281
1282 bta_sys_free_timer(&p_cb->sig_tmr);
1283 memset(&p_cb->sig_tmr, 0, sizeof(TIMER_LIST_ENT));
1284 bta_sys_free_timer(&p_cb->acp_sig_tmr);
1285 memset(&p_cb->acp_sig_tmr, 0, sizeof(TIMER_LIST_ENT));
1286 }
1287
1288 /*******************************************************************************
1289 **
1290 ** Function bta_av_api_disconnect
1291 **
1292 ** Description .
1293 **
1294 ** Returns void
1295 **
1296 *******************************************************************************/
bta_av_api_disconnect(tBTA_AV_DATA * p_data)1297 void bta_av_api_disconnect(tBTA_AV_DATA *p_data)
1298 {
1299 AVDT_DisconnectReq(p_data->api_discnt.bd_addr, bta_av_conn_cback);
1300 bta_sys_stop_timer(&bta_av_cb.sig_tmr);
1301 }
1302
1303 /*******************************************************************************
1304 **
1305 ** Function bta_av_sig_chg
1306 **
1307 ** Description process AVDT signal channel up/down.
1308 **
1309 ** Returns void
1310 **
1311 *******************************************************************************/
bta_av_sig_chg(tBTA_AV_DATA * p_data)1312 void bta_av_sig_chg(tBTA_AV_DATA *p_data)
1313 {
1314 UINT16 event = p_data->str_msg.hdr.layer_specific;
1315 tBTA_AV_CB *p_cb = &bta_av_cb;
1316 int xx;
1317 UINT8 mask;
1318 tBTA_AV_LCB *p_lcb = NULL;
1319
1320 APPL_TRACE_DEBUG("bta_av_sig_chg event: %d", event);
1321 if (event == AVDT_CONNECT_IND_EVT) {
1322 p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FIND);
1323 if (!p_lcb) {
1324 /* if the address does not have an LCB yet, alloc one */
1325 for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
1326 mask = 1 << xx;
1327 APPL_TRACE_DEBUG("conn_lcb: 0x%x", p_cb->conn_lcb);
1328
1329 /* look for a p_lcb with its p_scb registered */
1330 if ((!(mask & p_cb->conn_lcb)) && (p_cb->p_scb[xx] != NULL)) {
1331 p_lcb = &p_cb->lcb[xx];
1332 p_lcb->lidx = xx + 1;
1333 bdcpy(p_lcb->addr, p_data->str_msg.bd_addr);
1334 p_lcb->conn_msk = 0; /* clear the connect mask */
1335 /* start listening when the signal channel is open */
1336 if (p_cb->features & BTA_AV_FEAT_RCTG) {
1337 bta_av_rc_create(p_cb, AVCT_ACP, 0, p_lcb->lidx);
1338 }
1339 /* this entry is not used yet. */
1340 p_cb->conn_lcb |= mask; /* mark it as used */
1341 APPL_TRACE_DEBUG("start sig timer %d", p_data->hdr.offset);
1342 if (p_data->hdr.offset == AVDT_ACP) {
1343 APPL_TRACE_DEBUG("Incoming L2CAP acquired, set state as incoming");
1344 bdcpy(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr);
1345 p_cb->p_scb[xx]->use_rc = TRUE; /* allowing RC for incoming connection */
1346 bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_ACP_CONNECT_EVT, p_data);
1347
1348 /* The Pending Event should be sent as soon as the L2CAP signalling channel
1349 * is set up, which is NOW. Earlier this was done only after
1350 * BTA_AV_SIG_TIME_VAL milliseconds.
1351 * The following function shall send the event and start the recurring timer
1352 */
1353 bta_av_sig_timer(NULL);
1354
1355 /* Possible collision : need to avoid outgoing processing while the timer is running */
1356 p_cb->p_scb[xx]->coll_mask = BTA_AV_COLL_INC_TMR;
1357
1358 p_cb->acp_sig_tmr.param = (UINT32)xx;
1359 p_cb->acp_sig_tmr.p_cback = (TIMER_CBACK *)&bta_av_acp_sig_timer_cback;
1360 bta_sys_start_timer(&p_cb->acp_sig_tmr, 0, BTA_AV_ACP_SIG_TIME_VAL);
1361 }
1362 break;
1363 }
1364 }
1365
1366 /* check if we found something */
1367 if (xx == BTA_AV_NUM_LINKS) {
1368 /* We do not have scb for this avdt connection. */
1369 /* Silently close the connection. */
1370 APPL_TRACE_ERROR("av scb not available for avdt connection");
1371 AVDT_DisconnectReq (p_data->str_msg.bd_addr, NULL);
1372 return;
1373 }
1374 }
1375 }
1376 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
1377 else if (event == BTA_AR_AVDT_CONN_EVT) {
1378 bta_sys_stop_timer(&bta_av_cb.sig_tmr);
1379 }
1380 #endif
1381 else {
1382 /* disconnected. */
1383 p_lcb = bta_av_find_lcb(p_data->str_msg.bd_addr, BTA_AV_LCB_FREE);
1384 if (p_lcb && p_lcb->conn_msk) {
1385 APPL_TRACE_DEBUG("conn_msk: 0x%x", p_lcb->conn_msk);
1386 /* clean up ssm */
1387 for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
1388 mask = 1 << (xx + 1);
1389 if ((mask & p_lcb->conn_msk) && (p_cb->p_scb[xx]) &&
1390 (bdcmp(p_cb->p_scb[xx]->peer_addr, p_data->str_msg.bd_addr) == 0)) {
1391 p_cb->p_scb[xx]->disc_rsn = p_data->str_msg.hdr.offset;
1392 bta_av_ssm_execute(p_cb->p_scb[xx], BTA_AV_AVDT_DISCONNECT_EVT, NULL);
1393 }
1394 }
1395 }
1396 }
1397 APPL_TRACE_DEBUG("conn_lcb: 0x%x", p_cb->conn_lcb);
1398 }
1399
1400 /*******************************************************************************
1401 **
1402 ** Function bta_av_sig_timer
1403 **
1404 ** Description process the signal channel timer. This timer is started
1405 ** when the AVDTP signal channel is connected. If no profile
1406 ** is connected, the timer goes off every BTA_AV_SIG_TIME_VAL
1407 **
1408 ** Returns void
1409 **
1410 *******************************************************************************/
bta_av_sig_timer(tBTA_AV_DATA * p_data)1411 void bta_av_sig_timer(tBTA_AV_DATA *p_data)
1412 {
1413 tBTA_AV_CB *p_cb = &bta_av_cb;
1414 int xx;
1415 UINT8 mask;
1416 tBTA_AV_LCB *p_lcb = NULL;
1417 tBTA_AV_PEND pend;
1418 UNUSED(p_data);
1419
1420 APPL_TRACE_DEBUG("bta_av_sig_timer");
1421 for (xx = 0; xx < BTA_AV_NUM_LINKS; xx++) {
1422 mask = 1 << xx;
1423 if (mask & p_cb->conn_lcb) {
1424 /* this entry is used. check if it is connected */
1425 p_lcb = &p_cb->lcb[xx];
1426 if (!p_lcb->conn_msk) {
1427 bta_sys_start_timer(&p_cb->sig_tmr, BTA_AV_SIG_TIMER_EVT, BTA_AV_SIG_TIME_VAL);
1428 bdcpy(pend.bd_addr, p_lcb->addr);
1429 (*p_cb->p_cback)(BTA_AV_PENDING_EVT, (tBTA_AV *) &pend);
1430 }
1431 }
1432 }
1433 }
1434
1435 /*******************************************************************************
1436 **
1437 ** Function bta_av_acp_sig_timer_cback
1438 **
1439 ** Description Process the timeout when SRC is accepting connection
1440 ** and SNK did not start signalling.
1441 **
1442 ** Returns void
1443 **
1444 *******************************************************************************/
bta_av_acp_sig_timer_cback(TIMER_LIST_ENT * p_tle)1445 static void bta_av_acp_sig_timer_cback (TIMER_LIST_ENT *p_tle)
1446 {
1447 UINT8 inx = (UINT8)p_tle->param;
1448 tBTA_AV_CB *p_cb = &bta_av_cb;
1449 tBTA_AV_SCB *p_scb = NULL;
1450 tBTA_AV_API_OPEN *p_buf;
1451 if (inx < BTA_AV_NUM_STRS) {
1452 p_scb = p_cb->p_scb[inx];
1453 }
1454 if (p_scb) {
1455 APPL_TRACE_DEBUG("bta_av_acp_sig_timer_cback, coll_mask = 0x%02X", p_scb->coll_mask);
1456
1457 if (p_scb->coll_mask & BTA_AV_COLL_INC_TMR) {
1458 p_scb->coll_mask &= ~BTA_AV_COLL_INC_TMR;
1459
1460 if (bta_av_is_scb_opening(p_scb)) {
1461 if (p_scb->p_disc_db) {
1462 /* We are still doing SDP. Run the timer again. */
1463 p_scb->coll_mask |= BTA_AV_COLL_INC_TMR;
1464
1465 p_cb->acp_sig_tmr.param = (UINT32)inx;
1466 p_cb->acp_sig_tmr.p_cback = (TIMER_CBACK *)&bta_av_acp_sig_timer_cback;
1467 bta_sys_start_timer(&p_cb->acp_sig_tmr, 0, BTA_AV_ACP_SIG_TIME_VAL);
1468 } else {
1469 /* SNK did not start signalling, resume signalling process. */
1470 bta_av_discover_req (p_scb, NULL);
1471 }
1472 } else if (bta_av_is_scb_incoming(p_scb)) {
1473 /* Stay in incoming state if SNK does not start signalling */
1474
1475 /* API open was called right after SNK opened L2C connection. */
1476 if (p_scb->coll_mask & BTA_AV_COLL_API_CALLED) {
1477 p_scb->coll_mask &= ~BTA_AV_COLL_API_CALLED;
1478
1479 /* BTA_AV_API_OPEN_EVT */
1480 if ((p_buf = (tBTA_AV_API_OPEN *) osi_malloc(sizeof(tBTA_AV_API_OPEN))) != NULL) {
1481 memcpy(p_buf, &(p_scb->open_api), sizeof(tBTA_AV_API_OPEN));
1482 bta_sys_sendmsg(p_buf);
1483 }
1484 }
1485 }
1486 }
1487 }
1488 }
1489
1490 /*******************************************************************************
1491 **
1492 ** Function bta_av_check_peer_rc_features
1493 **
1494 ** Description check supported AVRC features on the peer device from the SDP
1495 ** record and return the feature mask
1496 **
1497 ** Returns tBTA_AV_FEAT peer device feature mask
1498 **
1499 *******************************************************************************/
bta_av_check_peer_rc_features(UINT16 service_uuid,UINT16 * rc_features)1500 tBTA_AV_FEAT bta_av_check_peer_rc_features (UINT16 service_uuid, UINT16 *rc_features)
1501 {
1502 tBTA_AV_FEAT peer_features = 0;
1503 tBTA_AV_CB *p_cb = &bta_av_cb;
1504 tSDP_DISC_REC *p_rec = NULL;
1505 tSDP_DISC_ATTR *p_attr;
1506 UINT16 peer_rc_version = 0;
1507 UINT16 categories = 0;
1508
1509 APPL_TRACE_DEBUG("bta_av_check_peer_rc features service_uuid:x%x", service_uuid);
1510 /* loop through all records we found */
1511 while (TRUE) {
1512 /* get next record; if none found, we're done */
1513 if ((p_rec = SDP_FindServiceInDb(p_cb->p_disc_db, service_uuid, p_rec)) == NULL) {
1514 break;
1515 }
1516
1517 if (( SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_CLASS_ID_LIST)) != NULL) {
1518 /* find peer features */
1519 if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL)) {
1520 peer_features |= BTA_AV_FEAT_RCCT;
1521 }
1522 if (SDP_FindServiceInDb(p_cb->p_disc_db, UUID_SERVCLASS_AV_REM_CTRL_TARGET, NULL)) {
1523 peer_features |= BTA_AV_FEAT_RCTG;
1524 }
1525 }
1526
1527 if (( SDP_FindAttributeInRec(p_rec, ATTR_ID_BT_PROFILE_DESC_LIST)) != NULL) {
1528 /* get profile version (if failure, version parameter is not updated) */
1529 SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_rc_version);
1530 APPL_TRACE_DEBUG("peer_rc_version 0x%x", peer_rc_version);
1531
1532 if (peer_rc_version >= AVRC_REV_1_3) {
1533 peer_features |= (BTA_AV_FEAT_VENDOR | BTA_AV_FEAT_METADATA);
1534 }
1535
1536 if (peer_rc_version >= AVRC_REV_1_4) {
1537 peer_features |= (BTA_AV_FEAT_ADV_CTRL);
1538 /* get supported categories */
1539 if ((p_attr = SDP_FindAttributeInRec(p_rec,
1540 ATTR_ID_SUPPORTED_FEATURES)) != NULL) {
1541 categories = p_attr->attr_value.v.u16;
1542 if (categories & AVRC_SUPF_CT_BROWSE) {
1543 peer_features |= (BTA_AV_FEAT_BROWSE);
1544 }
1545 }
1546 }
1547 }
1548 }
1549
1550 if (rc_features) {
1551 *rc_features = categories;
1552 }
1553
1554 APPL_TRACE_DEBUG("peer_features:x%x, rc:x%x", peer_features, categories);
1555 return peer_features;
1556 }
1557
1558 /*******************************************************************************
1559 **
1560 ** Function bta_av_rc_disc_done
1561 **
1562 ** Description Handle AVRCP service discovery results. If matching
1563 ** service found, open AVRCP connection.
1564 **
1565 ** Returns void
1566 **
1567 *******************************************************************************/
bta_av_rc_disc_done(tBTA_AV_DATA * p_data)1568 void bta_av_rc_disc_done(tBTA_AV_DATA *p_data)
1569 {
1570 tBTA_AV_CB *p_cb = &bta_av_cb;
1571 tBTA_AV_SCB *p_scb = NULL;
1572 tBTA_AV_LCB *p_lcb;
1573 tBTA_AV_RC_OPEN rc_open;
1574 tBTA_AV_RC_FEAT rc_feat;
1575 UINT8 rc_handle;
1576 tBTA_AV_FEAT peer_features; /* peer features mask */
1577 UINT16 peer_ct_features; /* peer features mask as controller */
1578 UINT16 peer_tg_features; /* peer features mask as target */
1579 UNUSED(p_data);
1580
1581 APPL_TRACE_DEBUG("bta_av_rc_disc_done disc:x%x", p_cb->disc);
1582 if (!p_cb->disc) {
1583 return;
1584 }
1585
1586 if ((p_cb->disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) {
1587 /* this is the rc handle/index to tBTA_AV_RCB */
1588 rc_handle = p_cb->disc & (~BTA_AV_CHNL_MSK);
1589 } else {
1590 /* Validate array index*/
1591 if (((p_cb->disc & BTA_AV_HNDL_MSK) - 1) < BTA_AV_NUM_STRS) {
1592 p_scb = p_cb->p_scb[(p_cb->disc & BTA_AV_HNDL_MSK) - 1];
1593 }
1594 if (p_scb) {
1595 rc_handle = p_scb->rc_handle;
1596 } else {
1597 p_cb->disc = 0;
1598 return;
1599 }
1600 }
1601
1602 APPL_TRACE_DEBUG("rc_handle %d", rc_handle);
1603 /* check peer version and whether support CT and TG role */
1604 peer_features = bta_av_check_peer_rc_features (UUID_SERVCLASS_AV_REMOTE_CONTROL, &peer_ct_features);
1605 peer_features |= bta_av_check_peer_rc_features (UUID_SERVCLASS_AV_REM_CTRL_TARGET, &peer_tg_features);
1606
1607 p_cb->disc = 0;
1608 utl_freebuf((void **) &p_cb->p_disc_db);
1609
1610 APPL_TRACE_DEBUG("peer_features 0x%x, local features 0x%x", peer_features, p_cb->features);
1611
1612 /* if we have no rc connection */
1613 if (rc_handle == BTA_AV_RC_HANDLE_NONE) {
1614 if (p_scb) {
1615 /* if peer remote control service matches ours and USE_RC is TRUE */
1616 if ((((p_cb->features & BTA_AV_FEAT_RCCT) && (peer_features & BTA_AV_FEAT_RCTG)) ||
1617 ((p_cb->features & BTA_AV_FEAT_RCTG) && (peer_features & BTA_AV_FEAT_RCCT))) ) {
1618 p_lcb = bta_av_find_lcb(p_scb->peer_addr, BTA_AV_LCB_FIND);
1619 if (p_lcb) {
1620 rc_handle = bta_av_rc_create(p_cb, AVCT_INT, (UINT8)(p_scb->hdi + 1), p_lcb->lidx);
1621 p_cb->rcb[rc_handle].peer_features = peer_features;
1622 p_cb->rcb[rc_handle].peer_ct_features = peer_ct_features;
1623 p_cb->rcb[rc_handle].peer_tg_features = peer_tg_features;
1624 }
1625 #if (BT_USE_TRACES == TRUE || BT_TRACE_APPL == TRUE)
1626 else {
1627 APPL_TRACE_ERROR("can not find LCB!!");
1628 }
1629 #endif
1630 } else if (p_scb->use_rc) {
1631 /* can not find AVRC on peer device. report failure */
1632 p_scb->use_rc = FALSE;
1633 bdcpy(rc_open.peer_addr, p_scb->peer_addr);
1634 rc_open.peer_features = 0;
1635 rc_open.sdp_disc_done = FALSE;
1636 rc_open.status = BTA_AV_FAIL_SDP;
1637 (*p_cb->p_cback)(BTA_AV_RC_OPEN_EVT, (tBTA_AV *) &rc_open);
1638 }
1639 }
1640 } else {
1641 p_cb->rcb[rc_handle].peer_features = peer_features;
1642 rc_feat.rc_handle = rc_handle;
1643 rc_feat.peer_features = peer_features;
1644 rc_feat.peer_ct_features = peer_ct_features;
1645 rc_feat.peer_tg_features = peer_tg_features;
1646 (*p_cb->p_cback)(BTA_AV_RC_FEAT_EVT, (tBTA_AV *) &rc_feat);
1647 }
1648 }
1649
1650 /*******************************************************************************
1651 **
1652 ** Function bta_av_rc_closed
1653 **
1654 ** Description Set AVRCP state to closed.
1655 **
1656 ** Returns void
1657 **
1658 *******************************************************************************/
bta_av_rc_closed(tBTA_AV_DATA * p_data)1659 void bta_av_rc_closed(tBTA_AV_DATA *p_data)
1660 {
1661 tBTA_AV_CB *p_cb = &bta_av_cb;
1662 tBTA_AV_RC_CLOSE rc_close;
1663 tBTA_AV_RC_CONN_CHG *p_msg = (tBTA_AV_RC_CONN_CHG *)p_data;
1664 tBTA_AV_RCB *p_rcb;
1665 tBTA_AV_SCB *p_scb;
1666 int i;
1667 BOOLEAN conn = FALSE;
1668 tBTA_AV_LCB *p_lcb;
1669
1670 rc_close.rc_handle = BTA_AV_RC_HANDLE_NONE;
1671 p_scb = NULL;
1672 APPL_TRACE_DEBUG("bta_av_rc_closed rc_handle:%d", p_msg->handle);
1673 for (i = 0; i < BTA_AV_NUM_RCB; i++) {
1674 p_rcb = &p_cb->rcb[i];
1675 APPL_TRACE_DEBUG("bta_av_rc_closed rcb[%d] rc_handle:%d, status=0x%x", i, p_rcb->handle, p_rcb->status);
1676 if (p_rcb->handle == p_msg->handle) {
1677 rc_close.rc_handle = i;
1678 p_rcb->status &= ~BTA_AV_RC_CONN_MASK;
1679 p_rcb->peer_features = 0;
1680 p_rcb->peer_ct_features = 0;
1681 p_rcb->peer_tg_features = 0;
1682 APPL_TRACE_DEBUG(" shdl:%d, lidx:%d", p_rcb->shdl, p_rcb->lidx);
1683 if (p_rcb->shdl) {
1684 if ((p_rcb->shdl - 1) < BTA_AV_NUM_STRS) {
1685 p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
1686 }
1687 if (p_scb) {
1688 bdcpy(rc_close.peer_addr, p_scb->peer_addr);
1689 if (p_scb->rc_handle == p_rcb->handle) {
1690 p_scb->rc_handle = BTA_AV_RC_HANDLE_NONE;
1691 }
1692 APPL_TRACE_DEBUG("shdl:%d, srch:%d", p_rcb->shdl, p_scb->rc_handle);
1693 }
1694 p_rcb->shdl = 0;
1695 } else if (p_rcb->lidx == (BTA_AV_NUM_LINKS + 1) ) {
1696 /* if the RCB uses the extra LCB, use the addr for event and clean it */
1697 p_lcb = &p_cb->lcb[BTA_AV_NUM_LINKS];
1698 bdcpy(rc_close.peer_addr, p_msg->peer_addr);
1699 APPL_TRACE_DEBUG("rc_only closed bd_addr:%02x-%02x-%02x-%02x-%02x-%02x",
1700 p_msg->peer_addr[0], p_msg->peer_addr[1],
1701 p_msg->peer_addr[2], p_msg->peer_addr[3],
1702 p_msg->peer_addr[4], p_msg->peer_addr[5]);
1703 p_lcb->conn_msk = 0;
1704 p_lcb->lidx = 0;
1705 }
1706 p_rcb->lidx = 0;
1707
1708 if ((p_rcb->status & BTA_AV_RC_ROLE_MASK) == BTA_AV_RC_ROLE_INT) {
1709 /* AVCT CCB is deallocated */
1710 p_rcb->handle = BTA_AV_RC_HANDLE_NONE;
1711 p_rcb->status = 0;
1712 } else {
1713 /* AVCT CCB is still there. dealloc */
1714 bta_av_del_rc(p_rcb);
1715
1716 /* if the AVRCP is no longer listening, create the listening channel */
1717 if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG) {
1718 bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
1719 }
1720 }
1721 } else if ((p_rcb->handle != BTA_AV_RC_HANDLE_NONE) && (p_rcb->status & BTA_AV_RC_CONN_MASK)) {
1722 /* at least one channel is still connected */
1723 conn = TRUE;
1724 }
1725 }
1726
1727 if (!conn) {
1728 /* no AVRC channels are connected, go back to INIT state */
1729 bta_av_sm_execute(p_cb, BTA_AV_AVRC_NONE_EVT, NULL);
1730 }
1731
1732 if (rc_close.rc_handle == BTA_AV_RC_HANDLE_NONE) {
1733 rc_close.rc_handle = p_msg->handle;
1734 bdcpy(rc_close.peer_addr, p_msg->peer_addr);
1735 }
1736 (*p_cb->p_cback)(BTA_AV_RC_CLOSE_EVT, (tBTA_AV *) &rc_close);
1737 }
1738
1739 /*******************************************************************************
1740 **
1741 ** Function bta_av_rc_disc
1742 **
1743 ** Description start AVRC SDP discovery.
1744 **
1745 ** Returns void
1746 **
1747 *******************************************************************************/
bta_av_rc_disc(UINT8 disc)1748 void bta_av_rc_disc(UINT8 disc)
1749 {
1750 tBTA_AV_CB *p_cb = &bta_av_cb;
1751 tAVRC_SDP_DB_PARAMS db_params;
1752 UINT16 attr_list[] = {ATTR_ID_SERVICE_CLASS_ID_LIST,
1753 ATTR_ID_BT_PROFILE_DESC_LIST,
1754 ATTR_ID_SUPPORTED_FEATURES
1755 };
1756 UINT8 hdi;
1757 tBTA_AV_SCB *p_scb;
1758 UINT8 *p_addr = NULL;
1759 UINT8 rc_handle;
1760
1761 APPL_TRACE_DEBUG("bta_av_rc_disc 0x%x, %d", disc, bta_av_cb.disc);
1762 if ((bta_av_cb.disc != 0) || (disc == 0)) {
1763 return;
1764 }
1765
1766 if ((disc & BTA_AV_CHNL_MSK) == BTA_AV_CHNL_MSK) {
1767 /* this is the rc handle/index to tBTA_AV_RCB */
1768 rc_handle = disc & (~BTA_AV_CHNL_MSK);
1769 if (p_cb->rcb[rc_handle].lidx) {
1770 p_addr = p_cb->lcb[p_cb->rcb[rc_handle].lidx - 1].addr;
1771 }
1772 } else {
1773 hdi = (disc & BTA_AV_HNDL_MSK) - 1;
1774 p_scb = p_cb->p_scb[hdi];
1775
1776 if (p_scb) {
1777 APPL_TRACE_DEBUG("rc_handle %d", p_scb->rc_handle);
1778 p_addr = p_scb->peer_addr;
1779 }
1780 }
1781
1782 if (p_addr) {
1783 /* allocate discovery database */
1784 if (p_cb->p_disc_db == NULL) {
1785 p_cb->p_disc_db = (tSDP_DISCOVERY_DB *) osi_malloc(BTA_AV_DISC_BUF_SIZE);
1786 }
1787
1788 if (p_cb->p_disc_db) {
1789 /* set up parameters */
1790 db_params.db_len = BTA_AV_DISC_BUF_SIZE;
1791 db_params.num_attr = 3;
1792 db_params.p_db = p_cb->p_disc_db;
1793 db_params.p_attrs = attr_list;
1794
1795 /* searching for UUID_SERVCLASS_AV_REMOTE_CONTROL gets both TG and CT */
1796 if (AVRC_FindService(UUID_SERVCLASS_AV_REMOTE_CONTROL, p_addr, &db_params,
1797 bta_av_avrc_sdp_cback) == AVRC_SUCCESS) {
1798 p_cb->disc = disc;
1799 APPL_TRACE_DEBUG("disc %d", p_cb->disc);
1800 }
1801 }
1802 }
1803 }
1804
1805 /*******************************************************************************
1806 **
1807 ** Function bta_av_dereg_comp
1808 **
1809 ** Description deregister complete. free the stream control block.
1810 **
1811 ** Returns void
1812 **
1813 *******************************************************************************/
bta_av_dereg_comp(tBTA_AV_DATA * p_data)1814 void bta_av_dereg_comp(tBTA_AV_DATA *p_data)
1815 {
1816 tBTA_AV_CB *p_cb = &bta_av_cb;
1817 tBTA_AV_SCB *p_scb;
1818 tBTA_UTL_COD cod;
1819 UINT8 mask;
1820 BT_HDR *p_buf;
1821
1822 /* find the stream control block */
1823 p_scb = bta_av_hndl_to_scb(p_data->hdr.layer_specific);
1824
1825 if (p_scb) {
1826 APPL_TRACE_DEBUG("deregistered %d(h%d)", p_scb->chnl, p_scb->hndl);
1827 mask = BTA_AV_HNDL_TO_MSK(p_scb->hdi);
1828 if (p_scb->chnl == BTA_AV_CHNL_AUDIO) {
1829 p_cb->reg_audio &= ~mask;
1830 if ((p_cb->conn_audio & mask) && bta_av_cb.audio_open_cnt) {
1831 /* this channel is still marked as open. decrease the count */
1832 bta_av_cb.audio_open_cnt--;
1833 }
1834 p_cb->conn_audio &= ~mask;
1835
1836 if (p_scb->q_tag == BTA_AV_Q_TAG_STREAM && p_scb->a2d_list) {
1837 /* make sure no buffers are in a2d_list */
1838 while (!list_is_empty(p_scb->a2d_list)) {
1839 p_buf = (BT_HDR *)list_front(p_scb->a2d_list);
1840 list_remove(p_scb->a2d_list, p_buf);
1841 osi_free(p_buf);
1842 }
1843 }
1844
1845 /* remove the A2DP SDP record, if no more audio stream is left */
1846 if (!p_cb->reg_audio) {
1847 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
1848 bta_ar_dereg_avrc (UUID_SERVCLASS_AV_REMOTE_CONTROL, BTA_ID_AV);
1849 #endif
1850 bta_av_del_sdp_rec(&p_cb->sdp_a2d_handle);
1851 bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SOURCE);
1852
1853 #if (BTA_AV_SINK_INCLUDED == TRUE)
1854 bta_av_del_sdp_rec(&p_cb->sdp_a2d_snk_handle);
1855 bta_sys_remove_uuid(UUID_SERVCLASS_AUDIO_SINK);
1856 #endif
1857 }
1858 } else {
1859 p_cb->reg_video &= ~mask;
1860 /* make sure that this channel is not connected */
1861 p_cb->conn_video &= ~mask;
1862 /* remove the VDP SDP record, (only one video stream at most) */
1863 bta_av_del_sdp_rec(&p_cb->sdp_vdp_handle);
1864 bta_sys_remove_uuid(UUID_SERVCLASS_VIDEO_SOURCE);
1865 }
1866
1867 /* make sure that the timer is not active */
1868 bta_sys_stop_timer(&p_scb->timer);
1869 list_free(p_scb->a2d_list);
1870 p_scb->a2d_list = NULL;
1871 utl_freebuf((void **)&p_cb->p_scb[p_scb->hdi]);
1872 }
1873
1874 APPL_TRACE_DEBUG("audio 0x%x, video: 0x%x, disable:%d",
1875 p_cb->reg_audio, p_cb->reg_video, p_cb->disabling);
1876 /* if no stream control block is active */
1877 if ((p_cb->reg_audio + p_cb->reg_video) == 0) {
1878 #if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
1879 /* deregister from AVDT */
1880 bta_ar_dereg_avdt(BTA_ID_AV);
1881
1882 /* deregister from AVCT */
1883 bta_ar_dereg_avrc (UUID_SERVCLASS_AV_REM_CTRL_TARGET, BTA_ID_AV);
1884 bta_ar_dereg_avct(BTA_ID_AV);
1885 #endif
1886
1887 if (p_cb->disabling) {
1888 p_cb->disabling = FALSE;
1889 bta_av_cb.features = 0;
1890 }
1891
1892 /* Clear the Capturing/Rendering service class bit */
1893 if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
1894 cod.service = BTM_COD_SERVICE_CAPTURING | BTM_COD_SERVICE_AUDIO;
1895 } else {
1896 #if (BTA_AV_SINK_INCLUDED == TRUE)
1897 cod.service = BTM_COD_SERVICE_RENDERING | BTM_COD_SERVICE_AUDIO;
1898 #endif
1899 }
1900 utl_set_device_class(&cod, BTA_UTL_CLR_COD_SERVICE_CLASS);
1901 }
1902 }
1903 #endif /* BTA_AV_INCLUDED */
1904