diff options
-rw-r--r-- | include/net/nfc/nfc.h | 27 | ||||
-rw-r--r-- | include/uapi/linux/nfc.h | 1 | ||||
-rw-r--r-- | net/nfc/core.c | 21 | ||||
-rw-r--r-- | net/nfc/netlink.c | 47 | ||||
-rw-r--r-- | net/nfc/nfc.h | 2 |
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 | ||
156 | struct 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 | |||
138 | struct nfc_genl_data { | 163 | struct 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 | ||
263 | void nfc_driver_failure(struct nfc_dev *dev, int err); | 288 | void nfc_driver_failure(struct nfc_dev *dev, int err); |
264 | 289 | ||
290 | int nfc_se_transaction(struct nfc_dev *dev, u8 se_idx, | ||
291 | struct nfc_evt_transaction *evt_transaction); | ||
265 | int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type); | 292 | int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type); |
266 | int nfc_remove_se(struct nfc_dev *dev, u32 se_idx); | 293 | int nfc_remove_se(struct nfc_dev *dev, u32 se_idx); |
267 | struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx); | 294 | struct 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 | } |
933 | EXPORT_SYMBOL(nfc_remove_se); | 933 | EXPORT_SYMBOL(nfc_remove_se); |
934 | 934 | ||
935 | int 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); | ||
950 | out: | ||
951 | device_unlock(&dev->dev); | ||
952 | return rc; | ||
953 | } | ||
954 | EXPORT_SYMBOL(nfc_se_transaction); | ||
955 | |||
935 | static void nfc_release(struct device *d) | 956 | static 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 | ||
500 | int 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 | |||
538 | nla_put_failure: | ||
539 | genlmsg_cancel(msg, hdr); | ||
540 | free_msg: | ||
541 | /* evt_transaction is no more used */ | ||
542 | devm_kfree(&dev->dev, evt_transaction); | ||
543 | nlmsg_free(msg); | ||
544 | return -EMSGSIZE; | ||
545 | } | ||
546 | |||
500 | static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, | 547 | static 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 | ||
101 | int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type); | 101 | int nfc_genl_se_added(struct nfc_dev *dev, u32 se_idx, u16 type); |
102 | int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx); | 102 | int nfc_genl_se_removed(struct nfc_dev *dev, u32 se_idx); |
103 | int nfc_genl_se_transaction(struct nfc_dev *dev, u8 se_idx, | ||
104 | struct nfc_evt_transaction *evt_transaction); | ||
103 | 105 | ||
104 | struct nfc_dev *nfc_get_device(unsigned int idx); | 106 | struct nfc_dev *nfc_get_device(unsigned int idx); |
105 | 107 | ||