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