static size_t
idle_process_cmd(const union hci_packet* cmd, struct nfc_device* nfc,
                 union hci_answer* rsp)
{
    size_t len = 0;

    assert(cmd);

    if (cmd->control.service == HCI_SERVICE_BCM2079x) {
        switch (cmd->control.cmd) {
            case HCI_MESSAGE_RFU|HCI_BCM2079x_CMD_WRITE_SLEEP_MODE:
                len = idle_process_bcm2079x_write_sleep_mode_cmd(cmd, nfc, rsp);
                break;
            default:
                NFC_D("unknown command");
                return 0;
        }
    }
    NFC_D("result length=%ld", (long)len);

    return len;
}
Exemple #2
0
static size_t
process_ptype_rnr(struct nfc_re* re, const struct llcp_pdu* llcp,
                  size_t len, uint8_t* consumed, struct llcp_pdu* rsp)
{
    struct llcp_data_link* dl;
    unsigned int nr;

    nr = llcp->info[0] & 0xf;

    NFC_D("LLCP RNR N(R)=%d", nr);

    dl = re->llcp_dl[llcp->ssap] + llcp->dsap;
    dl->v_sa = nr;

    update_last_saps(re, llcp->ssap, llcp->dsap);

    *consumed = sizeof(*llcp) + 1;
    return 0;
}
Exemple #3
0
static size_t
process_ptype_dm(struct nfc_re* re, const struct llcp_pdu* llcp,
                 size_t len, uint8_t* consumed,
                 struct llcp_pdu* rsp)
{
    struct llcp_data_link* dl;

    NFC_D("LLCP DM, reason=%d\n", llcp->info[0]);

    dl = re->llcp_dl[llcp->ssap] + llcp->dsap;
    dl->status = LLCP_DATA_LINK_DISCONNECTED;

    update_last_saps(re, llcp->ssap, llcp->dsap);

    /* consume 1 extra byte for 'reason' field */
    *consumed = sizeof(*llcp) + 1;

    return 0;
}
Exemple #4
0
static size_t
process_ptype_frmr(struct nfc_re* re, const struct llcp_pdu* llcp,
                size_t len, uint8_t* consumed, struct llcp_pdu* rsp)
{
    unsigned int flags = (llcp->info[0] >> 4) & 0xf;
    unsigned int ptype =  llcp->info[0] & 0xf;
    unsigned int v_s = (llcp->info[2] >> 4) & 0xf;
    unsigned int v_r =  llcp->info[2] & 0xf;
    unsigned int v_sa = (llcp->info[3] >> 4) & 0xf;
    unsigned int v_ra =  llcp->info[3] & 0xf;

    NFC_D("LLCP FRMR flags=%x ptype=%u sequence=%u v_s=%u v_r=%u v_sa=%u "
          "v_sr=%u\n", flags, ptype, llcp->info[1], v_s, v_r, v_sa, v_ra);

    update_last_saps(re, llcp->ssap, llcp->dsap);

    *consumed = sizeof(*llcp) + 4;

    return 0;
}
Exemple #5
0
static size_t
process_ptype_connect(struct nfc_re* re, const struct llcp_pdu* llcp,
                      size_t len, uint8_t* consumed,
                      struct llcp_pdu* rsp)
{
    struct llcp_data_link* dl;
    const uint8_t* opt;

    assert(re);
    assert(llcp);
    assert(consumed);
    assert(rsp);

    dl = llcp_init_data_link(re->llcp_dl[llcp->ssap] + llcp->dsap);
    dl->status = LLCP_DATA_LINK_CONNECTED;

    *consumed = sizeof(*llcp);
    len -= *consumed;

    opt = ((const uint8_t*)llcp) + *consumed;

    while (len >= 2) {
        len -= 2;
        switch (opt[0]) {
            case LLCP_PARAM_MIUX:
                if ((opt[1] != 2) || (len < opt[1])) {
                    continue;
                }
                {
                  const struct llcp_param_miux* param =
                      (const struct llcp_param_miux*)(opt + 2);
                  dl->miu = param->miux - 128;
                }
                NFC_D("LLCP MIU size=%d", dl->miu);
                break;
            case LLCP_PARAM_RW:
                if ((opt[1] != 1) || (len < opt[1])) {
                    continue;
                }
                {
                  const struct llcp_param_rw* param =
                      (const struct llcp_param_rw*)(opt + 2);
                  dl->rw_r = param->rw;
                }
                NFC_D("LLCP remote RW size %d", dl->rw_r);
                break;
            case LLCP_PARAM_SN:
                if (len < opt[1]) {
                    continue;
                }
                NFC_D("requesting LLCP service %.*s\n", opt[1], (const char*)opt+2);
                break;
            default:
                NFC_D("Ignoring unknown LLCP parameter %d\n", opt[0]);
                break;
        }
    }

    update_last_saps(re, llcp->ssap, llcp->dsap);

    /* switch DSAP and SSAP in outgoing PDU */
    return llcp_create_pdu(rsp, llcp->ssap, LLCP_PTYPE_CC, llcp->dsap);
}