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