Home | History | Annotate | Download | only in avrc
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2003-2013 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 #include <string.h>
     19 
     20 #include "gki.h"
     21 #include "avrc_api.h"
     22 #include "avrc_defs.h"
     23 #include "avrc_int.h"
     24 #include "bt_utils.h"
     25 
     26 /*****************************************************************************
     27 **  Global data
     28 *****************************************************************************/
     29 #if (AVRC_METADATA_INCLUDED == TRUE)
     30 
     31 /*******************************************************************************
     32 **
     33 ** Function         avrc_bld_get_capability_rsp
     34 **
     35 ** Description      This function builds the Get Capability response.
     36 **
     37 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
     38 **                  Otherwise, the error code.
     39 **
     40 *******************************************************************************/
     41 static tAVRC_STS avrc_bld_get_capability_rsp (tAVRC_GET_CAPS_RSP *p_rsp, BT_HDR *p_pkt)
     42 {
     43     UINT8   *p_data, *p_start, *p_len, *p_count;
     44     UINT16  len = 0;
     45     UINT8   xx;
     46     UINT32  *p_company_id;
     47     UINT8   *p_event_id;
     48     tAVRC_STS status = AVRC_STS_NO_ERROR;
     49 
     50     if (!(AVRC_IS_VALID_CAP_ID(p_rsp->capability_id)))
     51     {
     52         AVRC_TRACE_ERROR("avrc_bld_get_capability_rsp bad parameter. p_rsp: %x", p_rsp);
     53         status = AVRC_STS_BAD_PARAM;
     54         return status;
     55     }
     56 
     57     AVRC_TRACE_API("avrc_bld_get_capability_rsp");
     58     /* get the existing length, if any, and also the num attributes */
     59     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
     60     p_data = p_len = p_start + 2; /* pdu + rsvd */
     61 
     62     BE_STREAM_TO_UINT16(len, p_data);
     63     UINT8_TO_BE_STREAM(p_data, p_rsp->capability_id);
     64     p_count = p_data;
     65 
     66     if (len == 0)
     67     {
     68         *p_count = p_rsp->count;
     69         p_data++;
     70         len = 2; /* move past the capability_id and count */
     71     }
     72     else
     73     {
     74         p_data = p_start + p_pkt->len;
     75         *p_count += p_rsp->count;
     76     }
     77 
     78     if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID)
     79     {
     80         p_company_id = p_rsp->param.company_id;
     81         for (xx=0; xx< p_rsp->count; xx++)
     82         {
     83             UINT24_TO_BE_STREAM(p_data, p_company_id[xx]);
     84         }
     85         len += p_rsp->count * 3;
     86     }
     87     else
     88     {
     89         p_event_id = p_rsp->param.event_id;
     90         *p_count = 0;
     91         for (xx=0; xx< p_rsp->count; xx++)
     92         {
     93             if (AVRC_IS_VALID_EVENT_ID(p_event_id[xx]))
     94             {
     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 (tAVRC_LIST_APP_ATTR_RSP *p_rsp, BT_HDR *p_pkt)
    120 {
    121     UINT8   *p_data, *p_start, *p_len, *p_num;
    122     UINT16  len = 0;
    123     UINT8   xx;
    124 
    125     AVRC_TRACE_API("avrc_bld_list_app_settings_attr_rsp");
    126     /* get the existing length, if any, and also the num attributes */
    127     p_start = (UINT8 *)(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     {
    134         /* first time initialize the attribute count */
    135         *p_num = 0;
    136         p_data++;
    137     }
    138     else
    139     {
    140         p_data = p_start + p_pkt->len;
    141     }
    142 
    143     for (xx=0; xx<p_rsp->num_attr; xx++)
    144     {
    145         if(AVRC_IsValidPlayerAttr(p_rsp->attrs[xx]))
    146         {
    147             (*p_num)++;
    148             UINT8_TO_BE_STREAM(p_data, p_rsp->attrs[xx]);
    149         }
    150     }
    151 
    152     len = *p_num + 1;
    153     UINT16_TO_BE_STREAM(p_len, len);
    154     p_pkt->len = (p_data - p_start);
    155 
    156     return AVRC_STS_NO_ERROR;
    157 }
    158 
    159 /*******************************************************************************
    160 **
    161 ** Function         avrc_bld_list_app_settings_values_rsp
    162 **
    163 ** Description      This function builds the List Application Setting Values
    164 **                  response.
    165 **
    166 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    167 **                  Otherwise, the error code.
    168 **
    169 *******************************************************************************/
    170 static tAVRC_STS avrc_bld_list_app_settings_values_rsp (tAVRC_LIST_APP_VALUES_RSP *p_rsp,
    171     BT_HDR *p_pkt)
    172 {
    173     UINT8   *p_data, *p_start, *p_len, *p_num;
    174     UINT8   xx;
    175     UINT16  len;
    176 
    177     AVRC_TRACE_API("avrc_bld_list_app_settings_values_rsp");
    178 
    179     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    180     p_data = p_len = p_start + 2; /* pdu + rsvd */
    181 
    182     /* get the existing length, if any, and also the num attributes */
    183     BE_STREAM_TO_UINT16(len, p_data);
    184     p_num = p_data;
    185     /* first time initialize the attribute count */
    186     if (len == 0)
    187     {
    188         *p_num = p_rsp->num_val;
    189         p_data++;
    190     }
    191     else
    192     {
    193         p_data = p_start + p_pkt->len;
    194         *p_num += p_rsp->num_val;
    195     }
    196 
    197 
    198     for (xx=0; xx<p_rsp->num_val; xx++)
    199     {
    200         UINT8_TO_BE_STREAM(p_data, p_rsp->vals[xx]);
    201     }
    202 
    203     len = *p_num + 1;
    204     UINT16_TO_BE_STREAM(p_len, len);
    205     p_pkt->len = (p_data - p_start);
    206     return AVRC_STS_NO_ERROR;
    207 }
    208 
    209 /*******************************************************************************
    210 **
    211 ** Function         avrc_bld_get_cur_app_setting_value_rsp
    212 **
    213 ** Description      This function builds the Get Current Application Setting Value
    214 **                  response.
    215 **
    216 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    217 **                  Otherwise, the error code.
    218 **
    219 *******************************************************************************/
    220 static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp (tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp,
    221     BT_HDR *p_pkt)
    222 {
    223     UINT8   *p_data, *p_start, *p_len, *p_count;
    224     UINT16  len;
    225     UINT8   xx;
    226 
    227     if (!p_rsp->p_vals)
    228     {
    229         AVRC_TRACE_ERROR("avrc_bld_get_cur_app_setting_value_rsp NULL parameter");
    230         return AVRC_STS_BAD_PARAM;
    231     }
    232 
    233     AVRC_TRACE_API("avrc_bld_get_cur_app_setting_value_rsp");
    234     /* get the existing length, if any, and also the num attributes */
    235     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    236     p_data = p_len = p_start + 2; /* pdu + rsvd */
    237 
    238     BE_STREAM_TO_UINT16(len, p_data);
    239     p_count = p_data;
    240     if (len == 0)
    241     {
    242         /* first time initialize the attribute count */
    243         *p_count = 0;
    244         p_data++;
    245     }
    246     else
    247     {
    248         p_data = p_start + p_pkt->len;
    249     }
    250 
    251     for (xx=0; xx<p_rsp->num_val; xx++)
    252     {
    253         if (avrc_is_valid_player_attrib_value(p_rsp->p_vals[xx].attr_id, p_rsp->p_vals[xx].attr_val))
    254         {
    255             (*p_count)++;
    256             UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_id);
    257             UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_val);
    258         }
    259     }
    260     len = ((*p_count) << 1) + 1;
    261     UINT16_TO_BE_STREAM(p_len, len);
    262     p_pkt->len = (p_data - p_start);
    263 
    264     return AVRC_STS_NO_ERROR;
    265 }
    266 
    267 /*******************************************************************************
    268 **
    269 ** Function         avrc_bld_set_app_setting_value_rsp
    270 **
    271 ** Description      This function builds the Set Application Setting Value
    272 **                  response.
    273 **
    274 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    275 **                  Otherwise, the error code.
    276 **
    277 *******************************************************************************/
    278 static tAVRC_STS avrc_bld_set_app_setting_value_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    279 {
    280     UNUSED(p_rsp);
    281     UNUSED(p_pkt);
    282 
    283     /* nothing to be added. */
    284     AVRC_TRACE_API("avrc_bld_set_app_setting_value_rsp");
    285     return AVRC_STS_NO_ERROR;
    286 }
    287 
    288 /*******************************************************************************
    289 **
    290 ** Function         avrc_bld_app_setting_text_rsp
    291 **
    292 ** Description      This function builds the Get Application Settings Attribute Text
    293 **                  or Get Application Settings Value Text response.
    294 **
    295 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    296 **                  Otherwise, the error code.
    297 **
    298 *******************************************************************************/
    299 static tAVRC_STS avrc_bld_app_setting_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp, BT_HDR *p_pkt)
    300 {
    301     UINT8   *p_data, *p_start, *p_len, *p_count;
    302     UINT16  len, len_left;
    303     UINT8   xx;
    304     tAVRC_STS   sts = AVRC_STS_NO_ERROR;
    305     UINT8       num_added = 0;
    306 
    307     if (!p_rsp->p_attrs)
    308     {
    309         AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp NULL parameter");
    310         return AVRC_STS_BAD_PARAM;
    311     }
    312     /* get the existing length, if any, and also the num attributes */
    313     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    314     p_data = p_len = p_start + 2; /* pdu + rsvd */
    315     len_left = GKI_get_buf_size(p_pkt) - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
    316 
    317     BE_STREAM_TO_UINT16(len, p_data);
    318     p_count = p_data;
    319 
    320     if (len == 0)
    321     {
    322         *p_count = 0;
    323         p_data++;
    324     }
    325     else
    326     {
    327         p_data = p_start + p_pkt->len;
    328     }
    329 
    330     for (xx=0; xx<p_rsp->num_attr; xx++)
    331     {
    332         if  (len_left < (p_rsp->p_attrs[xx].str_len + 4))
    333         {
    334             AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp out of room (str_len:%d, left:%d)",
    335                 xx, p_rsp->p_attrs[xx].str_len, len_left);
    336             p_rsp->num_attr = num_added;
    337             sts = AVRC_STS_INTERNAL_ERR;
    338             break;
    339         }
    340         if ( !p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str )
    341         {
    342             AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp NULL attr text[%d]", xx);
    343             continue;
    344         }
    345         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
    346         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
    347         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
    348         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str, p_rsp->p_attrs[xx].str_len);
    349         (*p_count)++;
    350         num_added++;
    351     }
    352     len = p_data - p_count;
    353     UINT16_TO_BE_STREAM(p_len, len);
    354     p_pkt->len = (p_data - p_start);
    355 
    356     return sts;
    357 }
    358 
    359 /*******************************************************************************
    360 **
    361 ** Function         avrc_bld_get_app_setting_attr_text_rsp
    362 **
    363 ** Description      This function builds the Get Application Setting Attribute Text
    364 **                  response.
    365 **
    366 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    367 **                  Otherwise, the error code.
    368 **
    369 *******************************************************************************/
    370 static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
    371     BT_HDR *p_pkt)
    372 {
    373     AVRC_TRACE_API("avrc_bld_get_app_setting_attr_text_rsp");
    374     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
    375 }
    376 
    377 /*******************************************************************************
    378 **
    379 ** Function         avrc_bld_get_app_setting_value_text_rsp
    380 **
    381 ** Description      This function builds the Get Application Setting Value Text
    382 **                  response.
    383 **
    384 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    385 **                  Otherwise, the error code.
    386 **
    387 *******************************************************************************/
    388 static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
    389     BT_HDR *p_pkt)
    390 {
    391     AVRC_TRACE_API("avrc_bld_get_app_setting_value_text_rsp");
    392     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
    393 }
    394 
    395 /*******************************************************************************
    396 **
    397 ** Function         avrc_bld_inform_charset_rsp
    398 **
    399 ** Description      This function builds the Inform Displayable Character Set
    400 **                  response.
    401 **
    402 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    403 **                  Otherwise, the error code.
    404 **
    405 *******************************************************************************/
    406 static tAVRC_STS avrc_bld_inform_charset_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    407 {
    408     UNUSED(p_rsp);
    409     UNUSED(p_pkt);
    410 
    411     /* nothing to be added. */
    412     AVRC_TRACE_API("avrc_bld_inform_charset_rsp");
    413     return AVRC_STS_NO_ERROR;
    414 }
    415 
    416 /*******************************************************************************
    417 **
    418 ** Function         avrc_bld_inform_battery_status_rsp
    419 **
    420 ** Description      This function builds the Inform Battery Status
    421 **                  response.
    422 **
    423 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    424 **                  Otherwise, the error code.
    425 **
    426 *******************************************************************************/
    427 static tAVRC_STS avrc_bld_inform_battery_status_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    428 {
    429     UNUSED(p_rsp);
    430     UNUSED(p_pkt);
    431 
    432     /* nothing to be added. */
    433     AVRC_TRACE_API("avrc_bld_inform_battery_status_rsp");
    434     return AVRC_STS_NO_ERROR;
    435 }
    436 
    437 /*******************************************************************************
    438 **
    439 ** Function         avrc_bld_get_elem_attrs_rsp
    440 **
    441 ** Description      This function builds the Get Element Attributes
    442 **                  response.
    443 **
    444 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    445 **                  Otherwise, the error code.
    446 **
    447 *******************************************************************************/
    448 static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, BT_HDR *p_pkt)
    449 {
    450     UINT8   *p_data, *p_start, *p_len, *p_count;
    451     UINT16  len;
    452     UINT8   xx;
    453 
    454     AVRC_TRACE_API("avrc_bld_get_elem_attrs_rsp");
    455     if (!p_rsp->p_attrs)
    456     {
    457         AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp NULL parameter");
    458         return AVRC_STS_BAD_PARAM;
    459     }
    460 
    461     /* get the existing length, if any, and also the num attributes */
    462     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    463     p_data = p_len = p_start + 2; /* pdu + rsvd */
    464 
    465     BE_STREAM_TO_UINT16(len, p_data);
    466     p_count = p_data;
    467 
    468     if (len == 0)
    469     {
    470         *p_count = 0;
    471         p_data++;
    472     }
    473     else
    474     {
    475         p_data = p_start + p_pkt->len;
    476     }
    477 
    478     for (xx=0; xx<p_rsp->num_attr; xx++)
    479     {
    480         if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_rsp->p_attrs[xx].attr_id))
    481         {
    482             AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp invalid attr id[%d]: %d", xx, p_rsp->p_attrs[xx].attr_id);
    483             continue;
    484         }
    485         if ( !p_rsp->p_attrs[xx].name.p_str )
    486         {
    487             p_rsp->p_attrs[xx].name.str_len = 0;
    488         }
    489         UINT32_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
    490         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.charset_id);
    491         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.str_len);
    492         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, p_rsp->p_attrs[xx].name.str_len);
    493         (*p_count)++;
    494     }
    495     len = p_data - p_count;
    496     UINT16_TO_BE_STREAM(p_len, len);
    497     p_pkt->len = (p_data - p_start);
    498     return AVRC_STS_NO_ERROR;
    499 }
    500 
    501 /*******************************************************************************
    502 **
    503 ** Function         avrc_bld_get_play_status_rsp
    504 **
    505 ** Description      This function builds the Get Play Status
    506 **                  response.
    507 **
    508 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    509 **                  Otherwise, the error code.
    510 **
    511 *******************************************************************************/
    512 static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp, BT_HDR *p_pkt)
    513 {
    514     UINT8   *p_data, *p_start;
    515 
    516     AVRC_TRACE_API("avrc_bld_get_play_status_rsp");
    517     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    518     p_data = p_start + 2;
    519 
    520     /* add fixed lenth - song len(4) + song position(4) + status(1) */
    521     UINT16_TO_BE_STREAM(p_data, 9);
    522     UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
    523     UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
    524     UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
    525     p_pkt->len = (p_data - p_start);
    526 
    527     return AVRC_STS_NO_ERROR;
    528 }
    529 
    530 /*******************************************************************************
    531 **
    532 ** Function         avrc_bld_notify_rsp
    533 **
    534 ** Description      This function builds the Notification response.
    535 **
    536 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    537 **                  Otherwise, the error code.
    538 **
    539 *******************************************************************************/
    540 static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
    541 {
    542     UINT8   *p_data, *p_start;
    543     UINT8   *p_len;
    544     UINT16  len = 0;
    545     UINT8   xx;
    546     tAVRC_STS status = AVRC_STS_NO_ERROR;
    547 
    548     AVRC_TRACE_API("avrc_bld_notify_rsp");
    549 
    550     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    551     p_data = p_len = p_start + 2; /* pdu + rsvd */
    552     p_data += 2;
    553 
    554     UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
    555     switch (p_rsp->event_id)
    556     {
    557     case AVRC_EVT_PLAY_STATUS_CHANGE:       /* 0x01 */
    558         /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always TRUE */
    559         if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
    560             (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR) )
    561         {
    562             UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
    563             len = 2;
    564         }
    565         else
    566         {
    567             AVRC_TRACE_ERROR("bad play state");
    568             status = AVRC_STS_BAD_PARAM;
    569         }
    570         break;
    571 
    572     case AVRC_EVT_TRACK_CHANGE:             /* 0x02 */
    573         ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
    574         len = (UINT8)(AVRC_UID_SIZE + 1);
    575         break;
    576 
    577     case AVRC_EVT_TRACK_REACHED_END:        /* 0x03 */
    578     case AVRC_EVT_TRACK_REACHED_START:      /* 0x04 */
    579         len = 1;
    580         break;
    581 
    582     case AVRC_EVT_PLAY_POS_CHANGED:         /* 0x05 */
    583         UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
    584         len = 5;
    585         break;
    586 
    587     case AVRC_EVT_BATTERY_STATUS_CHANGE:    /* 0x06 */
    588         if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status))
    589         {
    590             UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
    591             len = 2;
    592         }
    593         else
    594         {
    595             AVRC_TRACE_ERROR("bad battery status");
    596             status = AVRC_STS_BAD_PARAM;
    597         }
    598         break;
    599 
    600     case AVRC_EVT_SYSTEM_STATUS_CHANGE:     /* 0x07 */
    601         if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status))
    602         {
    603             UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
    604             len = 2;
    605         }
    606         else
    607         {
    608             AVRC_TRACE_ERROR("bad system status");
    609             status = AVRC_STS_BAD_PARAM;
    610         }
    611         break;
    612 
    613     case AVRC_EVT_APP_SETTING_CHANGE:       /* 0x08 */
    614         if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS)
    615             p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
    616 
    617         if (p_rsp->param.player_setting.num_attr > 0)
    618         {
    619             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
    620             len = 2;
    621             for (xx=0; xx<p_rsp->param.player_setting.num_attr; xx++)
    622             {
    623                 if (avrc_is_valid_player_attrib_value(p_rsp->param.player_setting.attr_id[xx],
    624                     p_rsp->param.player_setting.attr_value[xx]))
    625                 {
    626                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
    627                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
    628                 }
    629                 else
    630                 {
    631                     AVRC_TRACE_ERROR("bad player app seeting attribute or value");
    632                     status = AVRC_STS_BAD_PARAM;
    633                     break;
    634                 }
    635                 len += 2;
    636             }
    637         }
    638         else
    639             status = AVRC_STS_BAD_PARAM;
    640         break;
    641 
    642     default:
    643         status = AVRC_STS_BAD_PARAM;
    644         AVRC_TRACE_ERROR("unknown event_id");
    645     }
    646 
    647     UINT16_TO_BE_STREAM(p_len, len);
    648     p_pkt->len = (p_data - p_start);
    649 
    650     return status;
    651 }
    652 
    653 /*******************************************************************************
    654 **
    655 ** Function         avrc_bld_next_rsp
    656 **
    657 ** Description      This function builds the Request Continue or Abort
    658 **                  response.
    659 **
    660 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    661 **                  Otherwise, the error code.
    662 **
    663 *******************************************************************************/
    664 static tAVRC_STS avrc_bld_next_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    665 {
    666     UNUSED(p_rsp);
    667     UNUSED(p_pkt);
    668 
    669     /* nothing to be added. */
    670     AVRC_TRACE_API("avrc_bld_next_rsp");
    671     return AVRC_STS_NO_ERROR;
    672 }
    673 
    674 /*******************************************************************************
    675 **
    676 ** Function         avrc_bld_group_navigation_rsp
    677 **
    678 ** Description      This function builds the Group Navigation
    679 **                  response.
    680 **
    681 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    682 **                  Otherwise, the error code.
    683 **
    684 *******************************************************************************/
    685 tAVRC_STS avrc_bld_group_navigation_rsp (UINT16 navi_id, BT_HDR *p_pkt)
    686 {
    687     UINT8   *p_data;
    688 
    689     if (!AVRC_IS_VALID_GROUP(navi_id))
    690     {
    691         AVRC_TRACE_ERROR("avrc_bld_group_navigation_rsp bad navigation op id: %d", navi_id);
    692         return AVRC_STS_BAD_PARAM;
    693     }
    694 
    695     AVRC_TRACE_API("avrc_bld_group_navigation_rsp");
    696     p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
    697     UINT16_TO_BE_STREAM(p_data, navi_id);
    698     p_pkt->len = 2;
    699     return AVRC_STS_NO_ERROR;
    700 }
    701 
    702 /*******************************************************************************
    703 **
    704 ** Function         avrc_bld_rejected_rsp
    705 **
    706 ** Description      This function builds the General Response response.
    707 **
    708 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    709 **                  Otherwise, the error code.
    710 **
    711 *******************************************************************************/
    712 static tAVRC_STS avrc_bld_rejected_rsp( tAVRC_RSP *p_rsp, BT_HDR *p_pkt )
    713 {
    714     UINT8 *p_data, *p_start;
    715 
    716     AVRC_TRACE_API("avrc_bld_rejected_rsp: status=%d, pdu:x%x", p_rsp->status, p_rsp->pdu);
    717 
    718     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    719     p_data = p_start + 2;
    720     AVRC_TRACE_DEBUG("pdu:x%x", *p_start);
    721 
    722     UINT16_TO_BE_STREAM(p_data, 1);
    723     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    724     p_pkt->len = p_data - p_start;
    725 
    726     return AVRC_STS_NO_ERROR;
    727 }
    728 
    729 /*******************************************************************************
    730 **
    731 ** Function         avrc_bld_init_rsp_buffer
    732 **
    733 ** Description      This function initializes the response buffer based on PDU
    734 **
    735 ** Returns          NULL, if no GKI buffer or failure to build the message.
    736 **                  Otherwise, the GKI buffer that contains the initialized message.
    737 **
    738 *******************************************************************************/
    739 static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
    740 {
    741     UINT16 offset = AVRC_MSG_PASS_THRU_OFFSET, chnl = AVCT_DATA_CTRL, len=AVRC_META_CMD_POOL_SIZE;
    742     BT_HDR *p_pkt=NULL;
    743     UINT8  opcode = avrc_opcode_from_pdu(p_rsp->pdu);
    744 
    745     AVRC_TRACE_API("avrc_bld_init_rsp_buffer: pdu=%x, opcode=%x/%x", p_rsp->pdu, opcode,
    746         p_rsp->rsp.opcode);
    747     if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
    748         avrc_is_valid_opcode(p_rsp->rsp.opcode))
    749     {
    750         opcode = p_rsp->rsp.opcode;
    751         AVRC_TRACE_API("opcode=%x", opcode);
    752     }
    753 
    754     switch (opcode)
    755     {
    756     case AVRC_OP_PASS_THRU:
    757         offset  = AVRC_MSG_PASS_THRU_OFFSET;
    758         break;
    759 
    760     case AVRC_OP_VENDOR:
    761         offset  = AVRC_MSG_VENDOR_OFFSET;
    762         if (p_rsp->pdu == AVRC_PDU_GET_ELEMENT_ATTR)
    763             len     = AVRC_BROWSE_POOL_SIZE;
    764         break;
    765     }
    766 
    767     /* allocate and initialize the buffer */
    768     p_pkt = (BT_HDR *)GKI_getbuf(len);
    769     if (p_pkt)
    770     {
    771         UINT8 *p_data, *p_start;
    772 
    773         p_pkt->layer_specific = chnl;
    774         p_pkt->event    = opcode;
    775         p_pkt->offset   = offset;
    776         p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    777         p_start = p_data;
    778 
    779         /* pass thru - group navigation - has a two byte op_id, so dont do it here */
    780         if (opcode != AVRC_OP_PASS_THRU)
    781             *p_data++ = p_rsp->pdu;
    782 
    783         switch (opcode)
    784         {
    785         case AVRC_OP_VENDOR:
    786             /* reserved 0, packet_type 0 */
    787             UINT8_TO_BE_STREAM(p_data, 0);
    788             /* continue to the next "case to add length */
    789             /* add fixed lenth - 0 */
    790             UINT16_TO_BE_STREAM(p_data, 0);
    791             break;
    792         }
    793 
    794         p_pkt->len = (p_data - p_start);
    795     }
    796     p_rsp->rsp.opcode = opcode;
    797     return p_pkt;
    798 }
    799 
    800 /*******************************************************************************
    801 **
    802 ** Function         AVRC_BldResponse
    803 **
    804 ** Description      This function builds the given AVRCP response to the given
    805 **                  GKI buffer
    806 **
    807 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    808 **                  Otherwise, the error code.
    809 **
    810 *******************************************************************************/
    811 tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt)
    812 {
    813     tAVRC_STS status = AVRC_STS_BAD_PARAM;
    814     BT_HDR *p_pkt;
    815     BOOLEAN alloc = FALSE;
    816     UNUSED(handle);
    817 
    818     if (!p_rsp || !pp_pkt)
    819     {
    820         AVRC_TRACE_API("AVRC_BldResponse. Invalid parameters passed. p_rsp=%p, pp_pkt=%p",
    821             p_rsp, pp_pkt);
    822         return AVRC_STS_BAD_PARAM;
    823     }
    824 
    825     if (*pp_pkt == NULL)
    826     {
    827         if ((*pp_pkt = avrc_bld_init_rsp_buffer(p_rsp)) == NULL)
    828         {
    829             AVRC_TRACE_API("AVRC_BldResponse: Failed to initialize response buffer");
    830             return AVRC_STS_INTERNAL_ERR;
    831         }
    832         alloc = TRUE;
    833     }
    834     status = AVRC_STS_NO_ERROR;
    835     p_pkt = *pp_pkt;
    836 
    837     AVRC_TRACE_API("AVRC_BldResponse: pdu=%x status=%x", p_rsp->rsp.pdu, p_rsp->rsp.status);
    838     if (p_rsp->rsp.status != AVRC_STS_NO_ERROR)
    839     {
    840         return( avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt) );
    841     }
    842 
    843     switch (p_rsp->pdu)
    844     {
    845     case AVRC_PDU_NEXT_GROUP:
    846     case AVRC_PDU_PREV_GROUP:
    847         status = avrc_bld_group_navigation_rsp(p_rsp->pdu, p_pkt);
    848         break;
    849 
    850     case AVRC_PDU_GET_CAPABILITIES:
    851         status = avrc_bld_get_capability_rsp(&p_rsp->get_caps, p_pkt);
    852         break;
    853 
    854     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
    855         status = avrc_bld_list_app_settings_attr_rsp(&p_rsp->list_app_attr, p_pkt);
    856         break;
    857 
    858     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
    859         status = avrc_bld_list_app_settings_values_rsp(&p_rsp->list_app_values, p_pkt);
    860         break;
    861 
    862     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
    863         status = avrc_bld_get_cur_app_setting_value_rsp(&p_rsp->get_cur_app_val, p_pkt);
    864         break;
    865 
    866     case AVRC_PDU_SET_PLAYER_APP_VALUE:
    867         status = avrc_bld_set_app_setting_value_rsp(&p_rsp->set_app_val, p_pkt);
    868         break;
    869 
    870     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
    871         status = avrc_bld_get_app_setting_attr_text_rsp(&p_rsp->get_app_attr_txt, p_pkt);
    872         break;
    873 
    874     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
    875         status = avrc_bld_get_app_setting_value_text_rsp(&p_rsp->get_app_val_txt, p_pkt);
    876         break;
    877 
    878     case AVRC_PDU_INFORM_DISPLAY_CHARSET:
    879         status = avrc_bld_inform_charset_rsp(&p_rsp->inform_charset, p_pkt);
    880         break;
    881 
    882     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
    883         status = avrc_bld_inform_battery_status_rsp(&p_rsp->inform_battery_status, p_pkt);
    884         break;
    885 
    886     case AVRC_PDU_GET_ELEMENT_ATTR:
    887         status = avrc_bld_get_elem_attrs_rsp(&p_rsp->get_elem_attrs, p_pkt);
    888         break;
    889 
    890     case AVRC_PDU_GET_PLAY_STATUS:
    891         status = avrc_bld_get_play_status_rsp(&p_rsp->get_play_status, p_pkt);
    892         break;
    893 
    894     case AVRC_PDU_REGISTER_NOTIFICATION:
    895         status = avrc_bld_notify_rsp(&p_rsp->reg_notif, p_pkt);
    896         break;
    897 
    898     case AVRC_PDU_REQUEST_CONTINUATION_RSP:     /*        0x40 */
    899         status = avrc_bld_next_rsp(&p_rsp->continu, p_pkt);
    900         break;
    901 
    902     case AVRC_PDU_ABORT_CONTINUATION_RSP:       /*          0x41 */
    903         status = avrc_bld_next_rsp(&p_rsp->abort, p_pkt);
    904         break;
    905     }
    906 
    907     if (alloc && (status != AVRC_STS_NO_ERROR) )
    908     {
    909         GKI_freebuf(p_pkt);
    910         *pp_pkt = NULL;
    911     }
    912     AVRC_TRACE_API("AVRC_BldResponse: returning %d", status);
    913     return status;
    914 }
    915 
    916 #endif /* (AVRC_METADATA_INCLUDED == TRUE)*/
    917 
    918