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 "bt_common.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("%s bad parameter. p_rsp: %x", __func__, p_rsp);
     53         status = AVRC_STS_BAD_PARAM;
     54         return status;
     55     }
     56 
     57     AVRC_TRACE_API("%s", __func__);
     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("%s", __func__);
    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("%s", __func__);
    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("%s NULL parameter", __func__);
    230         return AVRC_STS_BAD_PARAM;
    231     }
    232 
    233     AVRC_TRACE_API("%s", __func__);
    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("%s", __func__);
    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("%s NULL parameter", __func__);
    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 
    316     /*
    317      * NOTE: The buffer is allocated within avrc_bld_init_rsp_buffer(), and is
    318      * always of size BT_DEFAULT_BUFFER_SIZE.
    319      */
    320     len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
    321 
    322     BE_STREAM_TO_UINT16(len, p_data);
    323     p_count = p_data;
    324 
    325     if (len == 0)
    326     {
    327         *p_count = 0;
    328         p_data++;
    329     }
    330     else
    331     {
    332         p_data = p_start + p_pkt->len;
    333     }
    334 
    335     for (xx=0; xx<p_rsp->num_attr; xx++)
    336     {
    337         if  (len_left < (p_rsp->p_attrs[xx].str_len + 4))
    338         {
    339             AVRC_TRACE_ERROR("%s out of room (str_len:%d, left:%d)",
    340                              __func__, xx, p_rsp->p_attrs[xx].str_len, len_left);
    341             p_rsp->num_attr = num_added;
    342             sts = AVRC_STS_INTERNAL_ERR;
    343             break;
    344         }
    345         if ( !p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str )
    346         {
    347             AVRC_TRACE_ERROR("%s NULL attr text[%d]", __func__, xx);
    348             continue;
    349         }
    350         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
    351         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
    352         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
    353         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str, p_rsp->p_attrs[xx].str_len);
    354         (*p_count)++;
    355         num_added++;
    356     }
    357     len = p_data - p_count;
    358     UINT16_TO_BE_STREAM(p_len, len);
    359     p_pkt->len = (p_data - p_start);
    360 
    361     return sts;
    362 }
    363 
    364 /*******************************************************************************
    365 **
    366 ** Function         avrc_bld_get_app_setting_attr_text_rsp
    367 **
    368 ** Description      This function builds the Get Application Setting Attribute Text
    369 **                  response.
    370 **
    371 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    372 **                  Otherwise, the error code.
    373 **
    374 *******************************************************************************/
    375 static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
    376     BT_HDR *p_pkt)
    377 {
    378     AVRC_TRACE_API("%s", __func__);
    379     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
    380 }
    381 
    382 /*******************************************************************************
    383 **
    384 ** Function         avrc_bld_get_app_setting_value_text_rsp
    385 **
    386 ** Description      This function builds the Get Application Setting Value Text
    387 **                  response.
    388 **
    389 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    390 **                  Otherwise, the error code.
    391 **
    392 *******************************************************************************/
    393 static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
    394     BT_HDR *p_pkt)
    395 {
    396     AVRC_TRACE_API("%s", __func__);
    397     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
    398 }
    399 
    400 /*******************************************************************************
    401 **
    402 ** Function         avrc_bld_inform_charset_rsp
    403 **
    404 ** Description      This function builds the Inform Displayable Character Set
    405 **                  response.
    406 **
    407 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    408 **                  Otherwise, the error code.
    409 **
    410 *******************************************************************************/
    411 static tAVRC_STS avrc_bld_inform_charset_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    412 {
    413     UNUSED(p_rsp);
    414     UNUSED(p_pkt);
    415 
    416     /* nothing to be added. */
    417     AVRC_TRACE_API("%s", __func__);
    418     return AVRC_STS_NO_ERROR;
    419 }
    420 
    421 /*******************************************************************************
    422 **
    423 ** Function         avrc_bld_inform_battery_status_rsp
    424 **
    425 ** Description      This function builds the Inform Battery Status
    426 **                  response.
    427 **
    428 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    429 **                  Otherwise, the error code.
    430 **
    431 *******************************************************************************/
    432 static tAVRC_STS avrc_bld_inform_battery_status_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    433 {
    434     UNUSED(p_rsp);
    435     UNUSED(p_pkt);
    436 
    437     /* nothing to be added. */
    438     AVRC_TRACE_API("%s", __func__);
    439     return AVRC_STS_NO_ERROR;
    440 }
    441 
    442 /*******************************************************************************
    443 **
    444 ** Function         avrc_bld_get_elem_attrs_rsp
    445 **
    446 ** Description      This function builds the Get Element Attributes
    447 **                  response.
    448 **
    449 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    450 **                  Otherwise, the error code.
    451 **
    452 *******************************************************************************/
    453 static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, BT_HDR *p_pkt)
    454 {
    455     UINT8   *p_data, *p_start, *p_len, *p_count;
    456     UINT16  len;
    457     UINT8   xx;
    458 
    459     AVRC_TRACE_API("%s", __func__);
    460     if (!p_rsp->p_attrs)
    461     {
    462         AVRC_TRACE_ERROR("%s NULL parameter", __func__);
    463         return AVRC_STS_BAD_PARAM;
    464     }
    465 
    466     /* get the existing length, if any, and also the num attributes */
    467     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    468     p_data = p_len = p_start + 2; /* pdu + rsvd */
    469 
    470     BE_STREAM_TO_UINT16(len, p_data);
    471     p_count = p_data;
    472 
    473     if (len == 0)
    474     {
    475         *p_count = 0;
    476         p_data++;
    477     }
    478     else
    479     {
    480         p_data = p_start + p_pkt->len;
    481     }
    482 
    483     for (xx=0; xx<p_rsp->num_attr; xx++)
    484     {
    485         if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_rsp->p_attrs[xx].attr_id))
    486         {
    487             AVRC_TRACE_ERROR("%s invalid attr id[%d]: %d",
    488                              __func__, xx, p_rsp->p_attrs[xx].attr_id);
    489             continue;
    490         }
    491         if ( !p_rsp->p_attrs[xx].name.p_str )
    492         {
    493             p_rsp->p_attrs[xx].name.str_len = 0;
    494         }
    495         UINT32_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
    496         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.charset_id);
    497         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.str_len);
    498         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, p_rsp->p_attrs[xx].name.str_len);
    499         (*p_count)++;
    500     }
    501     len = p_data - p_count;
    502     UINT16_TO_BE_STREAM(p_len, len);
    503     p_pkt->len = (p_data - p_start);
    504     return AVRC_STS_NO_ERROR;
    505 }
    506 
    507 /*******************************************************************************
    508 **
    509 ** Function         avrc_bld_get_play_status_rsp
    510 **
    511 ** Description      This function builds the Get Play Status
    512 **                  response.
    513 **
    514 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    515 **                  Otherwise, the error code.
    516 **
    517 *******************************************************************************/
    518 static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp, BT_HDR *p_pkt)
    519 {
    520     UINT8   *p_data, *p_start;
    521 
    522     AVRC_TRACE_API("avrc_bld_get_play_status_rsp");
    523     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    524     p_data = p_start + 2;
    525 
    526     /* add fixed lenth - song len(4) + song position(4) + status(1) */
    527     UINT16_TO_BE_STREAM(p_data, 9);
    528     UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
    529     UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
    530     UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
    531     p_pkt->len = (p_data - p_start);
    532 
    533     return AVRC_STS_NO_ERROR;
    534 }
    535 
    536 /*******************************************************************************
    537 **
    538 ** Function         avrc_bld_notify_rsp
    539 **
    540 ** Description      This function builds the Notification response.
    541 **
    542 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    543 **                  Otherwise, the error code.
    544 **
    545 *******************************************************************************/
    546 static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
    547 {
    548     UINT8   *p_data, *p_start;
    549     UINT8   *p_len;
    550     UINT16  len = 0;
    551     UINT8   xx;
    552     tAVRC_STS status = AVRC_STS_NO_ERROR;
    553 
    554     AVRC_TRACE_API("%s event_id %d", __func__, p_rsp->event_id);
    555 
    556     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    557     p_data = p_len = p_start + 2; /* pdu + rsvd */
    558     p_data += 2;
    559 
    560     UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
    561     switch (p_rsp->event_id)
    562     {
    563     case AVRC_EVT_PLAY_STATUS_CHANGE:       /* 0x01 */
    564         /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always TRUE */
    565         if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
    566             (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR) )
    567         {
    568             UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
    569             len = 2;
    570         }
    571         else
    572         {
    573             AVRC_TRACE_ERROR("%s bad play state", __func__);
    574             status = AVRC_STS_BAD_PARAM;
    575         }
    576         break;
    577 
    578     case AVRC_EVT_TRACK_CHANGE:             /* 0x02 */
    579         ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
    580         len = (UINT8)(AVRC_UID_SIZE + 1);
    581         break;
    582 
    583     case AVRC_EVT_TRACK_REACHED_END:        /* 0x03 */
    584     case AVRC_EVT_TRACK_REACHED_START:      /* 0x04 */
    585         len = 1;
    586         break;
    587 
    588     case AVRC_EVT_PLAY_POS_CHANGED:         /* 0x05 */
    589         UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
    590         len = 5;
    591         break;
    592 
    593     case AVRC_EVT_BATTERY_STATUS_CHANGE:    /* 0x06 */
    594         if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status))
    595         {
    596             UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
    597             len = 2;
    598         }
    599         else
    600         {
    601             AVRC_TRACE_ERROR("%s bad battery status", __func__);
    602             status = AVRC_STS_BAD_PARAM;
    603         }
    604         break;
    605 
    606     case AVRC_EVT_SYSTEM_STATUS_CHANGE:     /* 0x07 */
    607         if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status))
    608         {
    609             UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
    610             len = 2;
    611         }
    612         else
    613         {
    614             AVRC_TRACE_ERROR("%s bad system status", __func__);
    615             status = AVRC_STS_BAD_PARAM;
    616         }
    617         break;
    618 
    619     case AVRC_EVT_APP_SETTING_CHANGE:       /* 0x08 */
    620         if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS)
    621             p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
    622 
    623         if (p_rsp->param.player_setting.num_attr > 0)
    624         {
    625             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
    626             len = 2;
    627             for (xx=0; xx<p_rsp->param.player_setting.num_attr; xx++)
    628             {
    629                 if (avrc_is_valid_player_attrib_value(p_rsp->param.player_setting.attr_id[xx],
    630                     p_rsp->param.player_setting.attr_value[xx]))
    631                 {
    632                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
    633                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
    634                 }
    635                 else
    636                 {
    637                     AVRC_TRACE_ERROR("%s bad player app seeting attribute or value", __func__);
    638                     status = AVRC_STS_BAD_PARAM;
    639                     break;
    640                 }
    641                 len += 2;
    642             }
    643         }
    644         else
    645             status = AVRC_STS_BAD_PARAM;
    646         break;
    647 
    648     case AVRC_EVT_VOLUME_CHANGE:
    649         len = 2;
    650         UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume));
    651         break;
    652 
    653     default:
    654         status = AVRC_STS_BAD_PARAM;
    655         AVRC_TRACE_ERROR("%s unknown event_id", __func__);
    656     }
    657 
    658     UINT16_TO_BE_STREAM(p_len, len);
    659     p_pkt->len = (p_data - p_start);
    660 
    661     return status;
    662 }
    663 
    664 /*******************************************************************************
    665 **
    666 ** Function         avrc_bld_next_rsp
    667 **
    668 ** Description      This function builds the Request Continue or Abort
    669 **                  response.
    670 **
    671 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    672 **                  Otherwise, the error code.
    673 **
    674 *******************************************************************************/
    675 static tAVRC_STS avrc_bld_next_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    676 {
    677     UNUSED(p_rsp);
    678     UNUSED(p_pkt);
    679 
    680     /* nothing to be added. */
    681     AVRC_TRACE_API("%s", __func__);
    682     return AVRC_STS_NO_ERROR;
    683 }
    684 
    685 /*****************************************************************************
    686 **
    687 ** Function      avrc_bld_set_address_player_rsp
    688 **
    689 ** Description   This function builds the set address player response
    690 **
    691 ** Returns       AVRC_STS_NO_ERROR
    692 **
    693 ******************************************************************************/
    694 static tAVRC_STS avrc_bld_set_address_player_rsp(tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    695 {
    696     AVRC_TRACE_API("%s", __func__);
    697     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    698     /* To calculate length */
    699     UINT8 *p_data = p_start + 2;
    700     /* add fixed lenth status(1) */
    701     UINT16_TO_BE_STREAM(p_data, 1);
    702     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    703     p_pkt->len = (p_data - p_start);
    704     return AVRC_STS_NO_ERROR;
    705 }
    706 
    707 /*****************************************************************************
    708 **
    709 ** Function      avrc_bld_play_item_rsp
    710 **
    711 ** Description   This function builds the play item response
    712 **
    713 ** Returns       AVRC_STS_NO_ERROR, if the response is build successfully
    714 **
    715 ******************************************************************************/
    716 static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
    717 {
    718     AVRC_TRACE_API("%s", __func__);
    719     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    720     /* To calculate length */
    721     UINT8 *p_data = p_start + 2;
    722     /* add fixed lenth status(1) */
    723     UINT16_TO_BE_STREAM(p_data, 1);
    724     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    725     p_pkt->len = (p_data - p_start);
    726     return AVRC_STS_NO_ERROR;
    727 }
    728 
    729 /*****************************************************************************
    730 **
    731 ** Function      avrc_bld_set_absolute_volume_rsp
    732 **
    733 ** Description   This function builds the set absolute volume response
    734 **
    735 ** Returns       AVRC_STS_NO_ERROR, if the response is build successfully
    736 **
    737 ******************************************************************************/
    738 static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, BT_HDR *p_pkt)
    739 {
    740     AVRC_TRACE_API("%s", __func__);
    741     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    742     /* To calculate length */
    743     UINT8 *p_data = p_start + 2;
    744     /* add fixed lenth status(1) */
    745     UINT16_TO_BE_STREAM(p_data, 1);
    746     UINT8_TO_BE_STREAM(p_data, abs_vol);
    747     p_pkt->len = (p_data - p_start);
    748     return AVRC_STS_NO_ERROR;
    749 }
    750 
    751 /*******************************************************************************
    752 **
    753 ** Function         avrc_bld_group_navigation_rsp
    754 **
    755 ** Description      This function builds the Group Navigation
    756 **                  response.
    757 **
    758 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    759 **                  Otherwise, the error code.
    760 **
    761 *******************************************************************************/
    762 tAVRC_STS avrc_bld_group_navigation_rsp (UINT16 navi_id, BT_HDR *p_pkt)
    763 {
    764     if (!AVRC_IS_VALID_GROUP(navi_id))
    765     {
    766         AVRC_TRACE_ERROR("%s bad navigation op id: %d", __func__, navi_id);
    767         return AVRC_STS_BAD_PARAM;
    768     }
    769     AVRC_TRACE_API("%s", __func__);
    770     UINT8 *p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    771     UINT16_TO_BE_STREAM(p_data, navi_id);
    772     p_pkt->len = 2;
    773     return AVRC_STS_NO_ERROR;
    774 }
    775 
    776 /*******************************************************************************
    777 **
    778 ** Function         avrc_bld_rejected_rsp
    779 **
    780 ** Description      This function builds the General Response response.
    781 **
    782 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    783 **
    784 *******************************************************************************/
    785 static tAVRC_STS avrc_bld_rejected_rsp( tAVRC_RSP *p_rsp, BT_HDR *p_pkt )
    786 {
    787     AVRC_TRACE_API("%s: status=%d, pdu:x%x", __func__, p_rsp->status, p_rsp->pdu);
    788 
    789     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    790     UINT8 *p_data = p_start + 2;
    791     AVRC_TRACE_DEBUG("%s pdu:x%x", __func__, *p_start);
    792 
    793     UINT16_TO_BE_STREAM(p_data, 1);
    794     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    795     p_pkt->len = p_data - p_start;
    796 
    797     return AVRC_STS_NO_ERROR;
    798 }
    799 
    800 /*******************************************************************************
    801 **
    802 ** Function         avrc_bld_init_rsp_buffer
    803 **
    804 ** Description      This function initializes the response buffer based on PDU
    805 **
    806 ** Returns          NULL, if no GKI buffer or failure to build the message.
    807 **                  Otherwise, the GKI buffer that contains the initialized message.
    808 **
    809 *******************************************************************************/
    810 static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
    811 {
    812     UINT16 offset = AVRC_MSG_PASS_THRU_OFFSET;
    813     UINT16 chnl = AVCT_DATA_CTRL;
    814     UINT8  opcode = avrc_opcode_from_pdu(p_rsp->pdu);
    815 
    816     AVRC_TRACE_API("%s: pdu=%x, opcode=%x/%x", __func__, p_rsp->pdu, opcode, p_rsp->rsp.opcode);
    817     if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
    818         avrc_is_valid_opcode(p_rsp->rsp.opcode))
    819     {
    820         opcode = p_rsp->rsp.opcode;
    821         AVRC_TRACE_API("%s opcode=%x", __func__, opcode);
    822     }
    823 
    824     switch (opcode)
    825     {
    826     case AVRC_OP_PASS_THRU:
    827         offset = AVRC_MSG_PASS_THRU_OFFSET;
    828         break;
    829 
    830     case AVRC_OP_VENDOR:
    831         offset = AVRC_MSG_VENDOR_OFFSET;
    832         break;
    833     }
    834 
    835     /* allocate and initialize the buffer */
    836     BT_HDR *p_pkt = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
    837     UINT8 *p_data, *p_start;
    838 
    839     p_pkt->layer_specific = chnl;
    840     p_pkt->event    = opcode;
    841     p_pkt->offset   = offset;
    842     p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    843     p_start = p_data;
    844 
    845     /* pass thru - group navigation - has a two byte op_id, so dont do it here */
    846     if (opcode != AVRC_OP_PASS_THRU)
    847         *p_data++ = p_rsp->pdu;
    848 
    849     switch (opcode) {
    850     case AVRC_OP_VENDOR:
    851         /* reserved 0, packet_type 0 */
    852         UINT8_TO_BE_STREAM(p_data, 0);
    853         /* continue to the next "case to add length */
    854         /* add fixed lenth - 0 */
    855         UINT16_TO_BE_STREAM(p_data, 0);
    856         break;
    857     }
    858 
    859     p_pkt->len = (p_data - p_start);
    860     p_rsp->rsp.opcode = opcode;
    861 
    862     return p_pkt;
    863 }
    864 
    865 /*******************************************************************************
    866 **
    867 ** Function         AVRC_BldResponse
    868 **
    869 ** Description      This function builds the given AVRCP response to the given
    870 **                  GKI buffer
    871 **
    872 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
    873 **                  Otherwise, the error code.
    874 **
    875 *******************************************************************************/
    876 tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt)
    877 {
    878     tAVRC_STS status = AVRC_STS_BAD_PARAM;
    879     BT_HDR *p_pkt;
    880     BOOLEAN alloc = FALSE;
    881     UNUSED(handle);
    882 
    883     if (!p_rsp || !pp_pkt)
    884     {
    885         AVRC_TRACE_API("%s Invalid parameters passed. p_rsp=%p, pp_pkt=%p",
    886                        __func__, p_rsp, pp_pkt);
    887         return AVRC_STS_BAD_PARAM;
    888     }
    889 
    890     if (*pp_pkt == NULL)
    891     {
    892         if ((*pp_pkt = avrc_bld_init_rsp_buffer(p_rsp)) == NULL)
    893         {
    894             AVRC_TRACE_API("%s Failed to initialize response buffer", __func__);
    895             return AVRC_STS_INTERNAL_ERR;
    896         }
    897         alloc = TRUE;
    898     }
    899     status = AVRC_STS_NO_ERROR;
    900     p_pkt = *pp_pkt;
    901 
    902     AVRC_TRACE_API("%s pdu=%x status=%x", __func__, p_rsp->rsp.pdu, p_rsp->rsp.status);
    903     if (p_rsp->rsp.status != AVRC_STS_NO_ERROR)
    904     {
    905         return( avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt) );
    906     }
    907 
    908     switch (p_rsp->pdu)
    909     {
    910     case AVRC_PDU_NEXT_GROUP:
    911     case AVRC_PDU_PREV_GROUP:
    912         status = avrc_bld_group_navigation_rsp(p_rsp->pdu, p_pkt);
    913         break;
    914 
    915     case AVRC_PDU_GET_CAPABILITIES:
    916         status = avrc_bld_get_capability_rsp(&p_rsp->get_caps, p_pkt);
    917         break;
    918 
    919     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
    920         status = avrc_bld_list_app_settings_attr_rsp(&p_rsp->list_app_attr, p_pkt);
    921         break;
    922 
    923     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
    924         status = avrc_bld_list_app_settings_values_rsp(&p_rsp->list_app_values, p_pkt);
    925         break;
    926 
    927     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
    928         status = avrc_bld_get_cur_app_setting_value_rsp(&p_rsp->get_cur_app_val, p_pkt);
    929         break;
    930 
    931     case AVRC_PDU_SET_PLAYER_APP_VALUE:
    932         status = avrc_bld_set_app_setting_value_rsp(&p_rsp->set_app_val, p_pkt);
    933         break;
    934 
    935     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
    936         status = avrc_bld_get_app_setting_attr_text_rsp(&p_rsp->get_app_attr_txt, p_pkt);
    937         break;
    938 
    939     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
    940         status = avrc_bld_get_app_setting_value_text_rsp(&p_rsp->get_app_val_txt, p_pkt);
    941         break;
    942 
    943     case AVRC_PDU_INFORM_DISPLAY_CHARSET:
    944         status = avrc_bld_inform_charset_rsp(&p_rsp->inform_charset, p_pkt);
    945         break;
    946 
    947     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
    948         status = avrc_bld_inform_battery_status_rsp(&p_rsp->inform_battery_status, p_pkt);
    949         break;
    950 
    951     case AVRC_PDU_GET_ELEMENT_ATTR:
    952         status = avrc_bld_get_elem_attrs_rsp(&p_rsp->get_elem_attrs, p_pkt);
    953         break;
    954 
    955     case AVRC_PDU_GET_PLAY_STATUS:
    956         status = avrc_bld_get_play_status_rsp(&p_rsp->get_play_status, p_pkt);
    957         break;
    958 
    959     case AVRC_PDU_REGISTER_NOTIFICATION:
    960         status = avrc_bld_notify_rsp(&p_rsp->reg_notif, p_pkt);
    961         break;
    962 
    963     case AVRC_PDU_REQUEST_CONTINUATION_RSP:     /*        0x40 */
    964         status = avrc_bld_next_rsp(&p_rsp->continu, p_pkt);
    965         break;
    966 
    967     case AVRC_PDU_ABORT_CONTINUATION_RSP:       /*          0x41 */
    968         status = avrc_bld_next_rsp(&p_rsp->abort, p_pkt);
    969         break;
    970 
    971     case AVRC_PDU_SET_ADDRESSED_PLAYER: /*PDU 0x60*/
    972         status = avrc_bld_set_address_player_rsp(&p_rsp->addr_player, p_pkt);
    973         break;
    974 
    975     case AVRC_PDU_PLAY_ITEM:
    976         status = avrc_bld_play_item_rsp(&p_rsp->play_item, p_pkt);
    977         break;
    978 
    979     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
    980         status = avrc_bld_set_absolute_volume_rsp(p_rsp->volume.volume, p_pkt);
    981         break;
    982     }
    983 
    984     if (alloc && (status != AVRC_STS_NO_ERROR) )
    985     {
    986         osi_free(p_pkt);
    987         *pp_pkt = NULL;
    988     }
    989     AVRC_TRACE_API("%s returning %d", __func__, status);
    990     return status;
    991 }
    992 
    993 #endif /* (AVRC_METADATA_INCLUDED == TRUE)*/
    994 
    995