/*******************************************************************************
**
** Function         avrc_bld_app_setting_text_rsp
**
** Description      This function builds the Get Application Settings Attribute Text
**                  or Get Application Settings Value Text response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_app_setting_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp, BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start, *p_len, *p_count;
    UINT16  len, len_left;
    UINT8   xx;
    tAVRC_STS   sts = AVRC_STS_NO_ERROR;
    UINT8       num_added = 0;

    if (!p_rsp->p_attrs)
    {
        AVRC_TRACE_ERROR0("avrc_bld_app_setting_text_rsp NULL parameter");
        return AVRC_STS_BAD_PARAM;
    }
    /* get the existing length, if any, and also the num attributes */
    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_len = p_start + 2; /* pdu + rsvd */
    len_left = GKI_get_buf_size(p_pkt) - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;

    BE_STREAM_TO_UINT16(len, p_data);
    p_count = p_data;

    if (len == 0)
    {
        *p_count = 0;
        p_data++;
    }
    else
    {
        p_data = p_start + p_pkt->len;
    }

    for (xx=0; xx<p_rsp->num_attr; xx++)
    {
        if  (len_left < (p_rsp->p_attrs[xx].str_len + 4))
        {
            AVRC_TRACE_ERROR3("avrc_bld_app_setting_text_rsp out of room (str_len:%d, left:%d)",
                xx, p_rsp->p_attrs[xx].str_len, len_left);
            p_rsp->num_attr = num_added;
            sts = AVRC_STS_INTERNAL_ERR;
            break;
        }
        if ( !p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str )
        {
            AVRC_TRACE_ERROR1("avrc_bld_app_setting_text_rsp NULL attr text[%d]", xx);
            continue;
        }
        UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
        UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
        UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
        ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str, p_rsp->p_attrs[xx].str_len);
        (*p_count)++;
        num_added++;
    }
    len = p_data - p_count;
    UINT16_TO_BE_STREAM(p_len, len);
    p_pkt->len = (p_data - p_start);

    return sts;
}
/*******************************************************************************
**
** Function         avrc_bld_get_elem_attrs_rsp
**
** Description      This function builds the Get Element Attributes
**                  response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start, *p_len, *p_count;
    UINT16  len;
    UINT8   xx;

    AVRC_TRACE_API0("avrc_bld_get_elem_attrs_rsp");
    if (!p_rsp->p_attrs)
    {
        AVRC_TRACE_ERROR0("avrc_bld_get_elem_attrs_rsp NULL parameter");
        return AVRC_STS_BAD_PARAM;
    }

    /* get the existing length, if any, and also the num attributes */
    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_len = p_start + 2; /* pdu + rsvd */

    BE_STREAM_TO_UINT16(len, p_data);
    p_count = p_data;

    if (len == 0)
    {
        *p_count = 0;
        p_data++;
    }
    else
    {
        p_data = p_start + p_pkt->len;
    }

    for (xx=0; xx<p_rsp->num_attr; xx++)
    {
        if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_rsp->p_attrs[xx].attr_id))
        {
            AVRC_TRACE_ERROR2("avrc_bld_get_elem_attrs_rsp invalid attr id[%d]: %d", xx, p_rsp->p_attrs[xx].attr_id);
            continue;
        }
        if ( !p_rsp->p_attrs[xx].name.p_str )
        {
            p_rsp->p_attrs[xx].name.str_len = 0;
        }
        UINT32_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
        UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.charset_id);
        UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.str_len);
        ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, p_rsp->p_attrs[xx].name.str_len);
        (*p_count)++;
    }
    len = p_data - p_count;
    UINT16_TO_BE_STREAM(p_len, len);
    p_pkt->len = (p_data - p_start);
    return AVRC_STS_NO_ERROR;
}
Beispiel #3
0
/*******************************************************************************
**
** Function         llcp_sdp_add_sdreq
**
** Description      Add Service Discovery Request into SNL PDU
**
**
** Returns          void
**
*******************************************************************************/
static void llcp_sdp_add_sdreq (UINT8 tid, char *p_name)
{
    UINT8  *p;
    UINT16 name_len = (UINT16) strlen (p_name);

    p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset + llcp_cb.sdp_cb.p_snl->len;

    UINT8_TO_BE_STREAM (p, LLCP_SDREQ_TYPE);
    UINT8_TO_BE_STREAM (p, (1 + name_len));
    UINT8_TO_BE_STREAM (p, tid);
    ARRAY_TO_BE_STREAM (p, p_name, name_len);

    llcp_cb.sdp_cb.p_snl->len += LLCP_SDREQ_MIN_LEN + name_len;
}
Beispiel #4
0
/*******************************************************************************
**
** Function         bta_hl_compose_supported_feature_list
**
** Description      This function is called to compose a data sequence from
**                  the supported  feature element list struct pointer
**
** Returns          the length of the data sequence
**
*******************************************************************************/
int bta_hl_compose_supported_feature_list( UINT8 *p, UINT16 num_elem,
                                           const tBTA_HL_SUP_FEATURE_ELEM *p_elem_list)
{
    UINT16          xx, str_len, seq_len;
    UINT8           *p_head = p;

    for (xx = 0; xx < num_elem; xx++, p_elem_list++)
    {
        UINT8_TO_BE_STREAM  (p, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
        seq_len=7;
        str_len=0;
        if (p_elem_list->p_mdep_desp)
        {
            str_len = strlen(p_elem_list->p_mdep_desp)+1;
            seq_len += str_len+2; /* todo add a # symbol for 2 */
        }

        *p++ = (UINT8) seq_len;

        UINT8_TO_BE_STREAM  (p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
        UINT8_TO_BE_STREAM  (p, p_elem_list->mdep_id);
        UINT8_TO_BE_STREAM  (p, (UINT_DESC_TYPE << 3) | SIZE_TWO_BYTES);
        UINT16_TO_BE_STREAM (p, p_elem_list->data_type);
        UINT8_TO_BE_STREAM  (p, (UINT_DESC_TYPE << 3) | SIZE_ONE_BYTE);
        UINT8_TO_BE_STREAM  (p, p_elem_list->mdep_role);

        if (str_len)
        {
            UINT8_TO_BE_STREAM  (p, (TEXT_STR_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
            UINT8_TO_BE_STREAM  (p, str_len);
            ARRAY_TO_BE_STREAM(p, p_elem_list->p_mdep_desp, str_len);
        }
    }

    return(p - p_head);
}
/*******************************************************************************
**
** Function         avrc_bld_notify_rsp
**
** Description      This function builds the Notification response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start;
    UINT8   *p_len;
    UINT16  len = 0;
    UINT8   xx;
    tAVRC_STS status = AVRC_STS_NO_ERROR;

    AVRC_TRACE_API0("avrc_bld_notify_rsp");

    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_len = p_start + 2; /* pdu + rsvd */
    p_data += 2;

    UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
    switch (p_rsp->event_id)
    {
    case AVRC_EVT_PLAY_STATUS_CHANGE:       /* 0x01 */
        /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always TRUE */
        if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
            (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR) )
        {
            UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
            len = 2;
        }
        else
        {
            AVRC_TRACE_ERROR0("bad play state");
            status = AVRC_STS_BAD_PARAM;
        }
        break;

    case AVRC_EVT_TRACK_CHANGE:             /* 0x02 */
        ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
        len = (UINT8)(AVRC_UID_SIZE + 1);
        break;

    case AVRC_EVT_TRACK_REACHED_END:        /* 0x03 */
    case AVRC_EVT_TRACK_REACHED_START:      /* 0x04 */
        len = 1;
        break;

    case AVRC_EVT_PLAY_POS_CHANGED:         /* 0x05 */
        UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
        len = 5;
        break;

    case AVRC_EVT_BATTERY_STATUS_CHANGE:    /* 0x06 */
        if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status))
        {
            UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
            len = 2;
        }
        else
        {
            AVRC_TRACE_ERROR0("bad battery status");
            status = AVRC_STS_BAD_PARAM;
        }
        break;

    case AVRC_EVT_SYSTEM_STATUS_CHANGE:     /* 0x07 */
        if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status))
        {
            UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
            len = 2;
        }
        else
        {
            AVRC_TRACE_ERROR0("bad system status");
            status = AVRC_STS_BAD_PARAM;
        }
        break;

    case AVRC_EVT_APP_SETTING_CHANGE:       /* 0x08 */
        if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS)
            p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;

        if (p_rsp->param.player_setting.num_attr > 0)
        {
            UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
            len = 2;
            for (xx=0; xx<p_rsp->param.player_setting.num_attr; xx++)
            {
                if (avrc_is_valid_player_attrib_value(p_rsp->param.player_setting.attr_id[xx],
                    p_rsp->param.player_setting.attr_value[xx]))
                {
                    UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
                    UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
                }
                else
                {
                    AVRC_TRACE_ERROR0("bad player app seeting attribute or value");
                    status = AVRC_STS_BAD_PARAM;
                    break;
                }
                len += 2;
            }
        }
        else
            status = AVRC_STS_BAD_PARAM;
        break;

    default:
        status = AVRC_STS_BAD_PARAM;
        AVRC_TRACE_ERROR0("unknown event_id");
    }

    UINT16_TO_BE_STREAM(p_len, len);
    p_pkt->len = (p_data - p_start);

    return status;
}
/*******************************************************************************
**
** Function         NDEF_MsgAddWktAc
**
** Description      This function adds Alternative Carrier Record.
**
** Returns          NDEF_OK if all OK
**
*******************************************************************************/
tNDEF_STATUS NDEF_MsgAddWktAc (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
                               UINT8 cps, char *p_carrier_data_ref_str,
                               UINT8 aux_data_ref_count, char *p_aux_data_ref_str[])
{
    tNDEF_STATUS    status;
    UINT32          payload_len;
    UINT8           ref_str_len, xx;
    UINT8 *p_rec, *p;

    /* get payload length first */

    /* CPS, length of carrier data ref, carrier data ref, Aux data reference count */
    payload_len = 3 + (UINT8)strlen (p_carrier_data_ref_str);
    for (xx = 0; xx < aux_data_ref_count; xx++)
    {
        /* Aux Data Reference length (1 byte) */
        payload_len += 1 + (UINT8)strlen (p_aux_data_ref_str[xx]);
    }

    /* reserve memory for payload */
    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
                             NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN,
                             NULL, 0, NULL, payload_len);

    if (status == NDEF_OK)
    {
        /* get AC record added at the end */
        p_rec = NDEF_MsgGetLastRecInMsg (p_msg);

        /* get start pointer of reserved payload */
        p = NDEF_RecGetPayload (p_rec, &payload_len);

        /* Get a pointer to the payload or NULL (for none) which is valid */
        if (p)
        {
            /* Add Carrier Power State */
            UINT8_TO_BE_STREAM (p, cps);

            /* Carrier Data Reference length */
            ref_str_len = (UINT8)strlen (p_carrier_data_ref_str);

            UINT8_TO_BE_STREAM (p, ref_str_len);

            /* Carrier Data Reference */
            ARRAY_TO_BE_STREAM (p, p_carrier_data_ref_str, ref_str_len);

            /* Aux Data Reference Count */
            UINT8_TO_BE_STREAM (p, aux_data_ref_count);

            for (xx = 0; xx < aux_data_ref_count; xx++)
            {
                /* Aux Data Reference length (1 byte) */
                ref_str_len = (UINT8)strlen (p_aux_data_ref_str[xx]);

                UINT8_TO_BE_STREAM (p, ref_str_len);

                /* Aux Data Reference */
                ARRAY_TO_BE_STREAM (p, p_aux_data_ref_str[xx], ref_str_len);
            }
        }
    }

    return (status);
}