Home | History | Annotate | Download | only in avrc
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2006-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 
     30 #if (AVRC_METADATA_INCLUDED == TRUE)
     31 
     32 /*******************************************************************************
     33 **
     34 ** Function         avrc_pars_vendor_rsp
     35 **
     36 ** Description      This function parses the vendor specific commands defined by
     37 **                  Bluetooth SIG
     38 **
     39 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
     40 **                  Otherwise, the error code defined by AVRCP 1.4
     41 **
     42 *******************************************************************************/
     43 static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result)
     44 {
     45     tAVRC_STS  status = AVRC_STS_NO_ERROR;
     46     UINT8   *p;
     47     UINT16  len;
     48 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
     49     UINT8 eventid=0;
     50 #endif
     51 
     52     /* Check the vendor data */
     53     if (p_msg->vendor_len == 0)
     54         return AVRC_STS_NO_ERROR;
     55     if (p_msg->p_vendor_data == NULL)
     56         return AVRC_STS_INTERNAL_ERR;
     57 
     58     p = p_msg->p_vendor_data;
     59     BE_STREAM_TO_UINT8 (p_result->pdu, p);
     60     p++; /* skip the reserved/packe_type byte */
     61     BE_STREAM_TO_UINT16 (len, p);
     62     AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d/0x%x",
     63                      __func__, p_msg->hdr.ctype, p_result->pdu, len, len);
     64     if (p_msg->hdr.ctype == AVRC_RSP_REJ)
     65     {
     66         p_result->rsp.status = *p;
     67         return p_result->rsp.status;
     68     }
     69 
     70     switch (p_result->pdu)
     71     {
     72     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
     73     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
     74 
     75 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
     76     case AVRC_PDU_SET_ABSOLUTE_VOLUME:      /* 0x50 */
     77         if (len != 1)
     78             status = AVRC_STS_INTERNAL_ERR;
     79         else
     80         {
     81             BE_STREAM_TO_UINT8 (p_result->volume.volume, p);
     82         }
     83         break;
     84 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
     85 
     86     case AVRC_PDU_REGISTER_NOTIFICATION:    /* 0x31 */
     87 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
     88         BE_STREAM_TO_UINT8 (eventid, p);
     89         if(AVRC_EVT_VOLUME_CHANGE==eventid
     90             && (AVRC_RSP_CHANGED==p_msg->hdr.ctype || AVRC_RSP_INTERIM==p_msg->hdr.ctype
     91             || AVRC_RSP_REJ==p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL==p_msg->hdr.ctype))
     92         {
     93             p_result->reg_notif.status=p_msg->hdr.ctype;
     94             p_result->reg_notif.event_id=eventid;
     95             BE_STREAM_TO_UINT8 (p_result->reg_notif.param.volume, p);
     96         }
     97         AVRC_TRACE_DEBUG("%s PDU reg notif response:event %x, volume %x",
     98                          __func__, eventid, p_result->reg_notif.param.volume);
     99 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
    100         break;
    101     default:
    102         status = AVRC_STS_BAD_CMD;
    103         break;
    104     }
    105 
    106     return status;
    107 }
    108 
    109 void avrc_parse_notification_rsp (UINT8 *p_stream, tAVRC_REG_NOTIF_RSP *p_rsp)
    110 {
    111     BE_STREAM_TO_UINT8(p_rsp->event_id, p_stream);
    112     switch (p_rsp->event_id)
    113     {
    114         case AVRC_EVT_PLAY_STATUS_CHANGE:
    115             BE_STREAM_TO_UINT8(p_rsp->param.play_status, p_stream);
    116             break;
    117 
    118         case AVRC_EVT_TRACK_CHANGE:
    119             BE_STREAM_TO_ARRAY(p_stream, p_rsp->param.track, 8);
    120             break;
    121 
    122         case AVRC_EVT_APP_SETTING_CHANGE:
    123             BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream);
    124             for (int index = 0; index < p_rsp->param.player_setting.num_attr; index++)
    125             {
    126                 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index], p_stream);
    127                 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_value[index], p_stream);
    128             }
    129             break;
    130 
    131         case AVRC_EVT_NOW_PLAYING_CHANGE:
    132             break;
    133 
    134         case AVRC_EVT_AVAL_PLAYERS_CHANGE:
    135             break;
    136 
    137         case AVRC_EVT_ADDR_PLAYER_CHANGE:
    138             break;
    139 
    140         case AVRC_EVT_UIDS_CHANGE:
    141             break;
    142 
    143         case AVRC_EVT_TRACK_REACHED_END:
    144         case AVRC_EVT_TRACK_REACHED_START:
    145         case AVRC_EVT_PLAY_POS_CHANGED:
    146         case AVRC_EVT_BATTERY_STATUS_CHANGE:
    147         case AVRC_EVT_SYSTEM_STATUS_CHANGE:
    148         default:
    149             break;
    150     }
    151 }
    152 
    153 #if (AVRC_CTLR_INCLUDED == TRUE)
    154 /*******************************************************************************
    155 **
    156 ** Function         avrc_ctrl_pars_vendor_rsp
    157 **
    158 ** Description      This function parses the vendor specific commands defined by
    159 **                  Bluetooth SIG
    160 **
    161 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
    162 **                  Otherwise, the error code defined by AVRCP 1.4
    163 **
    164 *******************************************************************************/
    165 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(
    166     tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result, UINT8* p_buf, UINT16* buf_len)
    167 {
    168     UINT8   *p = p_msg->p_vendor_data;
    169     BE_STREAM_TO_UINT8 (p_result->pdu, p);
    170     p++; /* skip the reserved/packe_type byte */
    171 
    172     UINT16  len;
    173     BE_STREAM_TO_UINT16 (len, p);
    174     AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d",
    175                      __func__, p_msg->hdr.ctype, p_result->pdu, len);
    176     /* Todo: Issue in handling reject, check */
    177     if (p_msg->hdr.ctype == AVRC_RSP_REJ)
    178     {
    179         p_result->rsp.status = *p;
    180         return p_result->rsp.status;
    181     }
    182 
    183     /* TODO: Break the big switch into functions. */
    184     switch (p_result->pdu)
    185     {
    186     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
    187     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
    188 
    189     case AVRC_PDU_REGISTER_NOTIFICATION:
    190         avrc_parse_notification_rsp(p, &p_result->reg_notif);
    191         break;
    192 
    193     case AVRC_PDU_GET_CAPABILITIES:
    194         if (len == 0)
    195         {
    196             p_result->get_caps.count = 0;
    197             p_result->get_caps.capability_id = 0;
    198             break;
    199         }
    200         BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
    201         BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
    202         AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ",
    203                          __func__, p_result->get_caps.capability_id, p_result->get_caps.count);
    204         if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID)
    205         {
    206             for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_COMP_ID));
    207                 xx++)
    208             {
    209                 BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
    210             }
    211         }
    212         else if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED)
    213         {
    214             for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_EVT_ID));
    215                 xx++)
    216             {
    217                 BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
    218             }
    219         }
    220         break;
    221 
    222     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
    223         if (len == 0)
    224         {
    225             p_result->list_app_attr.num_attr = 0;
    226             break;
    227         }
    228         BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
    229         AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->list_app_attr.num_attr);
    230         for(int xx = 0; xx < p_result->list_app_attr.num_attr; xx++)
    231         {
    232             BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
    233         }
    234         break;
    235 
    236     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
    237         if (len == 0)
    238         {
    239             p_result->list_app_values.num_val = 0;
    240             break;
    241         }
    242         BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
    243         AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->list_app_values.num_val);
    244         for(int xx = 0; xx < p_result->list_app_values.num_val; xx++)
    245         {
    246             BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
    247         }
    248         break;
    249 
    250     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
    251     {
    252         if (len == 0)
    253         {
    254             p_result->get_cur_app_val.num_val = 0;
    255             break;
    256         }
    257         BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
    258         tAVRC_APP_SETTING *app_sett =
    259             (tAVRC_APP_SETTING*)osi_malloc(p_result->get_cur_app_val.num_val*sizeof(tAVRC_APP_SETTING));
    260         AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_cur_app_val.num_val);
    261         for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++)
    262         {
    263             BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
    264             BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
    265         }
    266         p_result->get_cur_app_val.p_vals = app_sett;
    267     }
    268         break;
    269 
    270     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
    271     {
    272         tAVRC_APP_SETTING_TEXT   *p_setting_text;
    273         UINT8                    num_attrs;
    274 
    275         if (len == 0)
    276         {
    277             p_result->get_app_attr_txt.num_attr = 0;
    278             break;
    279         }
    280         BE_STREAM_TO_UINT8(num_attrs, p);
    281         AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_app_attr_txt.num_attr);
    282         p_result->get_app_attr_txt.num_attr = num_attrs;
    283         p_setting_text = (tAVRC_APP_SETTING_TEXT*)osi_malloc(num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
    284         for (int xx = 0; xx < num_attrs; xx++)
    285         {
    286             BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
    287             BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id, p);
    288             BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
    289             if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0)
    290             {
    291                 UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_attr_txt.p_attrs[xx].str_len);
    292                 BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_attr_txt.p_attrs[xx].str_len);
    293                 p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
    294             } else {
    295                 p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
    296             }
    297         }
    298     }
    299         break;
    300 
    301     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
    302     {
    303         tAVRC_APP_SETTING_TEXT   *p_setting_text;
    304         UINT8                    num_vals;
    305 
    306         if (len == 0)
    307         {
    308             p_result->get_app_val_txt.num_attr = 0;
    309             break;
    310         }
    311         BE_STREAM_TO_UINT8(num_vals, p);
    312         p_result->get_app_val_txt.num_attr = num_vals;
    313         AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->get_app_val_txt.num_attr);
    314 
    315         p_setting_text = (tAVRC_APP_SETTING_TEXT *)osi_malloc(num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
    316         for (int i = 0; i < num_vals; i++) {
    317             BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
    318             BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
    319             BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
    320             if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
    321                 UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_val_txt.p_attrs[i].str_len);
    322                 BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_val_txt.p_attrs[i].str_len);
    323                 p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
    324             } else {
    325                 p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
    326             }
    327         }
    328     }
    329         break;
    330 
    331     case AVRC_PDU_SET_PLAYER_APP_VALUE:
    332         /* nothing comes as part of this rsp */
    333         break;
    334 
    335     case AVRC_PDU_GET_ELEMENT_ATTR:
    336     {
    337         UINT8               num_attrs;
    338 
    339         if (len <= 0)
    340         {
    341             p_result->get_elem_attrs.num_attr = 0;
    342             break;
    343         }
    344         BE_STREAM_TO_UINT8(num_attrs, p);
    345         p_result->get_elem_attrs.num_attr = num_attrs;
    346         if (num_attrs)
    347         {
    348             tAVRC_ATTR_ENTRY *p_attrs =
    349                 (tAVRC_ATTR_ENTRY*)osi_malloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
    350             for (int i = 0; i < num_attrs; i++) {
    351                 BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
    352                 BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
    353                 BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
    354                 if (p_attrs[i].name.str_len > 0) {
    355                     p_attrs[i].name.p_str = (UINT8 *)osi_malloc(p_attrs[i].name.str_len);
    356                     BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str, p_attrs[i].name.str_len);
    357                 }
    358             }
    359             p_result->get_elem_attrs.p_attrs = p_attrs;
    360         }
    361     }
    362         break;
    363 
    364     case AVRC_PDU_GET_PLAY_STATUS:
    365         if (len == 0)
    366         {
    367             break;
    368         }
    369         BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
    370         BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
    371         BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
    372         break;
    373 
    374     default:
    375         return AVRC_STS_BAD_CMD;
    376     }
    377     return AVRC_STS_NO_ERROR;
    378 }
    379 
    380 /*******************************************************************************
    381 **
    382 ** Function         AVRC_Ctrl_ParsResponse
    383 **
    384 ** Description      This function is a parse response for AVRCP Controller.
    385 **
    386 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
    387 **                  Otherwise, the error code defined by AVRCP 1.4
    388 **
    389 *******************************************************************************/
    390 tAVRC_STS AVRC_Ctrl_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16* buf_len)
    391 {
    392     tAVRC_STS  status = AVRC_STS_INTERNAL_ERR;
    393     if (p_msg && p_result)
    394     {
    395         switch (p_msg->hdr.opcode)
    396         {
    397         case AVRC_OP_VENDOR:     /*  0x00    Vendor-dependent commands */
    398             status = avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf,buf_len);
    399             break;
    400 
    401         default:
    402             AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
    403             break;
    404         }
    405         p_result->rsp.opcode = p_msg->hdr.opcode;
    406         p_result->rsp.status = status;
    407     }
    408     return status;
    409 }
    410 #endif /* (AVRC_CTRL_INCLUDED) == TRUE) */
    411 /*******************************************************************************
    412 **
    413 ** Function         AVRC_ParsResponse
    414 **
    415 ** Description      This function is a superset of AVRC_ParsMetadata to parse the response.
    416 **
    417 ** Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
    418 **                  Otherwise, the error code defined by AVRCP 1.4
    419 **
    420 *******************************************************************************/
    421 tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16 buf_len)
    422 {
    423     tAVRC_STS  status = AVRC_STS_INTERNAL_ERR;
    424     UINT16  id;
    425     UNUSED(p_buf);
    426     UNUSED(buf_len);
    427 
    428     if (p_msg && p_result)
    429     {
    430         switch (p_msg->hdr.opcode)
    431         {
    432         case AVRC_OP_VENDOR:     /*  0x00    Vendor-dependent commands */
    433             status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
    434             break;
    435 
    436         case AVRC_OP_PASS_THRU:  /*  0x7C    panel subunit opcode */
    437             status = avrc_pars_pass_thru(&p_msg->pass, &id);
    438             if (status == AVRC_STS_NO_ERROR)
    439             {
    440                 p_result->pdu = (UINT8)id;
    441             }
    442             break;
    443 
    444         default:
    445             AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
    446             break;
    447         }
    448         p_result->rsp.opcode = p_msg->hdr.opcode;
    449         p_result->rsp.status = status;
    450     }
    451     return status;
    452 }
    453 #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
    454