aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/nfc/nfc.h27
-rw-r--r--include/uapi/linux/nfc.h1
-rw-r--r--net/nfc/core.c21
-rw-r--r--net/nfc/netlink.c47
-rw-r--r--net/nfc/nfc.h2
5 files changed, 98 insertions, 0 deletions
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index 12adb817c27a..73190e65d5c1 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -135,6 +135,31 @@ struct nfc_se {
135 u16 state; 135 u16 state;
136}; 136};
137 137
138/**
139 * nfc_evt_transaction - A struct for NFC secure element event transaction.
140 *
141 * @aid: The application identifier triggering the event
142 *
143 * @aid_len: The application identifier length [5:16]
144 *
145 * @params: The application parameters transmitted during the transaction
146 *
147 * @params_len: The applications parameters length [0:255]
148 *
149 */
150#define NFC_MIN_AID_LENGTH 5
151#define NFC_MAX_AID_LENGTH 16
152#define NFC_MAX_PARAMS_LENGTH 255
153
154#define NFC_EVT_TRANSACTION_AID_TAG 0x81
155#define NFC_EVT_TRANSACTION_PARAMS_TAG 0x82
156struct nfc_evt_transaction {
157 u32 aid_len;
158 u8 aid[NFC_MAX_AID_LENGTH];
159 u8 params_len;
160 u8 params[NFC_MAX_PARAMS_LENGTH];
161} __packed;
162
138struct nfc_genl_data { 163struct nfc_genl_data {
139 u32 poll_req_portid; 164 u32 poll_req_portid;
140 struct mutex genl_data_mutex; 165 struct mutex genl_data_mutex;
@@ -262,6 +287,8 @@ int nfc_tm_data_received(struct nfc_dev *dev, struct sk_buff *skb);
262 287
263void nfc_driver_failure(struct nfc_dev *dev, int err); 288void nfc_driver_failure(struct nfc_dev *dev, int err);
264 289
290int nfc_se_transaction(struct nfc_dev *dev, u8 se_idx,
291 struct nfc_evt_transaction *evt_transaction);
265int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type); 292int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type);
266int nfc_remove_se(struct nfc_dev *dev, u32 se_idx); 293int nfc_remove_se(struct nfc_dev *dev, u32 se_idx);
267struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx); 294struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx);
diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h
index 8119255feae4..c1e2e63cf9b5 100644
--- a/include/uapi/linux/nfc.h
+++ b/include/uapi/linux/nfc.h
@@ -183,6 +183,7 @@ enum nfc_attrs {
183 NFC_ATTR_SE_APDU, 183 NFC_ATTR_SE_APDU,
184 NFC_ATTR_TARGET_ISO15693_DSFID, 184 NFC_ATTR_TARGET_ISO15693_DSFID,
185 NFC_ATTR_TARGET_ISO15693_UID, 185 NFC_ATTR_TARGET_ISO15693_UID,
186 NFC_ATTR_SE_PARAMS,
186/* private: internal use only */ 187/* private: internal use only */
187 __NFC_ATTR_AFTER_LAST 188 __NFC_ATTR_AFTER_LAST
188}; 189};
diff --git a/net/nfc/core.c b/net/nfc/core.c
index 7f1b6351755c..cff3f1614ad4 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -932,6 +932,27 @@ int nfc_remove_se(struct nfc_dev *dev, u32 se_idx)
932} 932}
933EXPORT_SYMBOL(nfc_remove_se); 933EXPORT_SYMBOL(nfc_remove_se);
934 934
935int nfc_se_transaction(struct nfc_dev *dev, u8 se_idx,
936 struct nfc_evt_transaction *evt_transaction)
937{
938 int rc;
939
940 pr_debug("transaction: %x\n", se_idx);
941
942 device_lock(&dev->dev);
943
944 if (!evt_transaction) {
945 rc = -EPROTO;
946 goto out;
947 }
948
949 rc = nfc_genl_se_transaction(dev, se_idx, evt_transaction);
950out:
951 device_unlock(&dev->dev);
952 return rc;
953}
954EXPORT_SYMBOL(nfc_se_transaction);
955
935static void nfc_release(struct device *d) 956static void nfc_release(struct device *d)
936{ 957{
937 struct nfc_dev *dev = to_nfc_dev(d); 958 struct nfc_dev *dev = to_nfc_dev(d);
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index be387e6219a0..14a2d11581da 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -497,6 +497,53 @@ free_msg:
497 return -EMSGSIZE; 497 return -EMSGSIZE;
498} 498}
499 499
500int nfc_genl_se_transaction(struct nfc_dev *dev, u8 se_idx,
501 struct nfc_evt_transaction *evt_transaction)
502{
503 struct nfc_se *se;
504 struct sk_buff *msg;
505 void *hdr;
506
507 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
508 if (!msg)
509 return -ENOMEM;
510
511 hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
512 NFC_EVENT_SE_TRANSACTION);
513 if (!hdr)
514 goto free_msg;
515
516 se = nfc_find_se(dev, se_idx);
517 if (!se)
518 goto free_msg;
519
520 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
521 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se_idx) ||
522 nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type) ||
523 nla_put(msg, NFC_ATTR_SE_AID, evt_transaction->aid_len,
524 evt_transaction->aid) ||
525 nla_put(msg, NFC_ATTR_SE_PARAMS, evt_transaction->params_len,
526 evt_transaction->params))
527 goto nla_put_failure;
528
529 /* evt_transaction is no more used */
530 devm_kfree(&dev->dev, evt_transaction);
531
532 genlmsg_end(msg, hdr);
533
534 genlmsg_multicast(&nfc_genl_family, msg, 0, 0, GFP_KERNEL);
535
536 return 0;
537
538nla_put_failure:
539 genlmsg_cancel(msg, hdr);
540free_msg:
541 /* evt_transaction is no more used */
542 devm_kfree(&dev->dev, evt_transaction);
543 nlmsg_free(msg);
544 return -EMSGSIZE;
545}
546
500static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, 547static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
501 u32 portid, u32 seq, 548 u32 portid, u32 seq,
502 struct netlink_callback *cb, 549 struct netlink_callback *cb,
diff --git a/net/nfc/nfc.h b/net/nfc/nfc.h
index 88d60064890e..a8ce80b47720 100644
--- a/net/nfc/nfc.h
+++ b/net/nfc/nfc.h
@@ -100,6 +100,8 @@ int nfc_genl_llc_send_sdres(struct nfc_dev *dev, struct hlist_head *sdres_list);
100 100
101int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type); 101int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type);
102int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx); 102int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx);
103int nfc_genl_se_transaction(struct nfc_dev *dev, u8 se_idx,
104 struct nfc_evt_transaction *evt_transaction);
103 105
104struct nfc_dev *nfc_get_device(unsigned int idx); 106struct nfc_dev *nfc_get_device(unsigned int idx);
105 107