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