OSDN Git Service

Misc AV changes in stack
authorSumit Bajpai <sbajpai@codeaurora.org>
Tue, 14 Jun 2016 09:55:37 +0000 (15:25 +0530)
committerLinux Build Service Account <lnxbuild@localhost>
Wed, 24 Aug 2016 14:09:51 +0000 (08:09 -0600)
1) Update UI on remote's browsing support.
2) Avoid sending get capability request if Avrcp TG.
3) Use Interop database for Abs vol.
4) Add 30msec uinput delay upon creation.
5) Role switch failure handling.
6) Misc A2dp/Avrcp handling.

CRs-Fixed: 1029888
Change-Id: I2e86285da9e9a0b7c5180fbefeb7665f62ac77cd

bta/av/bta_av_act.c
bta/av/bta_av_cfg.c
bta/av/bta_av_main.c
btif/src/btif_av.c
btif/src/btif_rc.c
stack/avct/avct_l2c.c
stack/avrc/avrc_api.c
stack/avrc/avrc_bld_tg.c

index 6138bc9..d80128d 100644 (file)
@@ -2279,10 +2279,6 @@ void bta_av_rc_closed(tBTA_AV_DATA *p_data)
             {
                 /* AVCT CCB is still there. dealloc */
                 bta_av_del_rc(p_rcb);
-
-                /* if the AVRCP is no longer listening, create the listening channel */
-                if (bta_av_cb.rc_acp_handle == BTA_AV_RC_HANDLE_NONE && bta_av_cb.features & BTA_AV_FEAT_RCTG)
-                    bta_av_rc_create(&bta_av_cb, AVCT_ACP, 0, BTA_AV_NUM_LINKS + 1);
             }
         }
         else if ((p_rcb->handle != BTA_AV_RC_HANDLE_NONE) && (p_rcb->status & BTA_AV_RC_CONN_MASK))
index fcfebad..0c3011b 100644 (file)
@@ -41,6 +41,8 @@ const UINT32  bta_av_meta_caps_co_ids[] = {
 
 /* AVRCP cupported categories */
 #if (AVRC_CTLR_INCLUDED == TRUE)
+#define BTA_AV_RC_SUPF_CT       (AVRC_SUPF_CT_CAT1 | AVRC_SUPF_CT_CAT2)
+#else
 #define BTA_AV_RC_SUPF_CT       (AVRC_SUPF_CT_CAT2)
 #endif
 
index c37271f..3fafca7 100644 (file)
@@ -1139,6 +1139,7 @@ BOOLEAN bta_av_switch_if_needed(tBTA_AV_SCB *p_scb)
     UINT8 role;
     BOOLEAN needed = FALSE;
     tBTA_AV_SCB *p_scbi;
+    tBTM_STATUS ret;
     int i;
     UINT8       mask;
 
@@ -1156,7 +1157,11 @@ BOOLEAN bta_av_switch_if_needed(tBTA_AV_SCB *p_scb)
             {
                 if (bta_av_cb.features & BTA_AV_FEAT_MASTER)
                     bta_sys_clear_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_scbi->peer_addr);
-                if (BTM_CMD_STARTED != BTM_SwitchRole(p_scbi->peer_addr, BTM_ROLE_MASTER, NULL))
+                ret = BTM_SwitchRole(p_scbi->peer_addr, BTM_ROLE_MASTER, NULL);
+                if (ret == BTM_REPEATED_ATTEMPTS)
+                    return FALSE;
+
+                if (BTM_CMD_STARTED != ret)
                 {
                     /* can not switch role on SCBI
                      * start the timer on SCB - because this function is ONLY called when SCB gets API_OPEN */
@@ -1188,18 +1193,26 @@ BOOLEAN bta_av_link_role_ok(tBTA_AV_SCB *p_scb, UINT8 bits)
 {
     UINT8 role;
     BOOLEAN is_ok = TRUE;
+    tBTM_STATUS ret;
 
     if (BTM_GetRole(p_scb->peer_addr, &role) == BTM_SUCCESS)
     {
-        LOG_INFO(LOG_TAG, "%s hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x",
+        LOG_INFO("%s hndl:x%x role:%d conn_audio:x%x bits:%d features:x%x",
                 __func__, p_scb->hndl, role, bta_av_cb.conn_audio, bits,
                 bta_av_cb.features);
         if (BTM_ROLE_MASTER != role && (A2D_BitsSet(bta_av_cb.conn_audio) > bits || (bta_av_cb.features & BTA_AV_FEAT_MASTER)))
         {
             if (bta_av_cb.features & BTA_AV_FEAT_MASTER)
                 bta_sys_clear_policy(BTA_ID_AV, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_scb->peer_addr);
-
-            if (BTM_CMD_STARTED != BTM_SwitchRole(p_scb->peer_addr, BTM_ROLE_MASTER, NULL))
+            ret = BTM_SwitchRole(p_scb->peer_addr, BTM_ROLE_MASTER, NULL);
+            /* We have already reached maximum attempts,
+             * If we try again it will anyways fail
+             * return from here
+             * */
+            if (ret == BTM_REPEATED_ATTEMPTS)
+                return TRUE;
+
+            if (BTM_CMD_STARTED != ret)
             {
                 /* can not switch role on SCB - start the timer on SCB */
             }
index 437a2ba..1f526d2 100644 (file)
@@ -599,6 +599,8 @@ static BOOLEAN btif_av_state_idle_handler(btif_sm_event_t event, void *p_data, i
             else if ((btif_av_cb[index].peer_sep == AVDT_TSEP_SRC) &&
                     (p_bta_data->open.status == BTA_AV_SUCCESS))
             {
+                /* if queued PLAY command,  send it now */
+                btif_rc_check_handle_pending_play(p_bta_data->open.bd_addr, FALSE);
                 /* Bring up AVRCP connection too */
                 BTA_AvOpenRc(btif_av_cb[index].bta_handle);
             }
@@ -1652,13 +1654,13 @@ static void btif_av_handle_event(UINT16 event, char* p_param)
     switch (event)
     {
         case BTIF_AV_INIT_REQ_EVT:
-            BTIF_TRACE_DEBUG("%s: BTIF_AV_INIT_REQ_EVT", __FUNCTION__);
+            BTIF_TRACE_IMP("%s: BTIF_AV_INIT_REQ_EVT", __FUNCTION__);
             if(btif_a2dp_start_media_task())
                 btif_a2dp_on_init();
             break;
         /*events from Upper layer and Media Task*/
         case BTIF_AV_CLEANUP_REQ_EVT: /*Clean up to be called on default index*/
-            BTIF_TRACE_DEBUG("%s: BTIF_AV_CLEANUP_REQ_EVT", __FUNCTION__);
+            BTIF_TRACE_IMP("%s: BTIF_AV_CLEANUP_REQ_EVT", __FUNCTION__);
             uuid = (int)*p_param;
             if (uuid == BTA_A2DP_SOURCE_SERVICE_ID)
             {
@@ -2457,7 +2459,7 @@ static bt_status_t disconnect(bt_bdaddr_t *bd_addr)
 static void cleanup(int service_uuid)
 {
     int i;
-    BTIF_TRACE_EVENT("%s", __FUNCTION__);
+    BTIF_TRACE_IMP("AV %s", __FUNCTION__);
 
     btif_transfer_context(btif_av_handle_event, BTIF_AV_CLEANUP_REQ_EVT,
             (char*)&service_uuid, sizeof(int), NULL);
index b33f843..83eae05 100644 (file)
@@ -366,8 +366,10 @@ static void rc_start_play_status_timer(void);
 static bool absolute_volume_disabled(void);
 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label,
                                     int index);
+#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label,
                                     int index);
+#endif
 static bt_status_t set_addrplayer_rsp(btrc_status_t status_code, bt_bdaddr_t *bd_addr);
 static int btif_rc_get_idx_by_addr(BD_ADDR address);
 
@@ -394,7 +396,6 @@ static UINT8 btif_rc_get_idx_by_rc_handle(UINT8 rc_handle);
 ******************************************************************************/
 extern BOOLEAN btif_hf_call_terminated_recently();
 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
-
 extern void btif_get_latest_playing_device(BD_ADDR address); //get the Playing device address
 extern BOOLEAN btif_av_is_playing();
 extern BOOLEAN btif_av_is_device_connected(BD_ADDR address);
@@ -503,6 +504,8 @@ int uinput_create(char *name)
         close(fd);
         return -1;
     }
+    BTIF_TRACE_IMP("AVRCP: input device opened.. Delay 30 ms");
+    sleep_ms(30);
     return fd;
 }
 
@@ -604,9 +607,9 @@ void handle_rc_features(int index)
                          bdaddr_to_string(&avdtp_addr, addr1, sizeof(bdstr_t)),
                          bdaddr_to_string(&rc_addr, addr2, sizeof(bdstr_t)) );
 
-        //if (interop_match(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr)
-        if (absolute_volume_disabled()
-            || bdcmp(avdtp_addr.address, rc_addr.address))
+        if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr)
+                || absolute_volume_disabled()
+                || bdcmp(avdtp_addr.address, rc_addr.address))
             btif_rc_cb[index].rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
 
         if (btif_rc_cb[index].rc_features & BTA_AV_FEAT_BROWSE)
@@ -621,22 +624,20 @@ void handle_rc_features(int index)
         if (btif_rc_cb[index].rc_features & BTA_AV_FEAT_METADATA)
         {
             rc_features |= BTRC_FEAT_METADATA;
-            /* Mark rc features processed to avoid repeating
-             * the AVRCP procedure every time on receiving this
-             * update.
-             */
-            btif_rc_cb[index].rc_features_processed = TRUE;
-            getcapabilities_cmd (AVRC_CAP_COMPANY_ID);
         }
-        BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
+        if (btif_rc_cb[index].rc_features & BTA_AV_FEAT_AVRC_UI_UPDATE)
+        {
+            rc_features |= BTRC_FEAT_AVRC_UI_UPDATE;
+        }
+        BTIF_TRACE_IMP("%s: rc_features=0x%x", __FUNCTION__, rc_features);
         if (btif_rc_cb[index].rc_connected)
         {
-            BTIF_TRACE_DEBUG("%s: update App on supported features", __FUNCTION__);
+            BTIF_TRACE_IMP("%s: update App on supported features", __FUNCTION__);
             HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
         }
         else
         {
-            BTIF_TRACE_DEBUG("%s: skipping feature update to App", __FUNCTION__);
+            BTIF_TRACE_IMP("%s: skipping feature update to App", __FUNCTION__);
         }
 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
         BTIF_TRACE_DEBUG("Checking for feature flags in btif_rc_handler with label %d",
@@ -3555,6 +3556,7 @@ static bt_status_t get_itemattr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p
     UINT32 i;
     tAVRC_ATTR_ENTRY element_attrs[MAX_ELEM_ATTR_SIZE];
     int valid_attr, rc_index = btif_rc_get_idx_by_addr(bd_addr->address);
+    CHECK_RC_CONNECTED
 
     valid_attr = 0;
     if (rc_index == btif_max_rc_clients)
@@ -3563,7 +3565,7 @@ static bt_status_t get_itemattr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p
         return BT_STATUS_FAIL;
     }
     BTIF_TRACE_DEBUG("- %s on index = %d", __FUNCTION__, rc_index);
-    CHECK_RC_CONNECTED
+
     memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
 
     if (num_attr == 0)
index 674500d..2310390 100644 (file)
@@ -288,10 +288,10 @@ void avct_l2c_br_connect_ind_cback(BD_ADDR bd_addr, UINT16 lcid, UINT16 psm, UIN
             p_bcb->ch_lcid =   lcid;     /*Updadate LCID so that on config associated bcb could be found*/
             ertm_info.preferred_mode    = L2CAP_FCR_ERTM_MODE;
             ertm_info.allowed_modes     = L2CAP_FCR_CHAN_OPT_ERTM;
-            ertm_info.user_rx_buf_size   = 4096;//AVCT_BR_USER_RX_BUF_SIZE;
-            ertm_info.user_tx_buf_size   = 4096;//AVCT_BR_USER_TX_BUF_SIZE;
-            ertm_info.fcr_rx_buf_size    = 4096;//AVCT_BR_FCR_RX_BUF_SIZE;
-            ertm_info.fcr_tx_buf_size    = 4096;//AVCT_BR_FCR_TX_BUF_SIZE;
+            ertm_info.user_rx_buf_size   = AVCT_BR_USER_RX_BUF_SIZE;
+            ertm_info.user_tx_buf_size   = AVCT_BR_USER_TX_BUF_SIZE;
+            ertm_info.fcr_rx_buf_size    = AVCT_BR_FCR_RX_BUF_SIZE;
+            ertm_info.fcr_tx_buf_size    = AVCT_BR_FCR_TX_BUF_SIZE;
             p_ertm_info                 = &ertm_info;
             L2CA_ErtmConnectRsp (bd_addr, id, lcid, result, L2CAP_CONN_OK, p_ertm_info);
         }
index 7838823..ade3b85 100644 (file)
@@ -106,6 +106,29 @@ static UINT8 * avrc_get_data_ptr(BT_HDR *p_pkt)
 
 /******************************************************************************
 **
+** Function         avrc_get_packet_type
+**
+** Description      Gets a packet type for fragmanted packet.
+**
+** Returns          Type of fragmenatation packet.
+**
+******************************************************************************/
+static UINT8 avrc_get_packet_type(BT_HDR *pp_pkt)
+{
+    BT_HDR      *p_pkt = pp_pkt;
+    UINT8       *p_data;
+    UINT8       pkt_type;
+    p_data  = (UINT8 *)(p_pkt+1) + p_pkt->offset;
+    /* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */
+    p_data += AVRC_VENDOR_HDR_SIZE;
+
+    pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
+
+    return pkt_type;
+}
+
+/******************************************************************************
+**
 ** Function         avrc_copy_packet
 **
 ** Description      Copies an AVRC packet to a new buffer. In the new buffer,
@@ -236,6 +259,7 @@ static BT_HDR * avrc_proc_vendor_command(UINT8 handle, UINT8 label,
     UINT8       *p_data;
     UINT8       *p_begin;
     UINT8       pkt_type;
+    UINT8       *p_rsp_data;
     BOOLEAN     abort_frag = FALSE;
     tAVRC_STS   status = AVRC_STS_NO_ERROR;
     tAVRC_FRAG_CB   *p_fcb;
@@ -316,15 +340,15 @@ static BT_HDR * avrc_proc_vendor_command(UINT8 handle, UINT8 label,
 
     if (status != AVRC_STS_NO_ERROR)
     {
-        /* use the current GKI buffer to build/send the reject message */
-        p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
-        *p_data++ = AVRC_RSP_REJ;
-        p_data += AVRC_VENDOR_HDR_SIZE; /* pdu */
-        *p_data++ = 0;                  /* pkt_type */
-        UINT16_TO_BE_STREAM(p_data, 1); /* len */
-        *p_data++ = status;             /* error code */
-        p_pkt->len = AVRC_VENDOR_HDR_SIZE + 5;
-        p_rsp = p_pkt;
+        /* check for buffer size before modifing it */
+        p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_REJ_MSG_LEN);
+        p_rsp_data = avrc_get_data_ptr(p_rsp);
+        *p_rsp_data++ = AVRC_RSP_REJ;
+        p_rsp_data += AVRC_VENDOR_HDR_SIZE; /* pdu 1 byte*/
+        *p_rsp_data++ = 0;                  /* pkt_type  1 byte*/
+        UINT16_TO_BE_STREAM(p_rsp_data, 1); /* len 2 byte */
+        *p_rsp_data++ = status;             /* error code 1 byte*/
+        p_rsp->len = AVRC_VENDOR_HDR_SIZE + 5;
     }
 
     return p_rsp;
@@ -579,7 +603,7 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
             msg.hdr.subunit_id      = p_data[1] & AVRC_SUBID_MASK;
             opcode                  = p_data[2];
         }
-
+        AVRC_TRACE_DEBUG("opcode %d",opcode);
         if ( ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD)) ||
            ((avrc_cb.ccb[handle].control & AVRC_CT_CONTROL) && (cr == AVCT_RSP)) )
         {
@@ -672,6 +696,18 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
 
 #if (AVRC_METADATA_INCLUDED == TRUE)
                 UINT8 drop_code = 0;
+                if (p_msg->vendor_len > AVRC_META_CMD_BUF_SIZE)
+                {
+                    int packet_type = avrc_get_packet_type(p_pkt);
+                    AVRC_TRACE_DEBUG("packet_type %d", packet_type);
+                    //single packet size is greater then MTU size, reject it
+                    if (packet_type == AVRC_PKT_SINGLE)
+                    {
+                        AVRC_TRACE_ERROR("Incorrect lenght for single packet");
+                        reject = TRUE;
+                        break;
+                    }
+                }
                 drop_code = avrc_proc_far_msg(handle, label, cr, &p_pkt, p_msg);
                 if (drop_code > 0)
                     drop = TRUE;
@@ -786,7 +822,7 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
         opcode = p_data[0];
         AVRC_TRACE_DEBUG("opcode:%x, length:%x",opcode, p_pkt->len);
         /*Do sanity Check here*/
-        if (cr == AVCT_CMD)
+        if ((avrc_cb.ccb[handle].control & AVRC_CT_TARGET) && (cr == AVCT_CMD))
         {
             opcode  =  AVRC_OP_BROWSE;
             msg.browse.browse_len = p_pkt->len;
index 60a4cd3..5c184e7 100644 (file)
@@ -649,9 +649,6 @@ static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
             status = AVRC_STS_BAD_PARAM;
         break;
 
-    case AVRC_EVT_VOLUME_CHANGE:
-        len = 2;
-        UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume));
     case AVRC_EVT_AVAL_PLAYERS_CHANGE:
         len = EVT_AVAIL_PLAYER_CHANGE_RSP_LENGTH;
         break;
@@ -665,7 +662,10 @@ static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
     case AVRC_EVT_NOW_PLAYING_CHANGE:
         len = EVT_NOW_PLAYING_CHANGE_RSP_LENGTH;
         break;
-
+    case AVRC_EVT_VOLUME_CHANGE:
+        len = 2;
+        UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume));
+        break;
     default:
         status = AVRC_STS_BAD_PARAM;
         AVRC_TRACE_ERROR("%s unknown event_id", __func__);