Skip to content

Commit

Permalink
NFC Digital: Add initiator NFC-DEP support
Browse files Browse the repository at this point in the history
This adds support for NFC-DEP protocol in initiator mode for NFC-A and
NFC-F technologies.

When a target is detected, the process flow is as follow:

For NFC-A technology:
1 - The digital stack receives a SEL_RES as the reply of the SEL_REQ
    command.
2   - If b7 of SEL_RES is set, the peer device is configure for NFC-DEP
      protocol. NFC core is notified through nfc_targets_found().
      Execution continues at step 4.
3   - Otherwise, it's a tag and the NFC core is notified. Detection
      ends.
4 - The digital stacks sends an ATR_REQ command containing a randomly
    generated NFCID3 and the general bytes obtained from the LLCP layer
    of NFC core.

For NFC-F technology:
1 - The digital stack receives a SENSF_RES as the reply of the
    SENSF_REQ command.
2   - If B1 and B2 of NFCID2 are 0x01 and 0xFE respectively, the peer
      device is configured for NFC-DEP protocol. NFC core is notified
      through nfc_targets_found(). Execution continues at step 4.
3   - Otherwise it's a type 3 tag. NFC core is notified. Detection
      ends.
4 - The digital stacks sends an ATR_REQ command containing the NFC-F
    NFCID2 as NFCID3 and the general bytes obtained from the LLCP layer
    of NFC core.

For both technologies:
5 - The digital stacks receives the ATR_RES response containing the
    NFCID3 and the general bytes of the peer device.
6 - The digital stack notifies NFC core that the DEP link is up through
    nfc_dep_link_up().
7 - The NFC core performs data exchange through tm_transceive().
8 - The digital stack sends a DEP_REQ command containing an I PDU with
    the data from NFC core.
9 - The digital stack receives a DEP_RES command
10  - If the DEP_RES response contains a supervisor PDU with timeout
      extension request (RTOX) the digital stack sends a DEP_REQ
      command containing a supervisor PDU acknowledging the RTOX
      request. The execution continues at step 9.
11  - If the DEP_RES response contains an I PDU, the response data is
      passed back to NFC core through the response callback. The
      execution continues at step 8.

Signed-off-by: Thierry Escande <[email protected]>
Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
Thierry Escande authored and Samuel Ortiz committed Sep 25, 2013
1 parent 8c0695e commit 7d0911c
Show file tree
Hide file tree
Showing 5 changed files with 435 additions and 6 deletions.
2 changes: 1 addition & 1 deletion net/nfc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ obj-$(CONFIG_NFC_DIGITAL) += nfc_digital.o
nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \
llcp_sock.o

nfc_digital-objs := digital_core.o digital_technology.o
nfc_digital-objs := digital_core.o digital_technology.o digital_dep.o
14 changes: 14 additions & 0 deletions net/nfc/digital.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
#define DIGITAL_MAX_HEADER_LEN 7
#define DIGITAL_CRC_LEN 2

#define DIGITAL_SENSF_NFCID2_NFC_DEP_B1 0x01
#define DIGITAL_SENSF_NFCID2_NFC_DEP_B2 0xFE

#define DIGITAL_SENS_RES_NFC_DEP 0x0100
#define DIGITAL_SEL_RES_NFC_DEP 0x40
#define DIGITAL_SENSF_FELICA_SC 0xFFFF

#define DIGITAL_DRV_CAPS_IN_CRC(ddev) \
((ddev)->driver_capabilities & NFC_DIGITAL_DRV_CAPS_IN_CRC)
#define DIGITAL_DRV_CAPS_TG_CRC(ddev) \
Expand Down Expand Up @@ -72,6 +79,13 @@ int digital_target_found(struct nfc_digital_dev *ddev,

int digital_in_recv_mifare_res(struct sk_buff *resp);

int digital_in_send_atr_req(struct nfc_digital_dev *ddev,
struct nfc_target *target, __u8 comm_mode, __u8 *gb,
size_t gb_len);
int digital_in_send_dep_req(struct nfc_digital_dev *ddev,
struct nfc_target *target, struct sk_buff *skb,
struct digital_data_exch *data_exch);

typedef u16 (*crc_func_t)(u16, const u8 *, size_t);

#define CRC_A_INIT 0x6363
Expand Down
32 changes: 28 additions & 4 deletions net/nfc/digital_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
#include "digital.h"

#define DIGITAL_PROTO_NFCA_RF_TECH \
(NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK)
(NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK | NFC_PROTO_NFC_DEP_MASK)

#define DIGITAL_PROTO_NFCF_RF_TECH (NFC_PROTO_FELICA_MASK)
#define DIGITAL_PROTO_NFCF_RF_TECH \
(NFC_PROTO_FELICA_MASK | NFC_PROTO_NFC_DEP_MASK)

struct digital_cmd {
struct list_head queue;
Expand Down Expand Up @@ -260,6 +261,18 @@ int digital_target_found(struct nfc_digital_dev *ddev,
add_crc = digital_skb_add_crc_f;
break;

case NFC_PROTO_NFC_DEP:
if (rf_tech == NFC_DIGITAL_RF_TECH_106A) {
framing = NFC_DIGITAL_FRAMING_NFCA_NFC_DEP;
check_crc = digital_skb_check_crc_a;
add_crc = digital_skb_add_crc_a;
} else {
framing = NFC_DIGITAL_FRAMING_NFCF_NFC_DEP;
check_crc = digital_skb_check_crc_f;
add_crc = digital_skb_add_crc_f;
}
break;

default:
PR_ERR("Invalid protocol %d", protocol);
return -EINVAL;
Expand Down Expand Up @@ -453,12 +466,18 @@ static int digital_dep_link_up(struct nfc_dev *nfc_dev,
struct nfc_target *target,
__u8 comm_mode, __u8 *gb, size_t gb_len)
{
return -EOPNOTSUPP;
struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);

return digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len);
}

static int digital_dep_link_down(struct nfc_dev *nfc_dev)
{
return -EOPNOTSUPP;
struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);

ddev->curr_protocol = 0;

return 0;
}

static int digital_activate_target(struct nfc_dev *nfc_dev,
Expand Down Expand Up @@ -523,6 +542,9 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target,
data_exch->cb = cb;
data_exch->cb_context = cb_context;

if (ddev->curr_protocol == NFC_PROTO_NFC_DEP)
return digital_in_send_dep_req(ddev, target, skb, data_exch);

ddev->skb_add_crc(skb);

return digital_in_send_cmd(ddev, skb, 500, digital_in_send_complete,
Expand Down Expand Up @@ -578,6 +600,8 @@ struct nfc_digital_dev *nfc_digital_allocate_device(struct nfc_digital_ops *ops,
ddev->protocols |= NFC_PROTO_MIFARE_MASK;
if (supported_protocols & NFC_PROTO_FELICA_MASK)
ddev->protocols |= NFC_PROTO_FELICA_MASK;
if (supported_protocols & NFC_PROTO_NFC_DEP_MASK)
ddev->protocols |= NFC_PROTO_NFC_DEP_MASK;

ddev->tx_headroom = tx_headroom + DIGITAL_MAX_HEADER_LEN;
ddev->tx_tailroom = tx_tailroom + DIGITAL_CRC_LEN;
Expand Down
Loading

0 comments on commit 7d0911c

Please sign in to comment.