Home | History | Annotate | Download | only in avrc
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2006-2013 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 #include <string.h>
     19 
     20 #include "avrc_api.h"
     21 #include "avrc_defs.h"
     22 #include "avrc_int.h"
     23 #include "bt_common.h"
     24 #include "bt_utils.h"
     25 #include "osi/include/osi.h"
     26 
     27 /*****************************************************************************
     28  *  Global data
     29  ****************************************************************************/
     30 
     31 #if (AVRC_METADATA_INCLUDED == TRUE)
     32 
     33 /*******************************************************************************
     34  *
     35  * Function         avrc_pars_vendor_rsp
     36  *
     37  * Description      This function parses the vendor specific commands defined by
     38  *                  Bluetooth SIG
     39  *
     40  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
     41  *                  successfully.
     42  *                  Otherwise, the error code defined by AVRCP 1.4
     43  *
     44  ******************************************************************************/
     45 static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
     46                                       tAVRC_RESPONSE* p_result) {
     47   tAVRC_STS status = AVRC_STS_NO_ERROR;
     48   uint8_t* p;
     49   uint16_t len;
     50 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
     51   uint8_t eventid = 0;
     52 #endif
     53 
     54   /* Check the vendor data */
     55   if (p_msg->vendor_len == 0) return AVRC_STS_NO_ERROR;
     56   if (p_msg->p_vendor_data == NULL) return AVRC_STS_INTERNAL_ERR;
     57 
     58   p = p_msg->p_vendor_data;
     59   BE_STREAM_TO_UINT8(p_result->pdu, p);
     60   p++; /* skip the reserved/packe_type byte */
     61   BE_STREAM_TO_UINT16(len, p);
     62   AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d/0x%x", __func__,
     63                    p_msg->hdr.ctype, p_result->pdu, len, len);
     64   if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
     65     p_result->rsp.status = *p;
     66     return p_result->rsp.status;
     67   }
     68 
     69   switch (p_result->pdu) {
     70 /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
     71 /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
     72 
     73 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
     74     case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
     75       if (len != 1)
     76         status = AVRC_STS_INTERNAL_ERR;
     77       else {
     78         BE_STREAM_TO_UINT8(p_result->volume.volume, p);
     79       }
     80       break;
     81 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
     82 
     83     case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
     84 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
     85       BE_STREAM_TO_UINT8(eventid, p);
     86       if (AVRC_EVT_VOLUME_CHANGE == eventid &&
     87           (AVRC_RSP_CHANGED == p_msg->hdr.ctype ||
     88            AVRC_RSP_INTERIM == p_msg->hdr.ctype ||
     89            AVRC_RSP_REJ == p_msg->hdr.ctype ||
     90            AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) {
     91         p_result->reg_notif.status = p_msg->hdr.ctype;
     92         p_result->reg_notif.event_id = eventid;
     93         BE_STREAM_TO_UINT8(p_result->reg_notif.param.volume, p);
     94       }
     95       AVRC_TRACE_DEBUG("%s PDU reg notif response:event %x, volume %x",
     96                        __func__, eventid, p_result->reg_notif.param.volume);
     97 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
     98       break;
     99     default:
    100       status = AVRC_STS_BAD_CMD;
    101       break;
    102   }
    103 
    104   return status;
    105 }
    106 
    107 void avrc_parse_notification_rsp(uint8_t* p_stream,
    108                                  tAVRC_REG_NOTIF_RSP* p_rsp) {
    109   BE_STREAM_TO_UINT8(p_rsp->event_id, p_stream);
    110   switch (p_rsp->event_id) {
    111     case AVRC_EVT_PLAY_STATUS_CHANGE:
    112       BE_STREAM_TO_UINT8(p_rsp->param.play_status, p_stream);
    113       break;
    114 
    115     case AVRC_EVT_TRACK_CHANGE:
    116       BE_STREAM_TO_ARRAY(p_stream, p_rsp->param.track, 8);
    117       break;
    118 
    119     case AVRC_EVT_APP_SETTING_CHANGE:
    120       BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream);
    121       for (int index = 0; index < p_rsp->param.player_setting.num_attr;
    122            index++) {
    123         BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index],
    124                            p_stream);
    125         BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_value[index],
    126                            p_stream);
    127       }
    128       break;
    129 
    130     case AVRC_EVT_NOW_PLAYING_CHANGE:
    131       break;
    132 
    133     case AVRC_EVT_AVAL_PLAYERS_CHANGE:
    134       break;
    135 
    136     case AVRC_EVT_ADDR_PLAYER_CHANGE:
    137       break;
    138 
    139     case AVRC_EVT_UIDS_CHANGE:
    140       break;
    141 
    142     case AVRC_EVT_TRACK_REACHED_END:
    143     case AVRC_EVT_TRACK_REACHED_START:
    144     case AVRC_EVT_PLAY_POS_CHANGED:
    145     case AVRC_EVT_BATTERY_STATUS_CHANGE:
    146     case AVRC_EVT_SYSTEM_STATUS_CHANGE:
    147     default:
    148       break;
    149   }
    150 }
    151 
    152 static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg,
    153                                       tAVRC_RESPONSE* p_rsp) {
    154   tAVRC_STS status = AVRC_STS_NO_ERROR;
    155   uint8_t pdu;
    156 
    157   if (p_msg->browse_len == 0) {
    158     AVRC_TRACE_ERROR("%s length ", p_msg->browse_len);
    159     return AVRC_STS_BAD_PARAM;
    160   }
    161 
    162   uint8_t* p = p_msg->p_browse_data;
    163 
    164   /* read the pdu */
    165   BE_STREAM_TO_UINT8(pdu, p);
    166   uint16_t pkt_len;
    167   /* read the entire packet len */
    168   BE_STREAM_TO_UINT16(pkt_len, p);
    169 
    170   AVRC_TRACE_DEBUG("%s pdu %d", __func__, pdu);
    171 
    172   /* used to track how much we have read, if we cannot read anymore but the
    173    * packet says so then we have a malformed packet. Also vice versa. */
    174   uint16_t pkt_len_read = 0;
    175 
    176   switch (pdu) {
    177     case AVRC_PDU_GET_FOLDER_ITEMS: {
    178       tAVRC_GET_ITEMS_RSP* get_item_rsp = &(p_rsp->get_items);
    179       /* Copy back the PDU */
    180       get_item_rsp->pdu = pdu;
    181       /* read the status */
    182       BE_STREAM_TO_UINT8(get_item_rsp->status, p);
    183       /* read the UID counter */
    184       BE_STREAM_TO_UINT16(get_item_rsp->uid_counter, p);
    185       /* read the number of items */
    186       BE_STREAM_TO_UINT16(get_item_rsp->item_count, p);
    187       pkt_len_read += 5;
    188 
    189       AVRC_TRACE_DEBUG(
    190           "%s pdu %d status %d pkt_len %d uid counter %d item count %d",
    191           __func__, get_item_rsp->pdu, get_item_rsp->status, pkt_len,
    192           get_item_rsp->uid_counter, get_item_rsp->item_count);
    193 
    194       if (get_item_rsp->status != AVRC_STS_NO_ERROR) {
    195         AVRC_TRACE_WARNING("%s returning error %d", __func__,
    196                            get_item_rsp->status);
    197         return get_item_rsp->status;
    198       }
    199 
    200       /* get each of the items */
    201       get_item_rsp->p_item_list = (tAVRC_ITEM*)osi_malloc(
    202           get_item_rsp->item_count * (sizeof(tAVRC_ITEM)));
    203       tAVRC_ITEM* curr_item = get_item_rsp->p_item_list;
    204       for (int i = 0; i < get_item_rsp->item_count; i++) {
    205         BE_STREAM_TO_UINT8(curr_item->item_type, p);
    206         pkt_len_read += 1;
    207         AVRC_TRACE_DEBUG("%s item type %d", __func__, curr_item->item_type);
    208         switch (curr_item->item_type) {
    209           case AVRC_ITEM_PLAYER: {
    210             /* Handle player */
    211             tAVRC_ITEM_PLAYER* player = &(curr_item->u.player);
    212             uint8_t player_len;
    213             BE_STREAM_TO_UINT16(player_len, p);
    214             BE_STREAM_TO_UINT16(player->player_id, p);
    215             BE_STREAM_TO_UINT8(player->major_type, p);
    216             BE_STREAM_TO_UINT32(player->sub_type, p);
    217             BE_STREAM_TO_UINT8(player->play_status, p);
    218             BE_STREAM_TO_ARRAY(p, player->features, AVRC_FEATURE_MASK_SIZE);
    219             pkt_len_read += (10 + AVRC_FEATURE_MASK_SIZE);
    220 
    221             /* read str */
    222             BE_STREAM_TO_UINT16(player->name.charset_id, p);
    223             BE_STREAM_TO_UINT16(player->name.str_len, p);
    224             player->name.p_str = (uint8_t*)osi_malloc(
    225                 (player->name.str_len + 1) * sizeof(uint8_t));
    226             BE_STREAM_TO_ARRAY(p, player->name.p_str, player->name.str_len);
    227             pkt_len_read += (4 + player->name.str_len);
    228             AVRC_TRACE_DEBUG(
    229                 "%s type %d id %d mtype %d stype %d ps %d cs %d name len %d",
    230                 __func__, curr_item->item_type, player->player_id,
    231                 player->major_type, player->sub_type, player->play_status,
    232                 player->name.charset_id, player->name.str_len);
    233           } break;
    234 
    235           case AVRC_ITEM_FOLDER: {
    236             tAVRC_ITEM_FOLDER* folder = &(curr_item->u.folder);
    237             uint16_t folder_len;
    238             BE_STREAM_TO_UINT16(folder_len, p);
    239 
    240             BE_STREAM_TO_ARRAY(p, folder->uid, AVRC_UID_SIZE);
    241             BE_STREAM_TO_UINT8(folder->type, p);
    242             BE_STREAM_TO_UINT8(folder->playable, p);
    243             pkt_len_read += (4 + AVRC_UID_SIZE);
    244 
    245             /* read str, encoding to be handled by upper layers */
    246             BE_STREAM_TO_UINT16(folder->name.charset_id, p);
    247             BE_STREAM_TO_UINT16(folder->name.str_len, p);
    248             folder->name.p_str = (uint8_t*)osi_malloc(
    249                 (folder->name.str_len + 1) * sizeof(uint8_t));
    250             BE_STREAM_TO_ARRAY(p, folder->name.p_str, folder->name.str_len);
    251             pkt_len_read += (4 + folder->name.str_len);
    252             AVRC_TRACE_DEBUG("%s type %d playable %d cs %d name len %d",
    253                              __func__, folder->type, folder->playable,
    254                              folder->name.charset_id, folder->name.str_len);
    255           } break;
    256 
    257           case AVRC_ITEM_MEDIA: {
    258             tAVRC_ITEM_MEDIA* media = &(curr_item->u.media);
    259             uint8_t media_len;
    260             BE_STREAM_TO_UINT16(media_len, p);
    261             BE_STREAM_TO_ARRAY(p, media->uid, AVRC_UID_SIZE);
    262             BE_STREAM_TO_UINT8(media->type, p);
    263             pkt_len_read += (3 + AVRC_UID_SIZE);
    264 
    265             /* read str, encoding to be handled by upper layers */
    266             BE_STREAM_TO_UINT16(media->name.charset_id, p);
    267             BE_STREAM_TO_UINT16(media->name.str_len, p);
    268             media->name.p_str =
    269                 (uint8_t*)osi_malloc((media->name.str_len) * sizeof(uint8_t));
    270             BE_STREAM_TO_ARRAY(p, media->name.p_str, media->name.str_len);
    271 
    272             BE_STREAM_TO_UINT8(media->attr_count, p);
    273             AVRC_TRACE_DEBUG("%s media type %d charset id %d len %d attr ct %d",
    274                              __func__, media->type, media->name.charset_id,
    275                              media->name.str_len, media->attr_count);
    276             pkt_len_read += (5 + media->name.str_len);
    277 
    278             media->p_attr_list = (tAVRC_ATTR_ENTRY*)osi_malloc(
    279                 media->attr_count * sizeof(tAVRC_ATTR_ENTRY));
    280             for (int jk = 0; jk < media->attr_count; jk++) {
    281               tAVRC_ATTR_ENTRY* attr_entry = &(media->p_attr_list[jk]);
    282               BE_STREAM_TO_UINT32(attr_entry->attr_id, p);
    283 
    284               /* Parse the name now */
    285               BE_STREAM_TO_UINT16(attr_entry->name.charset_id, p);
    286               BE_STREAM_TO_UINT16(attr_entry->name.str_len, p);
    287               attr_entry->name.p_str = (uint8_t*)osi_malloc(
    288                   attr_entry->name.str_len * sizeof(uint8_t));
    289               BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str,
    290                                  attr_entry->name.str_len);
    291               pkt_len_read += (8 + attr_entry->name.str_len);
    292               AVRC_TRACE_DEBUG("%s media attr id %d cs %d name len %d",
    293                                __func__, attr_entry->attr_id,
    294                                attr_entry->name.charset_id,
    295                                attr_entry->name.str_len);
    296             }
    297           } break;
    298 
    299           default:
    300             AVRC_TRACE_ERROR("%s item type not handled %d", __func__,
    301                              curr_item->item_type);
    302             return AVRC_STS_INTERNAL_ERR;
    303         }
    304 
    305         /* we check if we have overrun */
    306         if (pkt_len_read > pkt_len) {
    307           AVRC_TRACE_ERROR("%s overflow in read pkt_len %d pkt_len_read %d",
    308                            __func__, pkt_len, pkt_len_read);
    309           return AVRC_STS_BAD_CMD;
    310         }
    311         AVRC_TRACE_DEBUG("%s pkt_len %d pkt_len_read %d", __func__, pkt_len,
    312                          pkt_len_read);
    313 
    314         /* advance to populate the next item */
    315         curr_item++;
    316       }
    317       break;
    318     }
    319 
    320     case AVRC_PDU_CHANGE_PATH: {
    321       tAVRC_CHG_PATH_RSP* change_path_rsp = &(p_rsp->chg_path);
    322       /* Copyback the PDU */
    323       change_path_rsp->pdu = pdu;
    324       /* Read the status */
    325       BE_STREAM_TO_UINT8(change_path_rsp->status, p);
    326       /* Read the number of items in folder */
    327       BE_STREAM_TO_UINT32(change_path_rsp->num_items, p);
    328       pkt_len_read += 5;
    329 
    330       AVRC_TRACE_DEBUG("%s pdu %d status %d item count %d", __func__,
    331                        change_path_rsp->pdu, change_path_rsp->status,
    332                        change_path_rsp->num_items);
    333       break;
    334     }
    335 
    336     case AVRC_PDU_SET_BROWSED_PLAYER: {
    337       tAVRC_SET_BR_PLAYER_RSP* set_br_pl_rsp = &(p_rsp->br_player);
    338       /* Copyback the PDU */
    339       set_br_pl_rsp->pdu = pdu;
    340 
    341       /* Read the status */
    342       BE_STREAM_TO_UINT8(set_br_pl_rsp->status, p);
    343 
    344       if (set_br_pl_rsp->status != AVRC_STS_NO_ERROR) {
    345         AVRC_TRACE_ERROR(
    346             "%s Stopping further parsing because player not browsable sts %d",
    347             __func__, set_br_pl_rsp->status);
    348         break;
    349       }
    350       BE_STREAM_TO_UINT16(set_br_pl_rsp->uid_counter, p);
    351       BE_STREAM_TO_UINT32(set_br_pl_rsp->num_items, p);
    352       BE_STREAM_TO_UINT16(set_br_pl_rsp->charset_id, p);
    353       BE_STREAM_TO_UINT8(set_br_pl_rsp->folder_depth, p);
    354       AVRC_TRACE_DEBUG(
    355           "%s AVRC_PDU_SET_BROWSED_PLAYER status %d items %d cs %d depth %d",
    356           __func__, set_br_pl_rsp->status, set_br_pl_rsp->num_items,
    357           set_br_pl_rsp->charset_id, set_br_pl_rsp->folder_depth);
    358       pkt_len_read += 10;
    359 
    360       set_br_pl_rsp->p_folders = (tAVRC_NAME*)osi_malloc(
    361           set_br_pl_rsp->num_items * sizeof(tAVRC_NAME));
    362 
    363       /* Read each of the folder in the depth */
    364       for (uint32_t i = 0; i < set_br_pl_rsp->folder_depth; i++) {
    365         tAVRC_NAME* folder_name = &(set_br_pl_rsp->p_folders[i]);
    366         BE_STREAM_TO_UINT16(folder_name->str_len, p);
    367         AVRC_TRACE_DEBUG("%s AVRC_PDU_SET_BROWSED_PLAYER item: %d len: %d",
    368                          __func__, i, folder_name->str_len);
    369         folder_name->p_str =
    370             (uint8_t*)osi_malloc((folder_name->str_len + 1) * sizeof(uint8_t));
    371         BE_STREAM_TO_ARRAY(p, folder_name->p_str, folder_name->str_len);
    372         pkt_len_read += (2 + folder_name->str_len);
    373       }
    374       break;
    375     }
    376 
    377     default:
    378       AVRC_TRACE_ERROR("%s pdu %d not handled", __func__, pdu);
    379   }
    380 
    381   if (pkt_len != pkt_len_read) {
    382     AVRC_TRACE_ERROR("%s finished pkt_len %d pkt_len_read %d", __func__,
    383                      pkt_len, pkt_len_read);
    384     return AVRC_STS_BAD_CMD;
    385   }
    386   return status;
    387 }
    388 
    389 /*******************************************************************************
    390  *
    391  * Function         avrc_ctrl_pars_vendor_rsp
    392  *
    393  * Description      This function parses the vendor specific commands defined by
    394  *                  Bluetooth SIG
    395  *
    396  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
    397  *                  successfully.
    398  *                  Otherwise, the error code defined by AVRCP 1.4
    399  *
    400  ******************************************************************************/
    401 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
    402                                            tAVRC_RESPONSE* p_result,
    403                                            uint8_t* p_buf, uint16_t* buf_len) {
    404   uint8_t* p = p_msg->p_vendor_data;
    405   BE_STREAM_TO_UINT8(p_result->pdu, p);
    406   p++; /* skip the reserved/packe_type byte */
    407 
    408   uint16_t len;
    409   BE_STREAM_TO_UINT16(len, p);
    410   AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d", __func__, p_msg->hdr.ctype,
    411                    p_result->pdu, len);
    412   /* Todo: Issue in handling reject, check */
    413   if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
    414     p_result->rsp.status = *p;
    415     return p_result->rsp.status;
    416   }
    417 
    418   /* TODO: Break the big switch into functions. */
    419   switch (p_result->pdu) {
    420     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
    421     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
    422 
    423     case AVRC_PDU_REGISTER_NOTIFICATION:
    424       avrc_parse_notification_rsp(p, &p_result->reg_notif);
    425       break;
    426 
    427     case AVRC_PDU_GET_CAPABILITIES:
    428       if (len == 0) {
    429         p_result->get_caps.count = 0;
    430         p_result->get_caps.capability_id = 0;
    431         break;
    432       }
    433       BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
    434       BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
    435       AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ", __func__,
    436                        p_result->get_caps.capability_id,
    437                        p_result->get_caps.count);
    438       if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
    439         for (int xx = 0; ((xx < p_result->get_caps.count) &&
    440                           (xx < AVRC_CAP_MAX_NUM_COMP_ID));
    441              xx++) {
    442           BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
    443         }
    444       } else if (p_result->get_caps.capability_id ==
    445                  AVRC_CAP_EVENTS_SUPPORTED) {
    446         for (int xx = 0; ((xx < p_result->get_caps.count) &&
    447                           (xx < AVRC_CAP_MAX_NUM_EVT_ID));
    448              xx++) {
    449           BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
    450         }
    451       }
    452       break;
    453 
    454     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
    455       if (len == 0) {
    456         p_result->list_app_attr.num_attr = 0;
    457         break;
    458       }
    459       BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
    460       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
    461                        p_result->list_app_attr.num_attr);
    462       for (int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) {
    463         BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
    464       }
    465       break;
    466 
    467     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
    468       if (len == 0) {
    469         p_result->list_app_values.num_val = 0;
    470         break;
    471       }
    472       BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
    473       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
    474                        p_result->list_app_values.num_val);
    475       for (int xx = 0; xx < p_result->list_app_values.num_val; xx++) {
    476         BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
    477       }
    478       break;
    479 
    480     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: {
    481       if (len == 0) {
    482         p_result->get_cur_app_val.num_val = 0;
    483         break;
    484       }
    485       BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
    486       tAVRC_APP_SETTING* app_sett = (tAVRC_APP_SETTING*)osi_malloc(
    487           p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING));
    488       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
    489                        p_result->get_cur_app_val.num_val);
    490       for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) {
    491         BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
    492         BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
    493       }
    494       p_result->get_cur_app_val.p_vals = app_sett;
    495     } break;
    496 
    497     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: {
    498       tAVRC_APP_SETTING_TEXT* p_setting_text;
    499       uint8_t num_attrs;
    500 
    501       if (len == 0) {
    502         p_result->get_app_attr_txt.num_attr = 0;
    503         break;
    504       }
    505       BE_STREAM_TO_UINT8(num_attrs, p);
    506       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
    507                        p_result->get_app_attr_txt.num_attr);
    508       p_result->get_app_attr_txt.num_attr = num_attrs;
    509       p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
    510           num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
    511       for (int xx = 0; xx < num_attrs; xx++) {
    512         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
    513         BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id,
    514                             p);
    515         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
    516         if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0) {
    517           uint8_t* p_str = (uint8_t*)osi_malloc(
    518               p_result->get_app_attr_txt.p_attrs[xx].str_len);
    519           BE_STREAM_TO_ARRAY(p, p_str,
    520                              p_result->get_app_attr_txt.p_attrs[xx].str_len);
    521           p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
    522         } else {
    523           p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
    524         }
    525       }
    526     } break;
    527 
    528     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
    529       tAVRC_APP_SETTING_TEXT* p_setting_text;
    530       uint8_t num_vals;
    531 
    532       if (len == 0) {
    533         p_result->get_app_val_txt.num_attr = 0;
    534         break;
    535       }
    536       BE_STREAM_TO_UINT8(num_vals, p);
    537       p_result->get_app_val_txt.num_attr = num_vals;
    538       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
    539                        p_result->get_app_val_txt.num_attr);
    540 
    541       p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(
    542           num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
    543       for (int i = 0; i < num_vals; i++) {
    544         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
    545         BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
    546         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
    547         if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
    548           uint8_t* p_str = (uint8_t*)osi_malloc(
    549               p_result->get_app_val_txt.p_attrs[i].str_len);
    550           BE_STREAM_TO_ARRAY(p, p_str,
    551                              p_result->get_app_val_txt.p_attrs[i].str_len);
    552           p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
    553         } else {
    554           p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
    555         }
    556       }
    557     } break;
    558 
    559     case AVRC_PDU_SET_PLAYER_APP_VALUE:
    560       /* nothing comes as part of this rsp */
    561       break;
    562 
    563     case AVRC_PDU_GET_ELEMENT_ATTR: {
    564       uint8_t num_attrs;
    565 
    566       if (len <= 0) {
    567         p_result->get_attrs.num_attrs = 0;
    568         break;
    569       }
    570       BE_STREAM_TO_UINT8(num_attrs, p);
    571       p_result->get_attrs.num_attrs = num_attrs;
    572       if (num_attrs) {
    573         tAVRC_ATTR_ENTRY* p_attrs =
    574             (tAVRC_ATTR_ENTRY*)osi_malloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
    575         for (int i = 0; i < num_attrs; i++) {
    576           BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
    577           BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
    578           BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
    579           if (p_attrs[i].name.str_len > 0) {
    580             p_attrs[i].name.p_str =
    581                 (uint8_t*)osi_malloc(p_attrs[i].name.str_len);
    582             BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str,
    583                                p_attrs[i].name.str_len);
    584           }
    585         }
    586         p_result->get_attrs.p_attrs = p_attrs;
    587       }
    588     } break;
    589 
    590     case AVRC_PDU_GET_PLAY_STATUS:
    591       if (len == 0) {
    592         break;
    593       }
    594       BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
    595       BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
    596       BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
    597       break;
    598 
    599     case AVRC_PDU_SET_ADDRESSED_PLAYER:
    600       if (len != 1) {
    601         AVRC_TRACE_ERROR("%s pdu: %d len %d", __func__, p_result->pdu, len);
    602         return AVRC_STS_BAD_CMD;
    603       }
    604       BE_STREAM_TO_UINT8(p_result->rsp.status, p);
    605       break;
    606 
    607     default:
    608       return AVRC_STS_BAD_CMD;
    609   }
    610   return AVRC_STS_NO_ERROR;
    611 }
    612 
    613 /*******************************************************************************
    614  *
    615  * Function         AVRC_Ctrl_ParsResponse
    616  *
    617  * Description      This function is a parse response for AVRCP Controller.
    618  *
    619  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
    620  *                  successfully.
    621  *                  Otherwise, the error code defined by AVRCP 1.4
    622  *
    623  ******************************************************************************/
    624 tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
    625                                  uint8_t* p_buf, uint16_t* buf_len) {
    626   tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
    627   if (p_msg && p_result) {
    628     switch (p_msg->hdr.opcode) {
    629       case AVRC_OP_VENDOR: /*  0x00    Vendor-dependent commands */
    630         status =
    631             avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf, buf_len);
    632         break;
    633 
    634       case AVRC_OP_BROWSE: /* 0xff Browse commands */
    635         status = avrc_pars_browse_rsp(&p_msg->browse, p_result);
    636         break;
    637 
    638       default:
    639         AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
    640         break;
    641     }
    642     p_result->rsp.opcode = p_msg->hdr.opcode;
    643     p_result->rsp.status = status;
    644   }
    645   return status;
    646 }
    647 
    648 /*******************************************************************************
    649  *
    650  * Function         AVRC_ParsResponse
    651  *
    652  * Description      This function is a superset of AVRC_ParsMetadata to parse
    653  *                  the response.
    654  *
    655  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
    656  *                  successfully.
    657  *                  Otherwise, the error code defined by AVRCP 1.4
    658  *
    659  ******************************************************************************/
    660 tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
    661                             UNUSED_ATTR uint8_t* p_buf,
    662                             UNUSED_ATTR uint16_t buf_len) {
    663   tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
    664   uint16_t id;
    665 
    666   if (p_msg && p_result) {
    667     switch (p_msg->hdr.opcode) {
    668       case AVRC_OP_VENDOR: /*  0x00    Vendor-dependent commands */
    669         status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
    670         break;
    671 
    672       case AVRC_OP_PASS_THRU: /*  0x7C    panel subunit opcode */
    673         status = avrc_pars_pass_thru(&p_msg->pass, &id);
    674         if (status == AVRC_STS_NO_ERROR) {
    675           p_result->pdu = (uint8_t)id;
    676         }
    677         break;
    678 
    679       default:
    680         AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
    681         break;
    682     }
    683     p_result->rsp.opcode = p_msg->hdr.opcode;
    684     p_result->rsp.status = status;
    685   }
    686   return status;
    687 }
    688 #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
    689