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