Home | History | Annotate | Download | only in avrc
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-2016 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 <base/logging.h>
     19 #include <string.h>
     20 
     21 #include "avrc_api.h"
     22 #include "avrc_defs.h"
     23 #include "avrc_int.h"
     24 #include "bt_common.h"
     25 #include "bt_utils.h"
     26 #include "osi/include/osi.h"
     27 
     28 /*****************************************************************************
     29  *  Global data
     30  ****************************************************************************/
     31 #if (AVRC_METADATA_INCLUDED == TRUE)
     32 #define AVRC_ITEM_PLAYER_IS_VALID(_p_player)                 \
     33   ((_p_player)->name.p_str &&                                \
     34    ((_p_player)->major_type & AVRC_MJ_TYPE_INVALID) == 0 &&  \
     35    ((_p_player)->sub_type & AVRC_SUB_TYPE_INVALID) == 0 &&   \
     36    (((_p_player)->play_status <= AVRC_PLAYSTATE_REV_SEEK) || \
     37     ((_p_player)->play_status == AVRC_PLAYSTATE_ERROR)))
     38 
     39 /* 17 = item_type(1) + item len(2) + min item (14) */
     40 #define AVRC_MIN_LEN_GET_FOLDER_ITEMS_RSP 17
     41 
     42 /*******************************************************************************
     43  *
     44  * Function         avrc_bld_get_capability_rsp
     45  *
     46  * Description      This function builds the Get Capability response.
     47  *
     48  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
     49  *                  Otherwise, the error code.
     50  *
     51  ******************************************************************************/
     52 static tAVRC_STS avrc_bld_get_capability_rsp(tAVRC_GET_CAPS_RSP* p_rsp,
     53                                              BT_HDR* p_pkt) {
     54   uint8_t *p_data, *p_start, *p_len, *p_count;
     55   uint16_t len = 0;
     56   uint8_t xx;
     57   uint32_t* p_company_id;
     58   uint8_t* p_event_id;
     59   tAVRC_STS status = AVRC_STS_NO_ERROR;
     60 
     61   if (!(AVRC_IS_VALID_CAP_ID(p_rsp->capability_id))) {
     62     AVRC_TRACE_ERROR("%s bad parameter. p_rsp: %x", __func__, p_rsp);
     63     status = AVRC_STS_BAD_PARAM;
     64     return status;
     65   }
     66 
     67   AVRC_TRACE_API("%s", __func__);
     68   /* get the existing length, if any, and also the num attributes */
     69   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
     70   p_data = p_len = p_start + 2; /* pdu + rsvd */
     71 
     72   BE_STREAM_TO_UINT16(len, p_data);
     73   UINT8_TO_BE_STREAM(p_data, p_rsp->capability_id);
     74   p_count = p_data;
     75 
     76   if (len == 0) {
     77     *p_count = p_rsp->count;
     78     p_data++;
     79     len = 2; /* move past the capability_id and count */
     80   } else {
     81     p_data = p_start + p_pkt->len;
     82     *p_count += p_rsp->count;
     83   }
     84 
     85   if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
     86     p_company_id = p_rsp->param.company_id;
     87     for (xx = 0; xx < p_rsp->count; xx++) {
     88       UINT24_TO_BE_STREAM(p_data, p_company_id[xx]);
     89     }
     90     len += p_rsp->count * 3;
     91   } else {
     92     p_event_id = p_rsp->param.event_id;
     93     *p_count = 0;
     94     for (xx = 0; xx < p_rsp->count; xx++) {
     95       if (AVRC_IS_VALID_EVENT_ID(p_event_id[xx])) {
     96         (*p_count)++;
     97         UINT8_TO_BE_STREAM(p_data, p_event_id[xx]);
     98       }
     99     }
    100     len += (*p_count);
    101   }
    102   UINT16_TO_BE_STREAM(p_len, len);
    103   p_pkt->len = (p_data - p_start);
    104   status = AVRC_STS_NO_ERROR;
    105 
    106   return status;
    107 }
    108 
    109 /*******************************************************************************
    110  *
    111  * Function         avrc_bld_list_app_settings_attr_rsp
    112  *
    113  * Description      This function builds the List Application Settings Attribute
    114  *                  response.
    115  *
    116  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    117  *                  Otherwise, the error code.
    118  *
    119  ******************************************************************************/
    120 static tAVRC_STS avrc_bld_list_app_settings_attr_rsp(
    121     tAVRC_LIST_APP_ATTR_RSP* p_rsp, BT_HDR* p_pkt) {
    122   uint8_t *p_data, *p_start, *p_len, *p_num;
    123   uint16_t len = 0;
    124   uint8_t xx;
    125 
    126   AVRC_TRACE_API("%s", __func__);
    127   /* get the existing length, if any, and also the num attributes */
    128   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    129   p_data = p_len = p_start + 2; /* pdu + rsvd */
    130 
    131   BE_STREAM_TO_UINT16(len, p_data);
    132   p_num = p_data;
    133   if (len == 0) {
    134     /* first time initialize the attribute count */
    135     *p_num = 0;
    136     p_data++;
    137   } else {
    138     p_data = p_start + p_pkt->len;
    139   }
    140 
    141   for (xx = 0; xx < p_rsp->num_attr; xx++) {
    142     if (AVRC_IsValidPlayerAttr(p_rsp->attrs[xx])) {
    143       (*p_num)++;
    144       UINT8_TO_BE_STREAM(p_data, p_rsp->attrs[xx]);
    145     }
    146   }
    147 
    148   len = *p_num + 1;
    149   UINT16_TO_BE_STREAM(p_len, len);
    150   p_pkt->len = (p_data - p_start);
    151 
    152   return AVRC_STS_NO_ERROR;
    153 }
    154 
    155 /*******************************************************************************
    156  *
    157  * Function         avrc_bld_list_app_settings_values_rsp
    158  *
    159  * Description      This function builds the List Application Setting Values
    160  *                  response.
    161  *
    162  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    163  *                  Otherwise, the error code.
    164  *
    165  ******************************************************************************/
    166 static tAVRC_STS avrc_bld_list_app_settings_values_rsp(
    167     tAVRC_LIST_APP_VALUES_RSP* p_rsp, BT_HDR* p_pkt) {
    168   uint8_t *p_data, *p_start, *p_len, *p_num;
    169   uint8_t xx;
    170   uint16_t len;
    171 
    172   AVRC_TRACE_API("%s", __func__);
    173 
    174   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    175   p_data = p_len = p_start + 2; /* pdu + rsvd */
    176 
    177   /* get the existing length, if any, and also the num attributes */
    178   BE_STREAM_TO_UINT16(len, p_data);
    179   p_num = p_data;
    180   /* first time initialize the attribute count */
    181   if (len == 0) {
    182     *p_num = p_rsp->num_val;
    183     p_data++;
    184   } else {
    185     p_data = p_start + p_pkt->len;
    186     *p_num += p_rsp->num_val;
    187   }
    188 
    189   for (xx = 0; xx < p_rsp->num_val; xx++) {
    190     UINT8_TO_BE_STREAM(p_data, p_rsp->vals[xx]);
    191   }
    192 
    193   len = *p_num + 1;
    194   UINT16_TO_BE_STREAM(p_len, len);
    195   p_pkt->len = (p_data - p_start);
    196   return AVRC_STS_NO_ERROR;
    197 }
    198 
    199 /*******************************************************************************
    200  *
    201  * Function         avrc_bld_get_cur_app_setting_value_rsp
    202  *
    203  * Description      This function builds the Get Current Application Setting
    204  *                  Value response.
    205  *
    206  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    207  *                  Otherwise, the error code.
    208  *
    209  ******************************************************************************/
    210 static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp(
    211     tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp, BT_HDR* p_pkt) {
    212   uint8_t *p_data, *p_start, *p_len, *p_count;
    213   uint16_t len;
    214   uint8_t xx;
    215 
    216   if (!p_rsp->p_vals) {
    217     AVRC_TRACE_ERROR("%s NULL parameter", __func__);
    218     return AVRC_STS_BAD_PARAM;
    219   }
    220 
    221   AVRC_TRACE_API("%s", __func__);
    222   /* get the existing length, if any, and also the num attributes */
    223   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    224   p_data = p_len = p_start + 2; /* pdu + rsvd */
    225 
    226   BE_STREAM_TO_UINT16(len, p_data);
    227   p_count = p_data;
    228   if (len == 0) {
    229     /* first time initialize the attribute count */
    230     *p_count = 0;
    231     p_data++;
    232   } else {
    233     p_data = p_start + p_pkt->len;
    234   }
    235 
    236   for (xx = 0; xx < p_rsp->num_val; xx++) {
    237     if (avrc_is_valid_player_attrib_value(p_rsp->p_vals[xx].attr_id,
    238                                           p_rsp->p_vals[xx].attr_val)) {
    239       (*p_count)++;
    240       UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_id);
    241       UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_val);
    242     }
    243   }
    244   len = ((*p_count) << 1) + 1;
    245   UINT16_TO_BE_STREAM(p_len, len);
    246   p_pkt->len = (p_data - p_start);
    247 
    248   return AVRC_STS_NO_ERROR;
    249 }
    250 
    251 /*******************************************************************************
    252  *
    253  * Function         avrc_bld_set_app_setting_value_rsp
    254  *
    255  * Description      This function builds the Set Application Setting Value
    256  *                  response.
    257  *
    258  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    259  *                  Otherwise, the error code.
    260  *
    261  ******************************************************************************/
    262 static tAVRC_STS avrc_bld_set_app_setting_value_rsp(
    263     UNUSED_ATTR tAVRC_RSP* p_rsp, UNUSED_ATTR BT_HDR* p_pkt) {
    264   /* nothing to be added. */
    265   AVRC_TRACE_API("%s", __func__);
    266   return AVRC_STS_NO_ERROR;
    267 }
    268 
    269 /*******************************************************************************
    270  *
    271  * Function         avrc_bld_app_setting_text_rsp
    272  *
    273  * Description      This function builds the Get Application Settings Attribute
    274  *                  Text or Get Application Settings Value Text response.
    275  *
    276  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    277  *                  Otherwise, the error code.
    278  *
    279  ******************************************************************************/
    280 static tAVRC_STS avrc_bld_app_setting_text_rsp(
    281     tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp, BT_HDR* p_pkt) {
    282   uint8_t *p_data, *p_start, *p_len, *p_count;
    283   uint16_t len, len_left;
    284   uint8_t xx;
    285   tAVRC_STS sts = AVRC_STS_NO_ERROR;
    286   uint8_t num_added = 0;
    287 
    288   if (!p_rsp->p_attrs) {
    289     AVRC_TRACE_ERROR("%s NULL parameter", __func__);
    290     return AVRC_STS_BAD_PARAM;
    291   }
    292   /* get the existing length, if any, and also the num attributes */
    293   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    294   p_data = p_len = p_start + 2; /* pdu + rsvd */
    295 
    296   /*
    297    * NOTE: The buffer is allocated within avrc_bld_init_rsp_buffer(), and is
    298    * always of size BT_DEFAULT_BUFFER_SIZE.
    299    */
    300   len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
    301 
    302   BE_STREAM_TO_UINT16(len, p_data);
    303   p_count = p_data;
    304 
    305   if (len == 0) {
    306     *p_count = 0;
    307     p_data++;
    308   } else {
    309     p_data = p_start + p_pkt->len;
    310   }
    311 
    312   for (xx = 0; xx < p_rsp->num_attr; xx++) {
    313     if (len_left < (p_rsp->p_attrs[xx].str_len + 4)) {
    314       AVRC_TRACE_ERROR("%s out of room (str_len:%d, left:%d)", __func__, xx,
    315                        p_rsp->p_attrs[xx].str_len, len_left);
    316       p_rsp->num_attr = num_added;
    317       sts = AVRC_STS_INTERNAL_ERR;
    318       break;
    319     }
    320     if (!p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str) {
    321       AVRC_TRACE_ERROR("%s NULL attr text[%d]", __func__, xx);
    322       continue;
    323     }
    324     UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
    325     UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
    326     UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
    327     ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str,
    328                        p_rsp->p_attrs[xx].str_len);
    329     (*p_count)++;
    330     num_added++;
    331   }
    332   len = p_data - p_count;
    333   UINT16_TO_BE_STREAM(p_len, len);
    334   p_pkt->len = (p_data - p_start);
    335 
    336   return sts;
    337 }
    338 
    339 /*******************************************************************************
    340  *
    341  * Function         avrc_bld_get_app_setting_attr_text_rsp
    342  *
    343  * Description      This function builds the Get Application Setting Attribute
    344  *                  Text response.
    345  *
    346  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    347  *                  Otherwise, the error code.
    348  *
    349  ******************************************************************************/
    350 static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp(
    351     tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp, BT_HDR* p_pkt) {
    352   AVRC_TRACE_API("%s", __func__);
    353   return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
    354 }
    355 
    356 /*******************************************************************************
    357  *
    358  * Function         avrc_bld_get_app_setting_value_text_rsp
    359  *
    360  * Description      This function builds the Get Application Setting Value Text
    361  *                  response.
    362  *
    363  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    364  *                  Otherwise, the error code.
    365  *
    366  ******************************************************************************/
    367 static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp(
    368     tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp, BT_HDR* p_pkt) {
    369   AVRC_TRACE_API("%s", __func__);
    370   return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
    371 }
    372 
    373 /*******************************************************************************
    374  *
    375  * Function         avrc_bld_inform_charset_rsp
    376  *
    377  * Description      This function builds the Inform Displayable Character Set
    378  *                  response.
    379  *
    380  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    381  *                  Otherwise, the error code.
    382  *
    383  ******************************************************************************/
    384 static tAVRC_STS avrc_bld_inform_charset_rsp(UNUSED_ATTR tAVRC_RSP* p_rsp,
    385                                              UNUSED_ATTR BT_HDR* p_pkt) {
    386   /* nothing to be added. */
    387   AVRC_TRACE_API("%s", __func__);
    388   return AVRC_STS_NO_ERROR;
    389 }
    390 
    391 /*******************************************************************************
    392  *
    393  * Function         avrc_bld_inform_battery_status_rsp
    394  *
    395  * Description      This function builds the Inform Battery Status
    396  *                  response.
    397  *
    398  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    399  *                  Otherwise, the error code.
    400  *
    401  ******************************************************************************/
    402 static tAVRC_STS avrc_bld_inform_battery_status_rsp(
    403     UNUSED_ATTR tAVRC_RSP* p_rsp, UNUSED_ATTR BT_HDR* p_pkt) {
    404   /* nothing to be added. */
    405   AVRC_TRACE_API("%s", __func__);
    406   return AVRC_STS_NO_ERROR;
    407 }
    408 
    409 static void avrc_build_attribute_entries(int num_attrs,
    410                                          tAVRC_ATTR_ENTRY* p_attrs,
    411                                          int remaining_buffer_capacity,
    412                                          uint8_t** pp_data,
    413                                          uint8_t* p_attribute_count) {
    414   AVRC_TRACE_DEBUG("%s num_attrs: %d, remaining_buffer_capacity: %d", __func__,
    415                    num_attrs, remaining_buffer_capacity);
    416   uint8_t* p_data = *pp_data;
    417   /* Fill in the Attribute ID, Character Set, Length and Values */
    418   for (int index = 0; index < num_attrs; index++) {
    419     AVRC_TRACE_DEBUG("%s attr id[%d]: %d", __func__, index,
    420                      p_attrs[index].attr_id);
    421     CHECK(AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_attrs[index].attr_id));
    422     if (!p_attrs[index].name.p_str) {
    423       p_attrs[index].name.str_len = 0;
    424     }
    425     /* 8 is the size of attr_id, char set and str_len */
    426     remaining_buffer_capacity -= 8;
    427     if (remaining_buffer_capacity < 0) {
    428       AVRC_TRACE_WARNING(
    429           "%s not enough buffer space for attr_id[%d]: %d,"
    430           " skipping %d attributes",
    431           __func__, index, p_attrs[index].attr_id, num_attrs - index);
    432       break;
    433     }
    434     if (remaining_buffer_capacity < p_attrs[index].name.str_len) {
    435       AVRC_TRACE_WARNING(
    436           "%s not enough buffer space for attr_id[%d]: %d,"
    437           " truncating attribute",
    438           __func__, index, p_attrs[index].attr_id);
    439       p_attrs[index].name.str_len = remaining_buffer_capacity;
    440       remaining_buffer_capacity = 0;
    441     }
    442     remaining_buffer_capacity -= p_attrs[index].name.str_len;
    443     UINT32_TO_BE_STREAM(p_data, p_attrs[index].attr_id);
    444     UINT16_TO_BE_STREAM(p_data, p_attrs[index].name.charset_id);
    445     UINT16_TO_BE_STREAM(p_data, p_attrs[index].name.str_len);
    446     ARRAY_TO_BE_STREAM(p_data, p_attrs[index].name.p_str,
    447                        p_attrs[index].name.str_len);
    448     (*p_attribute_count)++;
    449   }
    450   *pp_data = p_data;
    451   AVRC_TRACE_DEBUG("%s filled attributes, remaining_buffer_capacity: %d",
    452                    __func__, num_attrs, remaining_buffer_capacity);
    453 }
    454 
    455 /*******************************************************************************
    456  *
    457  * Function         avrc_bld_get_elem_attrs_rsp
    458  *
    459  * Description      This function builds the Get Element Attributes
    460  *                  response.
    461  *
    462  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    463  *                  Otherwise, the error code.
    464  *
    465  ******************************************************************************/
    466 static tAVRC_STS avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp,
    467                                              BT_HDR* p_pkt) {
    468   AVRC_TRACE_API("%s", __func__);
    469   if (!p_rsp->p_attrs) {
    470     AVRC_TRACE_ERROR("%s NULL p_attrs", __func__);
    471     return AVRC_STS_BAD_PARAM;
    472   }
    473   /* Figure out how much we have left in current buffer */
    474   int remaining_buffer_capacity =
    475       BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset;
    476   if (remaining_buffer_capacity < 5) {
    477     AVRC_TRACE_ERROR("%s not enough buffer for packet header",
    478                      remaining_buffer_capacity);
    479     return AVRC_STS_INTERNAL_ERR;
    480   }
    481   /* Get to the beginning of PDU */
    482   uint8_t* p_pdu_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    483   /* Skip PDU ID and Reserved byte to get pointer to Parameter Length */
    484   uint8_t *p_data, *p_parameter_len;
    485   p_data = p_parameter_len = p_pdu_start + 2;
    486   /* Parse parameter length */
    487   uint16_t parameter_len;
    488   BE_STREAM_TO_UINT16(parameter_len, p_data);
    489   /* Get pointer to Attribute Count */
    490   uint8_t* p_attribute_count = p_data;
    491   /* Initialize field values when Parameter Length is 0 */
    492   if (parameter_len == 0) {
    493     *p_attribute_count = 0;
    494     p_data++;
    495   } else {
    496     // TODO: Why do we need this case?
    497     p_data = p_pdu_start + p_pkt->len;
    498   }
    499   remaining_buffer_capacity -= p_data - p_pdu_start;
    500   ;
    501   if (remaining_buffer_capacity < 0) {
    502     AVRC_TRACE_ERROR("%s not enough buffer capacity for response");
    503     return AVRC_STS_BAD_PARAM;
    504   }
    505   /* Fill in the Attribute ID, Character Set, Length and Values */
    506   avrc_build_attribute_entries(p_rsp->num_attrs, p_rsp->p_attrs,
    507                                remaining_buffer_capacity, &p_data,
    508                                p_attribute_count);
    509   parameter_len = p_data - p_attribute_count;
    510   UINT16_TO_BE_STREAM(p_parameter_len, parameter_len);
    511   p_pkt->len = (p_data - p_pdu_start);
    512   return AVRC_STS_NO_ERROR;
    513 }
    514 
    515 /*******************************************************************************
    516  *
    517  * Function         avrc_bld_get_play_status_rsp
    518  *
    519  * Description      This function builds the Get Play Status
    520  *                  response.
    521  *
    522  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    523  *                  Otherwise, the error code.
    524  *
    525  ******************************************************************************/
    526 static tAVRC_STS avrc_bld_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP* p_rsp,
    527                                               BT_HDR* p_pkt) {
    528   uint8_t *p_data, *p_start;
    529 
    530   AVRC_TRACE_API("%s", __func__);
    531   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    532   p_data = p_start + 2;
    533 
    534   /* add fixed lenth - song len(4) + song position(4) + status(1) */
    535   UINT16_TO_BE_STREAM(p_data, 9);
    536   UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
    537   UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
    538   UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
    539   p_pkt->len = (p_data - p_start);
    540 
    541   return AVRC_STS_NO_ERROR;
    542 }
    543 
    544 /*******************************************************************************
    545  *
    546  * Function         avrc_bld_notify_rsp
    547  *
    548  * Description      This function builds the Notification response.
    549  *
    550  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    551  *                  Otherwise, the error code.
    552  *
    553  ******************************************************************************/
    554 static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp,
    555                                      BT_HDR* p_pkt) {
    556   uint8_t *p_data, *p_start;
    557   uint8_t* p_len;
    558   uint16_t len = 0;
    559   uint8_t xx;
    560   tAVRC_STS status = AVRC_STS_NO_ERROR;
    561 
    562   AVRC_TRACE_API("%s event_id %d", __func__, p_rsp->event_id);
    563 
    564   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    565   p_data = p_len = p_start + 2; /* pdu + rsvd */
    566   p_data += 2;
    567 
    568   UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
    569   switch (p_rsp->event_id) {
    570     case AVRC_EVT_PLAY_STATUS_CHANGE: /* 0x01 */
    571       /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always true */
    572       if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
    573           (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR)) {
    574         UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
    575         len = 2;
    576       } else {
    577         AVRC_TRACE_ERROR("%s bad play state", __func__);
    578         status = AVRC_STS_BAD_PARAM;
    579       }
    580       break;
    581 
    582     case AVRC_EVT_TRACK_CHANGE: /* 0x02 */
    583       ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
    584       len = (uint8_t)(AVRC_UID_SIZE + 1);
    585       break;
    586 
    587     case AVRC_EVT_TRACK_REACHED_END:   /* 0x03 */
    588     case AVRC_EVT_TRACK_REACHED_START: /* 0x04 */
    589     case AVRC_EVT_NOW_PLAYING_CHANGE:  /* 0x09 */
    590     case AVRC_EVT_AVAL_PLAYERS_CHANGE: /* 0x0a */
    591       len = 1;
    592       break;
    593 
    594     case AVRC_EVT_PLAY_POS_CHANGED: /* 0x05 */
    595       UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
    596       len = 5;
    597       break;
    598 
    599     case AVRC_EVT_BATTERY_STATUS_CHANGE: /* 0x06 */
    600       if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status)) {
    601         UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
    602         len = 2;
    603       } else {
    604         AVRC_TRACE_ERROR("%s bad battery status", __func__);
    605         status = AVRC_STS_BAD_PARAM;
    606       }
    607       break;
    608 
    609     case AVRC_EVT_SYSTEM_STATUS_CHANGE: /* 0x07 */
    610       if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status)) {
    611         UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
    612         len = 2;
    613       } else {
    614         AVRC_TRACE_ERROR("%s bad system status", __func__);
    615         status = AVRC_STS_BAD_PARAM;
    616       }
    617       break;
    618 
    619     case AVRC_EVT_APP_SETTING_CHANGE: /* 0x08 */
    620       if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS)
    621         p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
    622 
    623       if (p_rsp->param.player_setting.num_attr > 0) {
    624         UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
    625         len = 2;
    626         for (xx = 0; xx < p_rsp->param.player_setting.num_attr; xx++) {
    627           if (avrc_is_valid_player_attrib_value(
    628                   p_rsp->param.player_setting.attr_id[xx],
    629                   p_rsp->param.player_setting.attr_value[xx])) {
    630             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
    631             UINT8_TO_BE_STREAM(p_data,
    632                                p_rsp->param.player_setting.attr_value[xx]);
    633           } else {
    634             AVRC_TRACE_ERROR("%s bad player app seeting attribute or value",
    635                              __func__);
    636             status = AVRC_STS_BAD_PARAM;
    637             break;
    638           }
    639           len += 2;
    640         }
    641       } else
    642         status = AVRC_STS_BAD_PARAM;
    643       break;
    644 
    645     case AVRC_EVT_VOLUME_CHANGE: /* 0x0d */
    646       len = 2;
    647       UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume));
    648       break;
    649 
    650     case AVRC_EVT_ADDR_PLAYER_CHANGE: /* 0x0b */
    651       UINT16_TO_BE_STREAM(p_data, p_rsp->param.addr_player.player_id);
    652       UINT16_TO_BE_STREAM(p_data, p_rsp->param.addr_player.uid_counter);
    653       len = 5;
    654       break;
    655 
    656     case AVRC_EVT_UIDS_CHANGE:                               /* 0x0c */
    657       UINT16_TO_BE_STREAM(p_data, p_rsp->param.uid_counter); /* uid counter */
    658       len = 3;
    659       break;
    660 
    661     default:
    662       status = AVRC_STS_BAD_PARAM;
    663       AVRC_TRACE_ERROR("%s unknown event_id", __func__);
    664   }
    665 
    666   UINT16_TO_BE_STREAM(p_len, len);
    667   p_pkt->len = (p_data - p_start);
    668 
    669   return status;
    670 }
    671 
    672 /*******************************************************************************
    673  *
    674  * Function         avrc_bld_next_rsp
    675  *
    676  * Description      This function builds the Request Continue or Abort
    677  *                  response.
    678  *
    679  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    680  *                  Otherwise, the error code.
    681  *
    682  ******************************************************************************/
    683 static tAVRC_STS avrc_bld_next_rsp(tAVRC_NEXT_RSP* p_rsp, BT_HDR* p_pkt) {
    684   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    685   uint8_t* p_data = (p_start + 2); /* Skip the pdu and reserved bits */
    686 
    687   UINT16_TO_BE_STREAM(p_data, 0x0001); /* only one attribute to be sent */
    688   UINT8_TO_BE_STREAM(p_data, p_rsp->target_pdu);
    689 
    690   AVRC_TRACE_API("%s: target_pdu: 0x%02x", __func__, p_rsp->target_pdu);
    691   return AVRC_STS_NO_ERROR;
    692 }
    693 
    694 /*****************************************************************************
    695  *
    696  * Function      avrc_bld_set_absolute_volume_rsp
    697  *
    698  * Description   This function builds the set absolute volume response
    699  *
    700  * Returns       AVRC_STS_NO_ERROR, if the response is build successfully
    701  *
    702  *****************************************************************************/
    703 static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol,
    704                                                   BT_HDR* p_pkt) {
    705   AVRC_TRACE_API("%s", __func__);
    706   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    707   /* To calculate length */
    708   uint8_t* p_data = p_start + 2;
    709   /* add fixed lenth status(1) */
    710   UINT16_TO_BE_STREAM(p_data, 1);
    711   UINT8_TO_BE_STREAM(p_data, abs_vol);
    712   p_pkt->len = (p_data - p_start);
    713   return AVRC_STS_NO_ERROR;
    714 }
    715 
    716 /*******************************************************************************
    717  *
    718  * Function         avrc_bld_group_navigation_rsp
    719  *
    720  * Description      This function builds the Group Navigation
    721  *                  response.
    722  *
    723  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    724  *                  Otherwise, the error code.
    725  *
    726  ******************************************************************************/
    727 tAVRC_STS avrc_bld_group_navigation_rsp(uint16_t navi_id, BT_HDR* p_pkt) {
    728   if (!AVRC_IS_VALID_GROUP(navi_id)) {
    729     AVRC_TRACE_ERROR("%s bad navigation op id: %d", __func__, navi_id);
    730     return AVRC_STS_BAD_PARAM;
    731   }
    732   AVRC_TRACE_API("%s", __func__);
    733   uint8_t* p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    734   UINT16_TO_BE_STREAM(p_data, navi_id);
    735   p_pkt->len = 2;
    736   return AVRC_STS_NO_ERROR;
    737 }
    738 
    739 /*******************************************************************************
    740  *
    741  * Function         avrc_bld_rejected_rsp
    742  *
    743  * Description      This function builds the General Response response.
    744  *
    745  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    746  *
    747  ******************************************************************************/
    748 static tAVRC_STS avrc_bld_rejected_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
    749   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    750   uint8_t* p_data;
    751   uint8_t opcode = p_rsp->opcode;
    752 
    753   AVRC_TRACE_API("%s: status=%d, pdu:x%x, opcode=%x", __func__, p_rsp->status,
    754                  p_rsp->pdu, opcode);
    755 
    756   if (opcode == AVRC_OP_BROWSE) {
    757     p_data = p_start + 1;
    758     if ((AVRC_PDU_INVALID == *p_start) ||
    759         (avrc_opcode_from_pdu(*p_start) != AVRC_OP_BROWSE)) {
    760       /* if invalid or the given opcode is not recognized as a browsing command
    761        * opcode, */
    762       /* use general reject command */
    763       *p_start = AVRC_PDU_GENERAL_REJECT;
    764     }
    765   } else {
    766     p_data = p_start + 2;
    767   }
    768   AVRC_TRACE_DEBUG("%s pdu:x%x, Opcode:%x", __func__, *p_start, opcode);
    769   UINT16_TO_BE_STREAM(p_data, 1);
    770   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    771   p_pkt->len = p_data - p_start;
    772   return AVRC_STS_NO_ERROR;
    773 }
    774 
    775 /*****************************************************************************
    776  *  the following commands are introduced in AVRCP 1.4
    777  ****************************************************************************/
    778 
    779 /*******************************************************************************
    780  *
    781  * Function         avrc_bld_ctrl_status_rsp
    782  *
    783  * Description      This function builds the responses with a uint8_t parameter.
    784  *
    785  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    786  *                  Otherwise, the error code.
    787  *
    788  ******************************************************************************/
    789 static tAVRC_STS avrc_bld_ctrl_status_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
    790   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    791   AVRC_TRACE_DEBUG("pdu:x%x", *p_start);
    792 
    793   /* To calculate length */
    794   uint8_t* p_data = p_start + 2; /* pdu + rsvd */
    795 
    796   /* add fixed lenth - status(1) */
    797   UINT16_TO_BE_STREAM(p_data, 1);
    798   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    799   p_pkt->len = (p_data - p_start);
    800   return AVRC_STS_NO_ERROR;
    801 }
    802 
    803 /*******************************************************************************
    804  *
    805  * Function         avrc_bld_set_addr_player_rsp
    806  *
    807  * Description      This function builds the Set Addresses Player response.
    808  *
    809  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    810  *                  Otherwise, the error code.
    811  *
    812  ******************************************************************************/
    813 static tAVRC_STS avrc_bld_set_addr_player_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
    814   AVRC_TRACE_API("%s", __func__);
    815   return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt);
    816 }
    817 
    818 /*******************************************************************************
    819  *
    820  * Function         avrc_bld_set_browsed_player_rsp
    821  *
    822  * Description      This function builds the Set Browsed Player response.
    823  *
    824  *                  This message goes through the Browsing channel
    825  *
    826  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    827  *                  Otherwise, the error code.
    828  *
    829  ******************************************************************************/
    830 static tAVRC_STS avrc_bld_set_browsed_player_rsp(tAVRC_SET_BR_PLAYER_RSP* p_rsp,
    831                                                  BT_HDR* p_pkt) {
    832   uint8_t *p_data, *p_start;
    833   uint8_t* p_len;
    834   uint16_t len;
    835   tAVRC_NAME* p_folders = p_rsp->p_folders;
    836   uint16_t len_left;
    837   uint8_t* p_folder_depth;
    838   uint16_t mtu;
    839 
    840   /* make sure the given buffer can accomodate this response */
    841   len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE;
    842   p_data = (uint8_t*)(p_pkt + 1);
    843   BE_STREAM_TO_UINT16(mtu, p_data);
    844   if (len_left > mtu) {
    845     len_left = mtu;
    846   }
    847   len_left = len_left - p_pkt->offset - p_pkt->len;
    848   AVRC_TRACE_DEBUG("len_left:%d, mtu:%d ", len_left, mtu);
    849 
    850   /* get the existing length, if any, and also the num attributes */
    851   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    852   p_data = p_len = p_start + 1; /* pdu */
    853 
    854   /* the existing len */
    855   BE_STREAM_TO_UINT16(len, p_data);
    856   /* find the position to add the folder depth.
    857    * 9 is sizeof (status + uid_counter + num_items + charset_id) */
    858   p_folder_depth = p_data + 9;
    859   if (len == 0) {
    860     /* first time initialize the attribute count */
    861     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    862     UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
    863     UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
    864     UINT16_TO_BE_STREAM(p_data, p_rsp->charset_id);
    865     *p_folder_depth = 0;
    866     p_data++;
    867     len = 10;
    868     /* assuming that we would never use a buffer that is too small for headers
    869      */
    870     len_left -= 12;
    871   } else {
    872     p_data = p_start + p_pkt->len;
    873   }
    874 
    875   for (uint8_t xx = 0;
    876        (xx < p_rsp->folder_depth) && (len_left > (p_folders[xx].str_len + 2));
    877        xx++) {
    878     (*p_folder_depth)++;
    879     UINT16_TO_BE_STREAM(p_data, p_folders[xx].str_len);
    880     ARRAY_TO_BE_STREAM(p_data, p_folders[xx].p_str, p_folders[xx].str_len);
    881     len += (p_folders[xx].str_len + 2);
    882   }
    883   UINT16_TO_BE_STREAM(p_len, len);
    884   p_pkt->len = (p_data - p_start);
    885   return AVRC_STS_NO_ERROR;
    886 }
    887 
    888 /*******************************************************************************
    889  *
    890  * Function         avrc_bld_get_folder_items_rsp
    891  *
    892  * Description      This function builds the Get Folder Items response.
    893  *                  The error code is returned in *p_status.
    894  *                  AVRC_STS_INTERNAL_ERR means no buffers.
    895  *                  Try again later or with smaller item_count
    896  *
    897  *                  This message goes through the Browsing channel
    898  *
    899  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    900  *                  AVRC_STS_INTERNAL_ERR, if the given buffer does not have
    901  *                  enough room
    902  *                  Otherwise, the error code.
    903  *
    904  ******************************************************************************/
    905 static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp,
    906                                                BT_HDR* p_pkt) {
    907   uint8_t *p_data, *p_start;
    908   uint8_t *p_len, xx;
    909   uint16_t len;
    910   uint16_t item_len;
    911   uint8_t *p_item_len, yy;
    912   tAVRC_ITEM_PLAYER* p_player;
    913   tAVRC_ITEM_FOLDER* p_folder;
    914   tAVRC_ITEM_MEDIA* p_media;
    915   tAVRC_ATTR_ENTRY* p_attr;
    916   tAVRC_ITEM* p_item_list = p_rsp->p_item_list;
    917   tAVRC_STS status = AVRC_STS_NO_ERROR;
    918   uint16_t len_left;
    919   uint8_t *p_num, *p;
    920   uint8_t *p_item_start, *p_attr_count;
    921   uint16_t item_count;
    922   uint16_t mtu;
    923   bool multi_items_add_fail = false;
    924   AVRC_TRACE_API("%s", __func__);
    925 
    926   /* make sure the given buffer can accomodate this response */
    927   len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE;
    928   p = (uint8_t*)(p_pkt + 1);
    929   BE_STREAM_TO_UINT16(mtu, p);
    930   if (len_left > mtu) len_left = mtu;
    931   len_left = len_left - p_pkt->offset - p_pkt->len;
    932 
    933   /* get the existing length, if any, and also the num attributes */
    934   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    935   p_data = p_len = p_start + 1; /* pdu */
    936 
    937   /* the existing len */
    938   BE_STREAM_TO_UINT16(len, p_data);
    939   p_num = p_data + 3;
    940   if (len == 0) {
    941     /* first time initialize the attribute count */
    942     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    943     UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
    944     item_count = 0;
    945     p_data += 2;
    946     len = 5;
    947     len_left -= 5;
    948   } else {
    949     p_data = p_start + p_pkt->len;
    950     p = p_num;
    951     BE_STREAM_TO_UINT16(item_count, p);
    952   }
    953   AVRC_TRACE_DEBUG("len:%d, len_left:%d, num:%d", len, len_left, item_count);
    954 
    955   /* min len required = item_type(1) + item len(2) + min item (14) = 17 */
    956   for (xx = 0;
    957        xx < p_rsp->item_count && len_left > AVRC_MIN_LEN_GET_FOLDER_ITEMS_RSP &&
    958        multi_items_add_fail == false;
    959        xx++) {
    960     p_item_start = p_data;
    961     UINT8_TO_BE_STREAM(p_data, p_item_list[xx].item_type);
    962     /* variable item lenth - save the location to add length */
    963     p_item_len = p_data;
    964     p_data += 2;
    965     item_len = 0;
    966     len_left -= 3; /* item_type(1) + item len(2) */
    967     switch (p_item_list[xx].item_type) {
    968       case AVRC_ITEM_PLAYER:
    969         /* min len required: 2 + 1 + 4 + 1 + 16 + 2 + 2 = 30 + str_len */
    970         p_player = &p_item_list[xx].u.player;
    971         item_len = AVRC_FEATURE_MASK_SIZE + p_player->name.str_len + 12;
    972 
    973         if ((len_left <= item_len) ||
    974             AVRC_ITEM_PLAYER_IS_VALID(p_player) == false) {
    975           p_data = p_item_start;
    976         } else {
    977           UINT16_TO_BE_STREAM(p_data, p_player->player_id);
    978           UINT8_TO_BE_STREAM(p_data, p_player->major_type);
    979           UINT32_TO_BE_STREAM(p_data, p_player->sub_type);
    980           UINT8_TO_BE_STREAM(p_data, p_player->play_status);
    981           ARRAY_TO_BE_STREAM(p_data, p_player->features,
    982                              AVRC_FEATURE_MASK_SIZE);
    983           UINT16_TO_BE_STREAM(p_data, p_player->name.charset_id);
    984           UINT16_TO_BE_STREAM(p_data, p_player->name.str_len);
    985           ARRAY_TO_BE_STREAM(p_data, p_player->name.p_str,
    986                              p_player->name.str_len);
    987         }
    988         break;
    989 
    990       case AVRC_ITEM_FOLDER:
    991         /* min len required: 8 + 1 + 1 + 2 + 2 = 14 + str_len */
    992         p_folder = &p_item_list[xx].u.folder;
    993         item_len = AVRC_UID_SIZE + p_folder->name.str_len + 6;
    994 
    995         if ((len_left > item_len) && p_folder->name.p_str &&
    996             p_folder->type <= AVRC_FOLDER_TYPE_YEARS) {
    997           ARRAY_TO_BE_STREAM(p_data, p_folder->uid, AVRC_UID_SIZE);
    998           UINT8_TO_BE_STREAM(p_data, p_folder->type);
    999           UINT8_TO_BE_STREAM(p_data, p_folder->playable);
   1000           UINT16_TO_BE_STREAM(p_data, p_folder->name.charset_id);
   1001           UINT16_TO_BE_STREAM(p_data, p_folder->name.str_len);
   1002           ARRAY_TO_BE_STREAM(p_data, p_folder->name.p_str,
   1003                              p_folder->name.str_len);
   1004         } else {
   1005           p_data = p_item_start;
   1006         }
   1007         break;
   1008 
   1009       case AVRC_ITEM_MEDIA:
   1010         /* min len required: 8 + 1 + 2 + 2 + 1 = 14 + str_len */
   1011         p_media = &p_item_list[xx].u.media;
   1012         item_len = AVRC_UID_SIZE + p_media->name.str_len + 6;
   1013 
   1014         if ((len_left >= item_len) && p_media->name.p_str &&
   1015             p_media->type <= AVRC_MEDIA_TYPE_VIDEO) {
   1016           ARRAY_TO_BE_STREAM(p_data, p_media->uid, AVRC_UID_SIZE);
   1017           UINT8_TO_BE_STREAM(p_data, p_media->type);
   1018           UINT16_TO_BE_STREAM(p_data, p_media->name.charset_id);
   1019           UINT16_TO_BE_STREAM(p_data, p_media->name.str_len);
   1020           ARRAY_TO_BE_STREAM(p_data, p_media->name.p_str,
   1021                              p_media->name.str_len);
   1022           p_attr_count = p_data++;
   1023           *p_attr_count = 0;
   1024           len_left -= item_len;
   1025           if (p_media->attr_count > 0) {
   1026             p_attr = p_media->p_attr_list;
   1027             for (yy = 0; yy < p_media->attr_count; yy++) {
   1028               if (p_attr[yy].name.p_str &&
   1029                   AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_attr[yy].attr_id) &&
   1030                   (len_left >= (p_attr[yy].name.str_len + 8))) {
   1031                 (*p_attr_count)++;
   1032                 UINT32_TO_BE_STREAM(p_data, p_attr[yy].attr_id);
   1033                 UINT16_TO_BE_STREAM(p_data, p_attr[yy].name.charset_id);
   1034                 UINT16_TO_BE_STREAM(p_data, p_attr[yy].name.str_len);
   1035                 ARRAY_TO_BE_STREAM(p_data, p_attr[yy].name.p_str,
   1036                                    p_attr[yy].name.str_len);
   1037                 item_len += (p_attr[yy].name.str_len + 8);
   1038                 len_left -= (p_attr[yy].name.str_len + 8);
   1039               } else if ((len_left < (p_attr[yy].name.str_len + 8)) &&
   1040                          item_count > 0) {
   1041                 p_data = p_item_start;
   1042                 multi_items_add_fail = TRUE;
   1043                 break;
   1044               }
   1045             }
   1046           }
   1047         } else {
   1048           if (len_left < item_len && item_count > 0)
   1049             multi_items_add_fail = TRUE;
   1050           p_data = p_item_start;
   1051         }
   1052         break;
   1053     } /* switch item_type */
   1054 
   1055     if (p_item_start != p_data) {
   1056       /* successfully added the item */
   1057       item_count++;
   1058       /* fill in variable item lenth */
   1059       UINT16_TO_BE_STREAM(p_item_len, item_len);
   1060     } else {
   1061       if (multi_items_add_fail == false) {
   1062         /* some item is not added properly - set an error status */
   1063         if (len_left < item_len)
   1064           status = AVRC_STS_INTERNAL_ERR;
   1065         else
   1066           status = AVRC_STS_BAD_PARAM;
   1067       }
   1068     }
   1069     if (multi_items_add_fail == false) {
   1070       len += item_len;
   1071       len += 3; /* the item_type(1) and item_len(2) */
   1072     }
   1073     AVRC_TRACE_DEBUG("len:%d, len_left:%d, num:%d, item_len:%d", len, len_left,
   1074                      item_count, item_len);
   1075   } /* for item_count */
   1076 
   1077   UINT16_TO_BE_STREAM(p_num, item_count);
   1078   UINT16_TO_BE_STREAM(p_len, len);
   1079   p_pkt->len = (p_data - p_start);
   1080 
   1081   return status;
   1082 }
   1083 
   1084 /*******************************************************************************
   1085  *
   1086  * Function         avrc_bld_change_path_rsp
   1087  *
   1088  * Description      This function builds the Change Path response.
   1089  *
   1090  *                  This message goes through the Browsing channel
   1091  *
   1092  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1093  *                  Otherwise, the error code.
   1094  *
   1095  ******************************************************************************/
   1096 static tAVRC_STS avrc_bld_change_path_rsp(tAVRC_CHG_PATH_RSP* p_rsp,
   1097                                           BT_HDR* p_pkt) {
   1098   uint8_t *p_data, *p_start;
   1099 
   1100   /* get the existing length, if any, and also the num attributes */
   1101   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
   1102   p_data = p_start + 1; /* pdu */
   1103   /* add fixed length - status(1) + num_items(4) */
   1104   UINT16_TO_BE_STREAM(p_data, 5);
   1105   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
   1106   UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
   1107   p_pkt->len = (p_data - p_start);
   1108   return AVRC_STS_NO_ERROR;
   1109 }
   1110 
   1111 /*******************************************************************************
   1112  *
   1113  * Function         avrc_bld_get_attrs_rsp
   1114  *
   1115  * Description      This function builds the GetItemAttributes response,
   1116  *
   1117  *                  The Get Item Attributes message goes through the
   1118  *                  Browsing channel (already specified in the |p_pkt|)
   1119  *
   1120  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1121  *                  AVRC_STS_INTERNAL_ERR, if the given buffer does not have
   1122  *                  enough room
   1123  *                  Otherwise, the error code.
   1124  *
   1125  ******************************************************************************/
   1126 static tAVRC_STS avrc_bld_get_item_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp,
   1127                                              BT_HDR* p_pkt) {
   1128   AVRC_TRACE_API("%s", __func__);
   1129   if (!p_rsp->p_attrs) {
   1130     AVRC_TRACE_ERROR("%s NULL p_attrs", __func__);
   1131     return AVRC_STS_BAD_PARAM;
   1132   }
   1133   /* Figure out how much we have left in current buffer */
   1134   int remaining_buffer_capacity =
   1135       BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset;
   1136   /* Get to the beginning of data section in buffer */
   1137   uint8_t* p_data = (uint8_t*)(p_pkt + 1);
   1138   /* Get the MTU size that is filled in earlier */
   1139   uint16_t mtu;
   1140   BE_STREAM_TO_UINT16(mtu, p_data);
   1141   if (remaining_buffer_capacity > mtu) {
   1142     remaining_buffer_capacity = mtu;
   1143   }
   1144   AVRC_TRACE_DEBUG("%s: remaining_buffer_capacity:%d, mtu:%d", __func__,
   1145                    remaining_buffer_capacity, mtu);
   1146   if (remaining_buffer_capacity < 5) {
   1147     AVRC_TRACE_ERROR("%s: not enough space for packet header, remaining:%d < 5",
   1148                      __func__, remaining_buffer_capacity);
   1149     return AVRC_STS_INTERNAL_ERR;
   1150   }
   1151   /* Get to the beginning of PDU */
   1152   uint8_t* p_pdu_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
   1153   /* Skip PDU ID to get pointer to Parameter length */
   1154   uint8_t* p_parameter_len;
   1155   p_data = p_parameter_len = p_pdu_start + 1;
   1156   /* Parse existing parameter length */
   1157   uint16_t parameter_len;
   1158   BE_STREAM_TO_UINT16(parameter_len, p_data);
   1159   /* Skip one byte to Number of Attributes */
   1160   uint8_t* p_status = p_data++;
   1161   uint8_t* p_attribute_count = p_data++;
   1162   if (parameter_len == 0) {
   1163     /* First time, initialize the status byte */
   1164     *p_status = p_rsp->status;
   1165     if (p_rsp->status != AVRC_STS_NO_ERROR) {
   1166       // TODO(siyuanh): This is a hack
   1167       parameter_len = 1;
   1168       UINT16_TO_BE_STREAM(p_parameter_len, parameter_len);
   1169       p_pkt->len = p_status - p_pdu_start;
   1170       return AVRC_STS_NO_ERROR;
   1171     }
   1172     *p_attribute_count = 0;
   1173   } else {
   1174     // TODO(siyuanh): Why do wee need this case?
   1175     p_data = p_pdu_start + p_pkt->len;
   1176   }
   1177   remaining_buffer_capacity -= p_data - p_pdu_start;
   1178   /* Fill in the Attribute ID, Character Set, Length and Values */
   1179   avrc_build_attribute_entries(p_rsp->num_attrs, p_rsp->p_attrs,
   1180                                remaining_buffer_capacity, &p_data,
   1181                                p_attribute_count);
   1182   parameter_len = p_data - p_status;
   1183   UINT16_TO_BE_STREAM(p_parameter_len, parameter_len);
   1184   p_pkt->len = p_data - p_pdu_start;
   1185   return AVRC_STS_NO_ERROR;
   1186 }
   1187 
   1188 /*******************************************************************************
   1189  *
   1190  * Function         avrc_bld_get_num_of_item_rsp
   1191  *
   1192  * Description      This function builds the Get Total Number of Items response.
   1193  *
   1194  *                  This message goes through the Browsing channel
   1195  *
   1196  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1197  *                  AVRC_STS_INTERNAL_ERR, if the given buffer does not have
   1198  *                  enough room
   1199  *                  Otherwise, the error code.
   1200  *
   1201  ******************************************************************************/
   1202 static tAVRC_STS avrc_bld_get_num_of_item_rsp(tAVRC_GET_NUM_OF_ITEMS_RSP* p_rsp,
   1203                                               BT_HDR* p_pkt) {
   1204   uint8_t *p_data, *p_start, *p_len;
   1205 
   1206   AVRC_TRACE_API("%s", __func__);
   1207   /* get the existing length, if any, and also the num attributes */
   1208   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
   1209   p_data = p_len = p_start + 1; /* pdu */
   1210 
   1211   if (p_rsp->status == AVRC_STS_NO_ERROR) {
   1212     /* add fixed lenth - status(1) + uid_counter(2) + num_items(4) */
   1213     UINT16_TO_BE_STREAM(p_data, 7);
   1214     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
   1215     UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
   1216     UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
   1217     p_pkt->len = (p_data - p_start);
   1218     return AVRC_STS_NO_ERROR;
   1219   } else {
   1220     /* add fixed lenth - status(1) */
   1221     UINT16_TO_BE_STREAM(p_data, 7);
   1222     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
   1223     p_pkt->len = (p_data - p_start);
   1224     return p_rsp->status;
   1225   }
   1226 }
   1227 
   1228 /*******************************************************************************
   1229  *
   1230  * Function         avrc_bld_search_rsp
   1231  *
   1232  * Description      This function builds the Search response.
   1233  *
   1234  *                  This message goes through the Browsing channel
   1235  *
   1236  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1237  *                  Otherwise, the error code.
   1238  *
   1239  ******************************************************************************/
   1240 static tAVRC_STS avrc_bld_search_rsp(tAVRC_SEARCH_RSP* p_rsp, BT_HDR* p_pkt) {
   1241   uint8_t *p_data, *p_start, *p_len;
   1242 
   1243   AVRC_TRACE_API("%s", __func__);
   1244   /* get the existing length, if any, and also the num attributes */
   1245   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
   1246   p_data = p_len = p_start + 1; /* pdu */
   1247 
   1248   /* add fixed lenth - status(1) + uid_counter(2) + num_items(4) */
   1249   UINT16_TO_BE_STREAM(p_data, 7);
   1250   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
   1251   UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
   1252   UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
   1253   p_pkt->len = (p_data - p_start);
   1254   return AVRC_STS_NO_ERROR;
   1255 }
   1256 
   1257 /*******************************************************************************
   1258  *
   1259  * Function         avrc_bld_play_item_rsp
   1260  *
   1261  * Description      This function builds the Play Item response.
   1262  *
   1263  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1264  *                  Otherwise, the error code.
   1265  *
   1266  ******************************************************************************/
   1267 static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
   1268   AVRC_TRACE_API("%s", __func__);
   1269   return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt);
   1270 }
   1271 
   1272 /*******************************************************************************
   1273  *
   1274  * Function         avrc_bld_add_to_now_playing_rsp
   1275  *
   1276  * Description      This function builds the Add to Now Playing response.
   1277  *
   1278  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1279  *                  Otherwise, the error code.
   1280  *
   1281  ******************************************************************************/
   1282 static tAVRC_STS avrc_bld_add_to_now_playing_rsp(tAVRC_RSP* p_rsp,
   1283                                                  BT_HDR* p_pkt) {
   1284   AVRC_TRACE_API("%s", __func__);
   1285   return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt);
   1286 }
   1287 
   1288 /*******************************************************************************
   1289  *
   1290  * Function         avrc_bld_init_rsp_buffer
   1291  *
   1292  * Description      This function initializes the response buffer based on PDU
   1293  *
   1294  * Returns          NULL, if no buffer or failure to build the message.
   1295  *                  Otherwise, the buffer that contains the initialized message.
   1296  *
   1297  ******************************************************************************/
   1298 static BT_HDR* avrc_bld_init_rsp_buffer(tAVRC_RESPONSE* p_rsp) {
   1299   uint16_t offset = 0;
   1300   uint16_t chnl = AVCT_DATA_CTRL;
   1301   uint8_t opcode = avrc_opcode_from_pdu(p_rsp->pdu);
   1302 
   1303   AVRC_TRACE_API("%s: pdu=%x, opcode=%x/%x", __func__, p_rsp->pdu, opcode,
   1304                  p_rsp->rsp.opcode);
   1305   if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
   1306       avrc_is_valid_opcode(p_rsp->rsp.opcode)) {
   1307     opcode = p_rsp->rsp.opcode;
   1308     AVRC_TRACE_API("%s opcode=%x", __func__, opcode);
   1309   }
   1310 
   1311   switch (opcode) {
   1312     case AVRC_OP_BROWSE:
   1313       chnl = AVCT_DATA_BROWSE;
   1314       offset = AVCT_BROWSE_OFFSET;
   1315       break;
   1316 
   1317     case AVRC_OP_PASS_THRU:
   1318       offset = AVRC_MSG_PASS_THRU_OFFSET;
   1319       break;
   1320 
   1321     case AVRC_OP_VENDOR:
   1322       offset = AVRC_MSG_VENDOR_OFFSET;
   1323       break;
   1324   }
   1325 
   1326   /* allocate and initialize the buffer */
   1327   BT_HDR* p_pkt = (BT_HDR*)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
   1328   uint8_t *p_data, *p_start;
   1329 
   1330   p_pkt->layer_specific = chnl;
   1331   p_pkt->event = opcode;
   1332   p_pkt->offset = offset;
   1333   p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
   1334   p_start = p_data;
   1335 
   1336   /* pass thru - group navigation - has a two byte op_id, so dont do it here */
   1337   if (opcode != AVRC_OP_PASS_THRU) *p_data++ = p_rsp->pdu;
   1338 
   1339   switch (opcode) {
   1340     case AVRC_OP_VENDOR:
   1341       /* reserved 0, packet_type 0 */
   1342       UINT8_TO_BE_STREAM(p_data, 0);
   1343     /* continue to the next "case to add length */
   1344 
   1345     case AVRC_OP_BROWSE:
   1346       /* add fixed lenth - 0 */
   1347       UINT16_TO_BE_STREAM(p_data, 0);
   1348       break;
   1349   }
   1350 
   1351   p_pkt->len = (p_data - p_start);
   1352   p_rsp->rsp.opcode = opcode;
   1353 
   1354   return p_pkt;
   1355 }
   1356 
   1357 /*******************************************************************************
   1358  *
   1359  * Function         AVRC_BldResponse
   1360  *
   1361  * Description      This function builds the given AVRCP response to the given
   1362  *                  buffer
   1363  *
   1364  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
   1365  *                  Otherwise, the error code.
   1366  *
   1367  ******************************************************************************/
   1368 tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp,
   1369                            BT_HDR** pp_pkt) {
   1370   tAVRC_STS status = AVRC_STS_BAD_PARAM;
   1371   BT_HDR* p_pkt;
   1372   bool alloc = false;
   1373   uint8_t* p;
   1374   uint16_t peer_mtu;
   1375 
   1376   if (!p_rsp || !pp_pkt) {
   1377     AVRC_TRACE_API("%s Invalid parameters passed. p_rsp=%p, pp_pkt=%p",
   1378                    __func__, p_rsp, pp_pkt);
   1379     return AVRC_STS_BAD_PARAM;
   1380   }
   1381 
   1382   if (*pp_pkt == NULL) {
   1383     *pp_pkt = avrc_bld_init_rsp_buffer(p_rsp);
   1384     if (*pp_pkt == NULL) {
   1385       AVRC_TRACE_API("%s Failed to initialize response buffer", __func__);
   1386       return AVRC_STS_INTERNAL_ERR;
   1387     }
   1388 
   1389     if ((*pp_pkt)->layer_specific == AVCT_DATA_BROWSE) {
   1390       p = (uint8_t*)((*pp_pkt) + 1);
   1391       peer_mtu = AVCT_GetBrowseMtu(handle) - AVCT_HDR_LEN_SINGLE;
   1392       UINT16_TO_BE_STREAM(p, peer_mtu);
   1393     }
   1394 
   1395     alloc = true;
   1396   }
   1397   status = AVRC_STS_NO_ERROR;
   1398   p_pkt = *pp_pkt;
   1399 
   1400   AVRC_TRACE_API("%s pdu=%x status=%x", __func__, p_rsp->rsp.pdu,
   1401                  p_rsp->rsp.status);
   1402   if (p_rsp->rsp.status != AVRC_STS_NO_ERROR) {
   1403     return (avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt));
   1404   }
   1405 
   1406   switch (p_rsp->pdu) {
   1407     case AVRC_PDU_NEXT_GROUP:
   1408     case AVRC_PDU_PREV_GROUP:
   1409       status = avrc_bld_group_navigation_rsp(p_rsp->pdu, p_pkt);
   1410       break;
   1411 
   1412     case AVRC_PDU_GET_CAPABILITIES:
   1413       status = avrc_bld_get_capability_rsp(&p_rsp->get_caps, p_pkt);
   1414       break;
   1415 
   1416     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
   1417       status =
   1418           avrc_bld_list_app_settings_attr_rsp(&p_rsp->list_app_attr, p_pkt);
   1419       break;
   1420 
   1421     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
   1422       status =
   1423           avrc_bld_list_app_settings_values_rsp(&p_rsp->list_app_values, p_pkt);
   1424       break;
   1425 
   1426     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
   1427       status = avrc_bld_get_cur_app_setting_value_rsp(&p_rsp->get_cur_app_val,
   1428                                                       p_pkt);
   1429       break;
   1430 
   1431     case AVRC_PDU_SET_PLAYER_APP_VALUE:
   1432       status = avrc_bld_set_app_setting_value_rsp(&p_rsp->set_app_val, p_pkt);
   1433       break;
   1434 
   1435     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
   1436       status = avrc_bld_get_app_setting_attr_text_rsp(&p_rsp->get_app_attr_txt,
   1437                                                       p_pkt);
   1438       break;
   1439 
   1440     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
   1441       status = avrc_bld_get_app_setting_value_text_rsp(&p_rsp->get_app_val_txt,
   1442                                                        p_pkt);
   1443       break;
   1444 
   1445     case AVRC_PDU_INFORM_DISPLAY_CHARSET:
   1446       status = avrc_bld_inform_charset_rsp(&p_rsp->inform_charset, p_pkt);
   1447       break;
   1448 
   1449     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
   1450       status = avrc_bld_inform_battery_status_rsp(&p_rsp->inform_battery_status,
   1451                                                   p_pkt);
   1452       break;
   1453 
   1454     case AVRC_PDU_GET_ELEMENT_ATTR:
   1455       status = avrc_bld_get_elem_attrs_rsp(&p_rsp->get_attrs, p_pkt);
   1456       break;
   1457 
   1458     case AVRC_PDU_GET_PLAY_STATUS:
   1459       status = avrc_bld_get_play_status_rsp(&p_rsp->get_play_status, p_pkt);
   1460       break;
   1461 
   1462     case AVRC_PDU_REGISTER_NOTIFICATION:
   1463       status = avrc_bld_notify_rsp(&p_rsp->reg_notif, p_pkt);
   1464       break;
   1465 
   1466     case AVRC_PDU_REQUEST_CONTINUATION_RSP:
   1467       status = avrc_bld_next_rsp(&p_rsp->continu, p_pkt);
   1468       break;
   1469 
   1470     case AVRC_PDU_ABORT_CONTINUATION_RSP:
   1471       status = avrc_bld_next_rsp(&p_rsp->abort, p_pkt);
   1472       break;
   1473 
   1474     case AVRC_PDU_SET_ADDRESSED_PLAYER:
   1475       status = avrc_bld_set_addr_player_rsp(&p_rsp->addr_player, p_pkt);
   1476       break;
   1477 
   1478     case AVRC_PDU_PLAY_ITEM:
   1479       status = avrc_bld_play_item_rsp(&p_rsp->play_item, p_pkt);
   1480       break;
   1481 
   1482     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
   1483       status = avrc_bld_set_absolute_volume_rsp(p_rsp->volume.volume, p_pkt);
   1484       break;
   1485 
   1486     case AVRC_PDU_ADD_TO_NOW_PLAYING:
   1487       status = avrc_bld_add_to_now_playing_rsp(&p_rsp->add_to_play, p_pkt);
   1488       break;
   1489 
   1490     case AVRC_PDU_SET_BROWSED_PLAYER:
   1491       status = avrc_bld_set_browsed_player_rsp(&p_rsp->br_player, p_pkt);
   1492       break;
   1493 
   1494     case AVRC_PDU_GET_FOLDER_ITEMS:
   1495       status = avrc_bld_get_folder_items_rsp(&p_rsp->get_items, p_pkt);
   1496       break;
   1497 
   1498     case AVRC_PDU_CHANGE_PATH:
   1499       status = avrc_bld_change_path_rsp(&p_rsp->chg_path, p_pkt);
   1500       break;
   1501 
   1502     case AVRC_PDU_GET_ITEM_ATTRIBUTES:
   1503       status = avrc_bld_get_item_attrs_rsp(&p_rsp->get_attrs, p_pkt);
   1504       break;
   1505 
   1506     case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS:
   1507       status = avrc_bld_get_num_of_item_rsp(&p_rsp->get_num_of_items, p_pkt);
   1508       break;
   1509 
   1510     case AVRC_PDU_SEARCH:
   1511       status = avrc_bld_search_rsp(&p_rsp->search, p_pkt);
   1512       break;
   1513   }
   1514 
   1515   if (alloc && (status != AVRC_STS_NO_ERROR)) {
   1516     osi_free(p_pkt);
   1517     *pp_pkt = NULL;
   1518   }
   1519   AVRC_TRACE_API("%s returning %d", __func__, status);
   1520   return status;
   1521 }
   1522 
   1523 #endif /* (AVRC_METADATA_INCLUDED == true)*/
   1524