Пример #1
0
/*******************************************************************************
**
** Function         llcp_util_send_connect
**
** Description      Send CONNECT PDU
**
** Returns          tLLCP_STATUS
**
******************************************************************************/
tLLCP_STATUS llcp_util_send_connect (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params)
{
    BT_HDR *p_msg;
    UINT8  *p;
    UINT16  miu_len = 0, rw_len = 0, sn_len = 0;

    if (p_params->miu != LLCP_DEFAULT_MIU)
    {
        miu_len = 4;    /* TYPE, LEN, 2 bytes MIU */
    }
    if (p_params->rw != LLCP_DEFAULT_RW)
    {
        rw_len = 3;     /* TYPE, LEN, 1 byte RW */
        p_params->rw &= 0x0F;   /* only 4 bits  */
    }
    if ((strlen (p_params->sn)) && (p_dlcb->remote_sap == LLCP_SAP_SDP))
    {
        sn_len = (UINT16) (2 + strlen (p_params->sn));    /* TYPE, LEN, SN */
    }

    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

    if (p_msg)
    {
        p_msg->len    = LLCP_PDU_HEADER_SIZE + miu_len + rw_len + sn_len;
        p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;

        p = (UINT8 *) (p_msg + 1) + p_msg->offset;

        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CONNECT_TYPE, p_dlcb->local_sap));

        if (miu_len)
        {
            UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
            UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
            UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU);
        }

        if (rw_len)
        {
            UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE);
            UINT8_TO_BE_STREAM (p, LLCP_RW_LEN);
            UINT8_TO_BE_STREAM (p, p_params->rw);
        }

        if (sn_len)
        {
            UINT8_TO_BE_STREAM (p, LLCP_SN_TYPE);
            UINT8_TO_BE_STREAM (p, sn_len - 2);
            memcpy (p, p_params->sn, sn_len - 2);
        }

        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
        llcp_link_check_send_data ();

        return LLCP_STATUS_SUCCESS;
    }

    return LLCP_STATUS_FAIL;
}
Пример #2
0
/*******************************************************************************
**
** Function         rw_t4t_update_nlen
**
** Description      Send UpdateBinary Command to update NLEN to peer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN rw_t4t_update_nlen (UINT16 ndef_len)
{
    BT_HDR          *p_c_apdu;
    UINT8           *p;

    RW_TRACE_DEBUG1 ("rw_t4t_update_nlen () NLEN:%d", ndef_len);

    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);

    if (!p_c_apdu)
    {
        RW_TRACE_ERROR0 ("rw_t4t_update_nlen (): Cannot allocate buffer");
        return FALSE;
    }

    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;

    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY);
    UINT16_TO_BE_STREAM (p, 0x0000);                    /* offset for NLEN */
    UINT8_TO_BE_STREAM (p, T4T_FILE_LENGTH_SIZE);
    UINT16_TO_BE_STREAM (p, ndef_len);

    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_LENGTH_SIZE;

    if (!rw_t4t_send_to_lower (p_c_apdu))
    {
        return FALSE;
    }

    return TRUE;
}
Пример #3
0
/*******************************************************************************
**
** Function         CE_T4TTestSetCC
**
** Description      Set fields in Capability Container File for testing
**
** Returns          NFC_STATUS_OK if success
**
*******************************************************************************/
tNFC_STATUS CE_T4TTestSetCC (UINT16 cc_len,
                             UINT8  version,
                             UINT16 max_le,
                             UINT16 max_lc)
{
#if (CE_TEST_INCLUDED == TRUE)
    tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t;
    UINT8       *p;

    CE_TRACE_DEBUG4 ("CE_T4TTestSetCC (): CCLen:0x%04X, Ver:0x%02X, MaxLe:0x%04X, MaxLc:0x%04X",
                      cc_len, version, max_le, max_lc);

    /* CC file */
    p = p_t4t->cc_file;

    if (cc_len != 0xFFFF)
    {
        UINT16_TO_BE_STREAM (p, cc_len);
    }
    else
        p += 2;

    if (version != 0xFF)
    {
        mapping_aid_test_enabled = TRUE;
        if (version == T4T_VERSION_1_0)
            ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x00;
        else if (version == T4T_VERSION_2_0)
            ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0x01;
        else /* Undefined version */
            ce_test_tag_app_id[T4T_V20_NDEF_TAG_AID_LEN - 1] = 0xFF;

        UINT8_TO_BE_STREAM (p, version);
    }
    else
    {
        mapping_aid_test_enabled = FALSE;
        p += 1;
    }

    if (max_le != 0xFFFF)
    {
        UINT16_TO_BE_STREAM (p, max_le);
    }
    else
        p += 2;

    if (max_lc != 0xFFFF)
    {
        UINT16_TO_BE_STREAM (p, max_lc);
    }
    else
        p += 2;

    return NFC_STATUS_OK;
#else
    return NFC_STATUS_FAILED;
#endif
}
/*******************************************************************************
**
** 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;
}
Пример #5
0
/******************************************************************************
**
** Function         avrc_send_continue_frag
**
** Description      This function sends a continue response fragment
**
** Returns          Nothing.
**
******************************************************************************/
static void avrc_send_continue_frag(UINT8 handle, UINT8 label)
{
    tAVRC_FRAG_CB   *p_fcb;
    BT_HDR  *p_pkt_old, *p_pkt;
    UINT8   *p_old, *p_data;
    UINT8   cr = AVCT_RSP;
    tAVRC_RSP   rej_rsp;

    p_fcb = &avrc_cb.fcb[handle];
    p_pkt = p_fcb->p_fmsg;

    AVRC_TRACE_DEBUG("%s handle = %u label = %u len = %d",
                     __func__, handle, label, p_pkt->len);
    if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
        int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
        p_pkt_old = p_fcb->p_fmsg;
        p_pkt = (BT_HDR *)osi_malloc((UINT16)(AVRC_PACKET_LEN + offset_len + BT_HDR_SIZE));
        if (p_pkt) {
            p_pkt->len          = AVRC_MAX_CTRL_DATA_LEN;
            p_pkt->offset       = AVCT_MSG_OFFSET;
            p_pkt->layer_specific = p_pkt_old->layer_specific;
            p_pkt->event = p_pkt_old->event;
            p_old = (UINT8 *)(p_pkt_old + 1) + p_pkt_old->offset;
            p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
            memcpy (p_data, p_old, AVRC_MAX_CTRL_DATA_LEN);
            /* use AVRC continue packet type */
            p_data += AVRC_VENDOR_HDR_SIZE;
            p_data++; /* pdu */
            *p_data++ = AVRC_PKT_CONTINUE;
            /* 4=pdu, pkt_type & len */
            UINT16_TO_BE_STREAM(p_data, (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - 4));

            /* prepare the left over for as an end fragment */
            avrc_prep_end_frag (handle);
        } else {
            /* use the current GKI buffer to send Internal error status */
            p_pkt = p_fcb->p_fmsg;
            p_fcb->p_fmsg = NULL;
            p_fcb->frag_enabled = FALSE;
            AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation - send internal error" );
            p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
            *p_data++ = AVRC_PDU_REQUEST_CONTINUATION_RSP;
            *p_data++ = 0;
            UINT16_TO_BE_STREAM(p_data, 0);
            p_pkt->len = 4;
            rej_rsp.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP;
            rej_rsp.status = AVRC_STS_INTERNAL_ERR;
            AVRC_BldResponse( handle, (tAVRC_RESPONSE *)&rej_rsp, &p_pkt);
            cr = AVCT_RSP;
        }
    } else {
        /* end fragment. clean the control block */
        p_fcb->frag_enabled = FALSE;
        p_fcb->p_fmsg       = NULL;
    }
    AVCT_MsgReq( handle, label, cr, p_pkt);
}
/*******************************************************************************
**
** 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;
}
Пример #7
0
/*******************************************************************************
**
** Function         llcp_util_send_cc
**
** Description      Send CC PDU
**
** Returns          tLLCP_STATUS
**
******************************************************************************/
tLLCP_STATUS llcp_util_send_cc (tLLCP_DLCB *p_dlcb, tLLCP_CONNECTION_PARAMS *p_params)
{
    BT_HDR *p_msg;
    UINT8  *p;
    UINT16  miu_len = 0, rw_len = 0;

    if (p_params->miu != LLCP_DEFAULT_MIU)
    {
        miu_len = 4;
    }
    if (p_params->rw != LLCP_DEFAULT_RW)
    {
        rw_len = 3;
        p_params->rw &= 0x0F;
    }

    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

    if (p_msg)
    {
        p_msg->len      = LLCP_PDU_HEADER_SIZE + miu_len + rw_len;
        p_msg->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;

        p = (UINT8 *) (p_msg + 1) + p_msg->offset;

        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_CC_TYPE, p_dlcb->local_sap));

        if (miu_len)
        {
            UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
            UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
            UINT16_TO_BE_STREAM (p, p_params->miu - LLCP_DEFAULT_MIU);
        }

        if (rw_len)
        {
            UINT8_TO_BE_STREAM (p, LLCP_RW_TYPE);
            UINT8_TO_BE_STREAM (p, LLCP_RW_LEN);
            UINT8_TO_BE_STREAM (p, p_params->rw);
        }

        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
        llcp_link_check_send_data ();

        return LLCP_STATUS_SUCCESS;
    }

    return LLCP_STATUS_FAIL;
}
Пример #8
0
/*******************************************************************************
**
** Function         llcp_util_build_info_pdu
**
** Description      Add DSAP, PTYPE, SSAP and sequence numbers and update local ack
**                  sequence
**
** Returns          void
**
*******************************************************************************/
void llcp_util_build_info_pdu (tLLCP_DLCB *p_dlcb, BT_HDR *p_msg)
{
    UINT8  *p;
    UINT8  rcv_seq;

    p_msg->offset -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
    p_msg->len    += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
    p = (UINT8 *) (p_msg + 1) + p_msg->offset;

    UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_I_TYPE, p_dlcb->local_sap));

    /* if local_busy or rx congested then do not update receive sequence number to flow off */
    if (  (p_dlcb->local_busy)
        ||(p_dlcb->is_rx_congested)
        ||(llcp_cb.overall_rx_congested)  )
    {
        rcv_seq = p_dlcb->sent_ack_seq;
    }
    else
    {
        p_dlcb->sent_ack_seq = p_dlcb->next_rx_seq;
        rcv_seq = p_dlcb->sent_ack_seq;
    }
    UINT8_TO_BE_STREAM  (p, LLCP_GET_SEQUENCE (p_dlcb->next_tx_seq, rcv_seq));
}
/*******************************************************************************
**
** Function         avrc_bld_init_rsp_buffer
**
** Description      This function initializes the response buffer based on PDU
**
** Returns          NULL, if no GKI buffer or failure to build the message.
**                  Otherwise, the GKI buffer that contains the initialized message.
**
*******************************************************************************/
static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
{
    UINT16 offset = AVRC_MSG_PASS_THRU_OFFSET, chnl = AVCT_DATA_CTRL, len=AVRC_META_CMD_POOL_SIZE;
    BT_HDR *p_pkt=NULL;
    UINT8  opcode = avrc_opcode_from_pdu(p_rsp->pdu);

    AVRC_TRACE_API3("avrc_bld_init_rsp_buffer: pdu=%x, opcode=%x/%x", p_rsp->pdu, opcode,
        p_rsp->rsp.opcode);
    if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
        avrc_is_valid_opcode(p_rsp->rsp.opcode))
    {
        opcode = p_rsp->rsp.opcode;
        AVRC_TRACE_API1("opcode=%x", opcode);
    }

    switch (opcode)
    {
    case AVRC_OP_PASS_THRU:
        offset  = AVRC_MSG_PASS_THRU_OFFSET;
        break;

    case AVRC_OP_VENDOR:
        offset  = AVRC_MSG_VENDOR_OFFSET;
        if (p_rsp->pdu == AVRC_PDU_GET_ELEMENT_ATTR)
            len     = AVRC_BROWSE_POOL_SIZE;
        break;
    }

    /* allocate and initialize the buffer */
    p_pkt = (BT_HDR *)GKI_getbuf(len);
    if (p_pkt)
    {
        UINT8 *p_data, *p_start;

        p_pkt->layer_specific = chnl;
        p_pkt->event    = opcode;
        p_pkt->offset   = offset;
        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
        p_start = p_data;

        /* pass thru - group navigation - has a two byte op_id, so dont do it here */
        if (opcode != AVRC_OP_PASS_THRU)
            *p_data++ = p_rsp->pdu;

        switch (opcode)
        {
        case AVRC_OP_VENDOR:
            /* reserved 0, packet_type 0 */
            UINT8_TO_BE_STREAM(p_data, 0);
            /* continue to the next "case to add length */
            /* add fixed lenth - 0 */
            UINT16_TO_BE_STREAM(p_data, 0);
            break;
        }

        p_pkt->len = (p_data - p_start);
    }
    p_rsp->rsp.opcode = opcode;
    return p_pkt;
}
Пример #10
0
/*******************************************************************************
**
** Function         llcp_util_send_frmr
**
** Description      Send FRMR PDU
**
** Returns          tLLCP_STATUS
**
*******************************************************************************/
tLLCP_STATUS llcp_util_send_frmr (tLLCP_DLCB *p_dlcb, UINT8 flags, UINT8 ptype, UINT8 sequence)
{
    BT_HDR *p_msg;
    UINT8  *p;

    p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);

    if (p_msg)
    {
        p_msg->len      = LLCP_PDU_FRMR_SIZE;
        p_msg->offset   = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;

        p = (UINT8 *) (p_msg + 1) + p_msg->offset;

        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (p_dlcb->remote_sap, LLCP_PDU_FRMR_TYPE, p_dlcb->local_sap));
        UINT8_TO_BE_STREAM (p, (flags << 4) | ptype);
        UINT8_TO_BE_STREAM (p, sequence);
        UINT8_TO_BE_STREAM (p, (p_dlcb->next_tx_seq << 4) | p_dlcb->next_rx_seq);
        UINT8_TO_BE_STREAM (p, (p_dlcb->rcvd_ack_seq << 4) | p_dlcb->sent_ack_seq);

        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, p_msg);
        llcp_link_check_send_data ();

        return LLCP_STATUS_SUCCESS;
    }
    else
    {
        LLCP_TRACE_ERROR0 ("llcp_util_send_frmr (): Out of resource");
        return LLCP_STATUS_FAIL;
    }
}
Пример #11
0
/******************************************************************************
**
** Function         avrc_prep_end_frag
**
** Description      This function prepares an end response fragment
**
** Returns          Nothing.
**
******************************************************************************/
static void avrc_prep_end_frag(UINT8 handle)
{
    tAVRC_FRAG_CB   *p_fcb;
    BT_HDR  *p_pkt_new;
    UINT8   *p_data, *p_orig_data;
    UINT8   rsp_type;

    AVRC_TRACE_DEBUG ("avrc_prep_end_frag" );
    p_fcb = &avrc_cb.fcb[handle];

    /* The response type of the end fragment should be the same as the the PDU of "End Fragment
    ** Response" Errata: https://www.bluetooth.org/errata/errata_view.cfm?errata_id=4383
    */
    p_orig_data = ((UINT8 *)(p_fcb->p_fmsg + 1) + p_fcb->p_fmsg->offset);
    rsp_type = ((*p_orig_data) & AVRC_CTYPE_MASK);

    p_pkt_new           = p_fcb->p_fmsg;
    p_pkt_new->len      -= (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
    p_pkt_new->offset   += (AVRC_MAX_CTRL_DATA_LEN - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE);
    p_data = (UINT8 *)(p_pkt_new + 1) + p_pkt_new->offset;
    *p_data++       = rsp_type;
    *p_data++       = (AVRC_SUB_PANEL << AVRC_SUBTYPE_SHIFT);
    *p_data++       = AVRC_OP_VENDOR;
    AVRC_CO_ID_TO_BE_STREAM(p_data, AVRC_CO_METADATA);
    *p_data++       = p_fcb->frag_pdu;
    *p_data++       = AVRC_PKT_END;

    /* 4=pdu, pkt_type & len */
    UINT16_TO_BE_STREAM(p_data, (p_pkt_new->len - AVRC_VENDOR_HDR_SIZE - AVRC_MIN_META_HDR_SIZE));
}
Пример #12
0
/*******************************************************************************
**
** Function         llcp_sdp_check_send_snl
**
** Description      Enqueue Service Name Lookup PDU into sig_xmit_q for transmitting
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_check_send_snl (void)
{
    UINT8 *p;

    if (llcp_cb.sdp_cb.p_snl)
    {
        LLCP_TRACE_DEBUG0 ("SDP: llcp_sdp_check_send_snl ()");

        llcp_cb.sdp_cb.p_snl->len     += LLCP_PDU_HEADER_SIZE;
        llcp_cb.sdp_cb.p_snl->offset  -= LLCP_PDU_HEADER_SIZE;

        p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset;
        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_SDP, LLCP_PDU_SNL_TYPE, LLCP_SAP_SDP ));

        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, llcp_cb.sdp_cb.p_snl);
        llcp_cb.sdp_cb.p_snl = NULL;
    }
#if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE)
    else
    {
        /* Notify DTA after sending out SNL with SDRES not to send SNLs in AGF PDU */
        if ((llcp_cb.p_dta_cback) && (llcp_cb.dta_snl_resp))
        {
            llcp_cb.dta_snl_resp = FALSE;
            (*llcp_cb.p_dta_cback) ();
        }
    }
#endif
}
Пример #13
0
/*******************************************************************************
**
** Function         llcp_util_send_ui
**
** Description      Send UI PDU
**
** Returns          tLLCP_STATUS
**
*******************************************************************************/
tLLCP_STATUS llcp_util_send_ui (UINT8 ssap, UINT8 dsap, tLLCP_APP_CB *p_app_cb, BT_HDR *p_msg)
{
    UINT8        *p;
    tLLCP_STATUS status = LLCP_STATUS_SUCCESS;

    p_msg->offset -= LLCP_PDU_HEADER_SIZE;
    p_msg->len    += LLCP_PDU_HEADER_SIZE;

    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
    UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (dsap, LLCP_PDU_UI_TYPE, ssap));

    GKI_enqueue (&p_app_cb->ui_xmit_q, p_msg);
    llcp_cb.total_tx_ui_pdu++;

    llcp_link_check_send_data ();

    if (  (p_app_cb->is_ui_tx_congested)
        ||(p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
        ||(llcp_cb.overall_tx_congested)
        ||(llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)  )
    {
        /* set congested here so overall congestion check routine will not report event again, */
        /* or notify uncongestion later                                                        */
        p_app_cb->is_ui_tx_congested = TRUE;

        LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congested: ui_xmit_q.count=%d",
                              ssap, p_app_cb->ui_xmit_q.count);

        status = LLCP_STATUS_CONGESTED;
    }

    return status;
}
Пример #14
0
/*******************************************************************************
**
** Function         ce_t4t_send_status
**
** Description      Send status on R-APDU to peer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN ce_t4t_send_status (UINT16 status)
{
    BT_HDR      *p_r_apdu;
    UINT8       *p;

    CE_TRACE_DEBUG1 ("ce_t4t_send_status (): Status:0x%04X", status);

    p_r_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_CE_POOL_ID);

    if (!p_r_apdu)
    {
        CE_TRACE_ERROR0 ("ce_t4t_send_status (): Cannot allocate buffer");
        return FALSE;
    }

    p_r_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    p = (UINT8 *) (p_r_apdu + 1) + p_r_apdu->offset;

    UINT16_TO_BE_STREAM (p, status);

    p_r_apdu->len = T4T_RSP_STATUS_WORDS_SIZE;

    if (!ce_t4t_send_to_lower (p_r_apdu))
    {
        return FALSE;
    }
    return TRUE;
}
/*******************************************************************************
**
** Function         mca_ccb_snd_req
**
** Description      This function builds a request and sends it to the peer.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_snd_req(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
    BT_HDR  *p_pkt;
    UINT8   *p, *p_start;
    BOOLEAN is_abort = FALSE;
    tMCA_DCB *p_dcb;

    MCA_TRACE_DEBUG ("mca_ccb_snd_req cong=%d req=%d", p_ccb->cong, p_msg->op_code);
    /* check for abort request */
    if ((p_ccb->status == MCA_CCB_STAT_PENDING) && (p_msg->op_code == MCA_OP_MDL_ABORT_REQ))
    {
        p_dcb = mca_dcb_by_hdl(p_ccb->p_tx_req->dcb_idx);
        /* the Abort API does not have the associated mdl_id.
         * Get the mdl_id in dcb to compose the request */
        if (p_dcb)
        {
            p_msg->mdl_id = p_dcb->mdl_id;
            mca_dcb_event(p_dcb, MCA_DCB_API_CLOSE_EVT, NULL);
        }
        mca_free_buf ((void **)&p_ccb->p_tx_req);
        p_ccb->status = MCA_CCB_STAT_NORM;
        is_abort = TRUE;
    }

    /* no pending outgoing messages or it's an abort request for a pending data channel */
    if ((!p_ccb->p_tx_req) || is_abort)
    {
        p_ccb->p_tx_req = p_msg;
        if (!p_ccb->cong)
        {
            p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
            if (p_pkt)
            {
                p_pkt->offset = L2CAP_MIN_OFFSET;
                p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
                *p++ = p_msg->op_code;
                UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
                if (p_msg->op_code == MCA_OP_MDL_CREATE_REQ)
                {
                    *p++ = p_msg->mdep_id;
                    *p++ = p_msg->param;
                }
                p_msg->hdr.layer_specific = TRUE;   /* mark this message as sent */
                p_pkt->len = p - p_start;
                L2CA_DataWrite (p_ccb->lcid, p_pkt);
                p_ccb->timer_entry.param = (TIMER_PARAM_TYPE) p_ccb;
                btu_start_timer(&p_ccb->timer_entry, BTU_TTYPE_MCA_CCB_RSP, p_ccb->p_rcb->reg.rsp_tout);
            }
        }
        /* else the L2CAP channel is congested. keep the message to be sent later */
    }
    else
    {
        MCA_TRACE_WARNING ("dropping api req");
        GKI_freebuf (p_data);
    }
}
/******************************************************************************
**
** Function         AVRC_AddRecord
**
** Description      This function is called to build an AVRCP SDP record.
**                  Prior to calling this function the application must
**                  call SDP_CreateRecord() to create an SDP record.
**
**                  Input Parameters:
**                      service_uuid:  Indicates TG(UUID_SERVCLASS_AV_REM_CTRL_TARGET)
**                                            or CT(UUID_SERVCLASS_AV_REMOTE_CONTROL)
**
**                      p_service_name:  Pointer to a null-terminated character
**                      string containing the service name.
**                      If service name is not used set this to NULL.
**
**                      p_provider_name:  Pointer to a null-terminated character
**                      string containing the provider name.
**                      If provider name is not used set this to NULL.
**
**                      categories:  Supported categories.
**
**                      sdp_handle:  SDP handle returned by SDP_CreateRecord().
**
**                  Output Parameters:
**                      None.
**
** Returns          AVRC_SUCCESS if successful.
**                  AVRC_NO_RESOURCES if not enough resources to build the SDP record.
**
******************************************************************************/
UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name,
                char *p_provider_name, UINT16 categories, UINT32 sdp_handle)
{
    UINT16      browse_list[1];
    BOOLEAN     result = TRUE;
    UINT8       temp[8];
    UINT8       *p;
    UINT16      count = 1;
    UINT16      class_list[2];


    AVRC_TRACE_API1("AVRC_AddRecord uuid: %x", service_uuid);

    if( service_uuid != UUID_SERVCLASS_AV_REM_CTRL_TARGET && service_uuid != UUID_SERVCLASS_AV_REMOTE_CONTROL )
        return AVRC_BAD_PARAM;

    /* add service class id list */
    class_list[0] = service_uuid;
    result &= SDP_AddServiceClassIdList(sdp_handle, count, class_list);

    /* add protocol descriptor list   */
    result &= SDP_AddProtocolList(sdp_handle, AVRC_NUM_PROTO_ELEMS, (tSDP_PROTOCOL_ELEM *)avrc_proto_list);

    /* add profile descriptor list   */
#if AVRC_METADATA_INCLUDED == TRUE
    result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_3);
#else
    result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_0);
#endif


    /* add supported categories */
    p = temp;
    UINT16_TO_BE_STREAM(p, categories);
    result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
              (UINT32)2, (UINT8*)temp);

    /* add provider name */
    if (p_provider_name != NULL)
    {
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_PROVIDER_NAME, TEXT_STR_DESC_TYPE,
                    (UINT32)(strlen(p_provider_name)+1), (UINT8 *) p_provider_name);
    }

    /* add service name */
    if (p_service_name != NULL)
    {
        result &= SDP_AddAttribute(sdp_handle, ATTR_ID_SERVICE_NAME, TEXT_STR_DESC_TYPE,
                    (UINT32)(strlen(p_service_name)+1), (UINT8 *) p_service_name);
    }

    /* add browse group list */
    browse_list[0] = UUID_SERVCLASS_PUBLIC_BROWSE_GROUP;
    result &= SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, browse_list);


    return (result ? AVRC_SUCCESS : AVRC_FAIL);
}
/*******************************************************************************
**
** Function         avrc_bld_init_cmd_buffer
**
** Description      This function initializes the command buffer based on PDU
**
** Returns          NULL, if no GKI buffer or failure to build the message.
**                  Otherwise, the GKI buffer that contains the initialized message.
**
*******************************************************************************/
static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd)
{
    UINT16 offset = 0, chnl = AVCT_DATA_CTRL, len=AVRC_META_CMD_POOL_SIZE;
    BT_HDR *p_pkt=NULL;
    UINT8  opcode;

    opcode = avrc_opcode_from_pdu(p_cmd->pdu);
    AVRC_TRACE_API("avrc_bld_init_cmd_buffer: pdu=%x, opcode=%x", p_cmd->pdu, opcode);

    switch (opcode)
    {
    case AVRC_OP_PASS_THRU:
        offset  = AVRC_MSG_PASS_THRU_OFFSET;
        break;

    case AVRC_OP_VENDOR:
        offset  = AVRC_MSG_VENDOR_OFFSET;
        break;
    }

    /* allocate and initialize the buffer */
    p_pkt = (BT_HDR *)GKI_getbuf(len);
    if (p_pkt)
    {
        UINT8 *p_data, *p_start;

        p_pkt->layer_specific = chnl;
        p_pkt->event    = opcode;
        p_pkt->offset   = offset;
        p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
        p_start = p_data;

        /* pass thru - group navigation - has a two byte op_id, so dont do it here */
        if (opcode != AVRC_OP_PASS_THRU)
            *p_data++ = p_cmd->pdu;

        switch (opcode)
        {
        case AVRC_OP_VENDOR:
            /* reserved 0, packet_type 0 */
            UINT8_TO_BE_STREAM(p_data, 0);
            /* continue to the next "case to add length */
            /* add fixed lenth - 0 */
            UINT16_TO_BE_STREAM(p_data, 0);
            break;
        }

        p_pkt->len = (p_data - p_start);
    }
    p_cmd->cmd.opcode = opcode;
    return p_pkt;
}
Пример #18
0
/*******************************************************************************
**
** Function         rw_t4t_update_file
**
** Description      Send UpdateBinary Command to peer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN rw_t4t_update_file (void)
{
    tRW_T4T_CB      *p_t4t = &rw_cb.tcb.t4t;
    BT_HDR          *p_c_apdu;
    UINT8           *p;
    UINT16          length;

    RW_TRACE_DEBUG2 ("rw_t4t_update_file () rw_offset:%d, rw_length:%d",
                      p_t4t->rw_offset, p_t4t->rw_length);

    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);

    if (!p_c_apdu)
    {
        RW_TRACE_ERROR0 ("rw_t4t_write_file (): Cannot allocate buffer");
        return FALSE;
    }

    /* try to send all of remaining data */
    length = p_t4t->rw_length;

    /* adjust updating length if payload is bigger than max size per single command */
    if (length > p_t4t->max_update_size)
    {
        length = (UINT8) (p_t4t->max_update_size);
    }

    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;

    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_UPDATE_BINARY);
    UINT16_TO_BE_STREAM (p, p_t4t->rw_offset);
    UINT8_TO_BE_STREAM (p, length);

    memcpy (p, p_t4t->p_update_data, length);

    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + length;

    if (!rw_t4t_send_to_lower (p_c_apdu))
    {
        return FALSE;
    }

    /* adjust offset, length and pointer for remaining data */
    p_t4t->rw_offset     += length;
    p_t4t->rw_length     -= length;
    p_t4t->p_update_data += length;

    return TRUE;
}
/*******************************************************************************
**
** Function         NDEF_MsgAddWktCr
**
** Description      This function adds Collision Resolution Record.
**
** Returns          NDEF_OK if all OK
**
*******************************************************************************/
tNDEF_STATUS NDEF_MsgAddWktCr (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size,
                               UINT16 random_number )
{
    tNDEF_STATUS    status;
    UINT8           data[2], *p;

    p = data;
    UINT16_TO_BE_STREAM (p, random_number);

    status = NDEF_MsgAddRec (p_msg, max_size, p_cur_size,
                             NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN,
                             NULL, 0, data, 2);
    return (status);
}
/*******************************************************************************
**
** Function         avrc_bld_set_abs_volume_cmd
**
** Description      This function builds the Set Absolute Volume command.
**
** Returns          AVRC_STS_NO_ERROR, if the command is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_set_abs_volume_cmd (tAVRC_SET_VOLUME_CMD *p_cmd, BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start;

    AVRC_TRACE_API("avrc_bld_set_abs_volume_cmd");
    /* get the existing length, if any, and also the num attributes */
    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_start + 2; /* pdu + rsvd */
    /* add fixed lenth 1 - volume (1) */
    UINT16_TO_BE_STREAM(p_data, 1);
    UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_cmd->volume));
    p_pkt->len = (p_data - p_start);
    return AVRC_STS_NO_ERROR;
}
Пример #21
0
/*******************************************************************************
**
** Function         rw_t4t_read_file
**
** Description      Send ReadBinary Command to peer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN rw_t4t_read_file (UINT16 offset, UINT16 length, BOOLEAN is_continue)
{
    tRW_T4T_CB      *p_t4t = &rw_cb.tcb.t4t;
    BT_HDR          *p_c_apdu;
    UINT8           *p;

    RW_TRACE_DEBUG3 ("rw_t4t_read_file () offset:%d, length:%d, is_continue:%d, ",
                      offset, length, is_continue);

    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);

    if (!p_c_apdu)
    {
        RW_TRACE_ERROR0 ("rw_t4t_read_file (): Cannot allocate buffer");
        return FALSE;
    }

    /* if this is the first reading */
    if (is_continue == FALSE)
    {
        /* initialise starting offset and total length */
        /* these will be updated when receiving response */
        p_t4t->rw_offset = offset;
        p_t4t->rw_length = length;
    }

    /* adjust reading length if payload is bigger than max size per single command */
    if (length > p_t4t->max_read_size)
    {
        length = (UINT8) (p_t4t->max_read_size);
    }

    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;

    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_READ_BINARY);
    UINT16_TO_BE_STREAM (p, offset);
    UINT8_TO_BE_STREAM (p, length); /* Le */

    p_c_apdu->len = T4T_CMD_MIN_HDR_SIZE + 1; /* adding Le */

    if (!rw_t4t_send_to_lower (p_c_apdu))
    {
        return FALSE;
    }

    return TRUE;
}
/*******************************************************************************
**
** Function         avrc_bld_vol_change_notfn
**
** Description      This function builds the register notification for volume change.
**
** Returns          AVRC_STS_NO_ERROR, if the command is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_vol_change_notfn(BT_HDR * p_pkt)
{
    UINT8   *p_data, *p_start;

    AVRC_TRACE_API("avrc_bld_vol_change");
    /* get the existing length, if any, and also the num attributes */
    // Set the notify value
    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_start + 2; /* pdu + rsvd */
    /* add fixed length 5 -*/
    UINT16_TO_BE_STREAM(p_data, 5);
    UINT8_TO_BE_STREAM(p_data,AVRC_EVT_VOLUME_CHANGE);
    UINT32_TO_BE_STREAM(p_data, 0);
    p_pkt->len = (p_data - p_start);
    return AVRC_STS_NO_ERROR;
}
/*******************************************************************************
**
** Function         avrc_bld_group_navigation_rsp
**
** Description      This function builds the Group Navigation
**                  response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
tAVRC_STS avrc_bld_group_navigation_rsp (UINT16 navi_id, BT_HDR *p_pkt)
{
    UINT8   *p_data;

    if (!AVRC_IS_VALID_GROUP(navi_id))
    {
        AVRC_TRACE_ERROR1("avrc_bld_group_navigation_rsp bad navigation op id: %d", navi_id);
        return AVRC_STS_BAD_PARAM;
    }

    AVRC_TRACE_API0("avrc_bld_group_navigation_rsp");
    p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
    UINT16_TO_BE_STREAM(p_data, navi_id);
    p_pkt->len = 2;
    return AVRC_STS_NO_ERROR;
}
/*******************************************************************************
**
** Function         avrc_bld_rejected_rsp
**
** Description      This function builds the General Response response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_rejected_rsp( tAVRC_RSP *p_rsp, BT_HDR *p_pkt )
{
    UINT8 *p_data, *p_start;

    AVRC_TRACE_API2("avrc_bld_rejected_rsp: status=%d, pdu:x%x", p_rsp->status, p_rsp->pdu);

    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_start + 2;
    AVRC_TRACE_DEBUG1("pdu:x%x", *p_start);

    UINT16_TO_BE_STREAM(p_data, 1);
    UINT8_TO_BE_STREAM(p_data, p_rsp->status);
    p_pkt->len = p_data - p_start;

    return AVRC_STS_NO_ERROR;
}
/*******************************************************************************
**
** Function         avrc_bld_get_play_status_rsp
**
** Description      This function builds the Get Play Status
**                  response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp, BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start;

    AVRC_TRACE_API0("avrc_bld_get_play_status_rsp");
    p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
    p_data = p_start + 2;

    /* add fixed lenth - song len(4) + song position(4) + status(1) */
    UINT16_TO_BE_STREAM(p_data, 9);
    UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
    UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
    UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
    p_pkt->len = (p_data - p_start);

    return AVRC_STS_NO_ERROR;
}
/*******************************************************************************
**
** Function         avrc_bld_next_cmd
**
** Description      This function builds the Request Continue or Abort command.
**
** Returns          AVRC_STS_NO_ERROR, if the command is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_next_cmd (tAVRC_NEXT_CMD *p_cmd, BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start;

    AVRC_TRACE_API("avrc_bld_next_cmd");

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

    /* add fixed lenth 1 - pdu_id (1) */
    UINT16_TO_BE_STREAM(p_data, 1);
    UINT8_TO_BE_STREAM(p_data, p_cmd->target_pdu);
    p_pkt->len = (p_data - p_start);

    return AVRC_STS_NO_ERROR;
}
/*******************************************************************************
**
** Function         avrc_bld_get_cur_app_setting_value_rsp
**
** Description      This function builds the Get Current Application Setting Value
**                  response.
**
** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
**                  Otherwise, the error code.
**
*******************************************************************************/
static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp (tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp,
    BT_HDR *p_pkt)
{
    UINT8   *p_data, *p_start, *p_len, *p_count;
    UINT16  len;
    UINT8   xx;

    if (!p_rsp->p_vals)
    {
        AVRC_TRACE_ERROR0("avrc_bld_get_cur_app_setting_value_rsp NULL parameter");
        return AVRC_STS_BAD_PARAM;
    }

    AVRC_TRACE_API0("avrc_bld_get_cur_app_setting_value_rsp");
    /* 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)
    {
        /* first time initialize the attribute count */
        *p_count = 0;
        p_data++;
    }
    else
    {
        p_data = p_start + p_pkt->len;
    }

    for (xx=0; xx<p_rsp->num_val; xx++)
    {
        if (avrc_is_valid_player_attrib_value(p_rsp->p_vals[xx].attr_id, p_rsp->p_vals[xx].attr_val))
        {
            (*p_count)++;
            UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_id);
            UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_val);
        }
    }
    len = ((*p_count) << 1) + 1;
    UINT16_TO_BE_STREAM(p_len, len);
    p_pkt->len = (p_data - p_start);

    return AVRC_STS_NO_ERROR;
}
/*******************************************************************************
**
** Function         llcp_sdp_check_send_snl
**
** Description      Enqueue Service Name Lookup PDU into sig_xmit_q for transmitting
**
**
** Returns          void
**
*******************************************************************************/
void llcp_sdp_check_send_snl (void)
{
    UINT8 *p;

    if (llcp_cb.sdp_cb.p_snl)
    {
        LLCP_TRACE_DEBUG0 ("SDP: llcp_sdp_check_send_snl ()");

        llcp_cb.sdp_cb.p_snl->len     += LLCP_PDU_HEADER_SIZE;
        llcp_cb.sdp_cb.p_snl->offset  -= LLCP_PDU_HEADER_SIZE;

        p = (UINT8 *) (llcp_cb.sdp_cb.p_snl + 1) + llcp_cb.sdp_cb.p_snl->offset;
        UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_SDP, LLCP_PDU_SNL_TYPE, LLCP_SAP_SDP ));

        GKI_enqueue (&llcp_cb.lcb.sig_xmit_q, llcp_cb.sdp_cb.p_snl);
        llcp_cb.sdp_cb.p_snl = NULL;
    }
}
Пример #29
0
/*******************************************************************************
**
** Function         rw_t4t_select_file
**
** Description      Send Select Command (by File ID) to peer
**
** Returns          TRUE if success
**
*******************************************************************************/
static BOOLEAN rw_t4t_select_file (UINT16 file_id)
{
    BT_HDR      *p_c_apdu;
    UINT8       *p;

    RW_TRACE_DEBUG1 ("rw_t4t_select_file (): File ID:0x%04X", file_id);

    p_c_apdu = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID);

    if (!p_c_apdu)
    {
        RW_TRACE_ERROR0 ("rw_t4t_select_file (): Cannot allocate buffer");
        return FALSE;
    }

    p_c_apdu->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    p = (UINT8 *) (p_c_apdu + 1) + p_c_apdu->offset;

    UINT8_TO_BE_STREAM (p, T4T_CMD_CLASS);
    UINT8_TO_BE_STREAM (p, T4T_CMD_INS_SELECT);
    UINT8_TO_BE_STREAM (p, T4T_CMD_P1_SELECT_BY_FILE_ID);

    /* if current version mapping is V2.0 */
    if (rw_cb.tcb.t4t.version == T4T_VERSION_2_0)
    {
        UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_0CH);
    }
    else /* version 1.0 */
    {
        UINT8_TO_BE_STREAM (p, T4T_CMD_P2_FIRST_OR_ONLY_00H);
    }

    UINT8_TO_BE_STREAM (p, T4T_FILE_ID_SIZE);
    UINT16_TO_BE_STREAM (p, file_id);

    p_c_apdu->len = T4T_CMD_MAX_HDR_SIZE + T4T_FILE_ID_SIZE;

    if (!rw_t4t_send_to_lower (p_c_apdu))
    {
        return FALSE;
    }

    return TRUE;
}
/*******************************************************************************
**
** Function         mca_ccb_snd_rsp
**
** Description      This function builds a response and sends it to
**                  the peer.
**
** Returns          void.
**
*******************************************************************************/
void mca_ccb_snd_rsp(tMCA_CCB *p_ccb, tMCA_CCB_EVT *p_data)
{
    tMCA_CCB_MSG *p_msg = (tMCA_CCB_MSG *)p_data;
    BT_HDR  *p_pkt;
    UINT8   *p, *p_start;
    BOOLEAN chk_mdl = FALSE;
    tMCA_DCB    *p_dcb;

    MCA_TRACE_DEBUG ("mca_ccb_snd_rsp cong=%d req=%d", p_ccb->cong, p_msg->op_code);
    /* assume that API functions verified the parameters */
    p_pkt = (BT_HDR *)GKI_getbuf (MCA_CTRL_MTU);
    if (p_pkt)
    {
        p_pkt->offset = L2CAP_MIN_OFFSET;
        p = p_start = (UINT8*)(p_pkt + 1) + L2CAP_MIN_OFFSET;
        *p++ = p_msg->op_code;
        *p++ = p_msg->rsp_code;
        UINT16_TO_BE_STREAM (p, p_msg->mdl_id);
        if (p_msg->op_code == MCA_OP_MDL_CREATE_RSP)
        {
            *p++ = p_msg->param;
            chk_mdl = TRUE;
        }
        else if (p_msg->op_code == MCA_OP_MDL_RECONNECT_RSP)
            chk_mdl = TRUE;

        if (chk_mdl && p_msg->rsp_code == MCA_RSP_SUCCESS)
        {
            p_dcb = mca_dcb_by_hdl(p_msg->dcb_idx);
            BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_MCAP_DATA, p_ccb->sec_mask,
                                 p_ccb->p_rcb->reg.data_psm, BTM_SEC_PROTO_MCA, p_msg->dcb_idx);
            p_ccb->status = MCA_CCB_STAT_PENDING;
            /* set p_tx_req to block API_REQ/API_RSP before DL is up */
            mca_free_buf ((void **)&p_ccb->p_tx_req);
            p_ccb->p_tx_req = p_ccb->p_rx_msg;
            p_ccb->p_rx_msg = NULL;
            p_ccb->p_tx_req->dcb_idx = p_msg->dcb_idx;
        }
        mca_free_buf ((void **)&p_ccb->p_rx_msg);
        p_pkt->len = p - p_start;
        L2CA_DataWrite (p_ccb->lcid, p_pkt);
    }

}