diff options
author | Ilan Elias <ilane@ti.com> | 2012-08-15 11:46:24 +0300 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-09-25 00:17:23 +0200 |
commit | 767f19ae698e535f308663c48245fa951abebe20 (patch) | |
tree | 98c9353741a371d9c812f81c577fa36e0c4e5451 | |
parent | ac206838403411e617dbe0e7df1891ee957f1f9a (diff) |
NFC: Implement NCI dep_link_up and dep_link_down
During NFC-DEP target activation, store the remote
general bytes to be used later in dep_link_up.
When dep_link_up is called, activate the NFC-DEP target,
and forward the remote general bytes.
When dep_link_down is called, deactivate the target.
Signed-off-by: Ilan Elias <ilane@ti.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | include/net/nfc/nci_core.h | 4 | ||||
-rw-r--r-- | include/net/nfc/nfc.h | 1 | ||||
-rw-r--r-- | net/nfc/nci/core.c | 36 | ||||
-rw-r--r-- | net/nfc/nci/ntf.c | 20 |
4 files changed, 60 insertions, 1 deletions
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index f98674d7baf1..d705d8674949 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -138,6 +138,10 @@ struct nci_dev { data_exchange_cb_t data_exchange_cb; void *data_exchange_cb_context; struct sk_buff *rx_data_reassembly; + + /* stored during intf_activated_ntf */ + __u8 remote_gb[NFC_MAX_GT_LEN]; + __u8 remote_gb_len; }; /* ----- NCI Devices ----- */ diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 6431f5e39022..7b9f71fa0ea7 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -72,6 +72,7 @@ struct nfc_ops { #define NFC_TARGET_IDX_ANY -1 #define NFC_MAX_GT_LEN 48 +#define NFC_ATR_RES_GT_OFFSET 15 struct nfc_target { u32 idx; diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index f017b781667a..acf9abb7d99b 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -564,7 +564,7 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, { struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); - pr_debug("target_idx %d\n", target->idx); + pr_debug("entry\n"); if (!ndev->target_active_prot) { pr_err("unable to deactivate target, no active target\n"); @@ -579,6 +579,38 @@ static void nci_deactivate_target(struct nfc_dev *nfc_dev, } } + +static int nci_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, + __u8 comm_mode, __u8 *gb, size_t gb_len) +{ + struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); + int rc; + + pr_debug("target_idx %d, comm_mode %d\n", target->idx, comm_mode); + + rc = nci_activate_target(nfc_dev, target, NFC_PROTO_NFC_DEP); + if (rc) + return rc; + + rc = nfc_set_remote_general_bytes(nfc_dev, ndev->remote_gb, + ndev->remote_gb_len); + if (!rc) + rc = nfc_dep_link_is_up(nfc_dev, target->idx, NFC_COMM_PASSIVE, + NFC_RF_INITIATOR); + + return rc; +} + +static int nci_dep_link_down(struct nfc_dev *nfc_dev) +{ + pr_debug("entry\n"); + + nci_deactivate_target(nfc_dev, NULL); + + return 0; +} + + static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context) @@ -612,6 +644,8 @@ static struct nfc_ops nci_nfc_ops = { .dev_down = nci_dev_down, .start_poll = nci_start_poll, .stop_poll = nci_stop_poll, + .dep_link_up = nci_dep_link_up, + .dep_link_down = nci_dep_link_down, .activate_target = nci_activate_target, .deactivate_target = nci_deactivate_target, .im_transceive = nci_transceive, diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 6e17661a41a4..b2aa98ef0927 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -176,6 +176,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev, protocol = NFC_PROTO_ISO14443_B_MASK; else if (rf_protocol == NCI_RF_PROTOCOL_T3T) protocol = NFC_PROTO_FELICA_MASK; + else if (rf_protocol == NCI_RF_PROTOCOL_NFC_DEP) + protocol = NFC_PROTO_NFC_DEP_MASK; else protocol = 0; @@ -505,6 +507,24 @@ exit: /* set the available credits to initial value */ atomic_set(&ndev->credits_cnt, ndev->initial_num_credits); + + /* store general bytes to be reported later in dep_link_up */ + if (ntf.rf_interface == NCI_RF_INTERFACE_NFC_DEP) { + ndev->remote_gb_len = 0; + + if (ntf.activation_params_len > 0) { + /* ATR_RES general bytes at offset 15 */ + ndev->remote_gb_len = min_t(__u8, + (ntf.activation_params + .poll_nfc_dep.atr_res_len + - NFC_ATR_RES_GT_OFFSET), + NFC_MAX_GT_LEN); + memcpy(ndev->remote_gb, + (ntf.activation_params.poll_nfc_dep + .atr_res + NFC_ATR_RES_GT_OFFSET), + ndev->remote_gb_len); + } + } } if (atomic_read(&ndev->state) == NCI_DISCOVERY) { |