aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/nfc.h2
-rw-r--r--net/nfc/netlink.c91
2 files changed, 93 insertions, 0 deletions
diff --git a/include/uapi/linux/nfc.h b/include/uapi/linux/nfc.h
index 539d60494c04..029921b067fd 100644
--- a/include/uapi/linux/nfc.h
+++ b/include/uapi/linux/nfc.h
@@ -84,6 +84,7 @@
84 * @NFC_EVENT_SE_TRANSACTION: This event is sent when an application running on 84 * @NFC_EVENT_SE_TRANSACTION: This event is sent when an application running on
85 * a specific SE notifies us about the end of a transaction. The parameter 85 * a specific SE notifies us about the end of a transaction. The parameter
86 * for this event is the application ID (AID). 86 * for this event is the application ID (AID).
87 * @NFC_CMD_GET_SE: Dump all discovered secure elements from an NFC controller.
87 */ 88 */
88enum nfc_commands { 89enum nfc_commands {
89 NFC_CMD_UNSPEC, 90 NFC_CMD_UNSPEC,
@@ -112,6 +113,7 @@ enum nfc_commands {
112 NFC_EVENT_SE_REMOVED, 113 NFC_EVENT_SE_REMOVED,
113 NFC_EVENT_SE_CONNECTIVITY, 114 NFC_EVENT_SE_CONNECTIVITY,
114 NFC_EVENT_SE_TRANSACTION, 115 NFC_EVENT_SE_TRANSACTION,
116 NFC_CMD_GET_SE,
115/* private: internal use only */ 117/* private: internal use only */
116 __NFC_CMD_AFTER_LAST 118 __NFC_CMD_AFTER_LAST
117}; 119};
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index f16fd59d4160..3b08ef90e045 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1191,6 +1191,91 @@ static int nfc_genl_disable_se(struct sk_buff *skb, struct genl_info *info)
1191 return rc; 1191 return rc;
1192} 1192}
1193 1193
1194static int nfc_genl_send_se(struct sk_buff *msg, struct nfc_dev *dev,
1195 u32 portid, u32 seq,
1196 struct netlink_callback *cb,
1197 int flags)
1198{
1199 void *hdr;
1200 struct nfc_se *se, *n;
1201
1202 list_for_each_entry_safe(se, n, &dev->secure_elements, list) {
1203 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
1204 NFC_CMD_GET_SE);
1205 if (!hdr)
1206 goto nla_put_failure;
1207
1208 if (cb)
1209 genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
1210
1211 if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
1212 nla_put_u32(msg, NFC_ATTR_SE_INDEX, se->idx) ||
1213 nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type))
1214 goto nla_put_failure;
1215
1216 if (genlmsg_end(msg, hdr) < 0)
1217 goto nla_put_failure;
1218 }
1219
1220 return 0;
1221
1222nla_put_failure:
1223 genlmsg_cancel(msg, hdr);
1224 return -EMSGSIZE;
1225}
1226
1227static int nfc_genl_dump_ses(struct sk_buff *skb,
1228 struct netlink_callback *cb)
1229{
1230 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
1231 struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
1232 bool first_call = false;
1233
1234 if (!iter) {
1235 first_call = true;
1236 iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
1237 if (!iter)
1238 return -ENOMEM;
1239 cb->args[0] = (long) iter;
1240 }
1241
1242 mutex_lock(&nfc_devlist_mutex);
1243
1244 cb->seq = nfc_devlist_generation;
1245
1246 if (first_call) {
1247 nfc_device_iter_init(iter);
1248 dev = nfc_device_iter_next(iter);
1249 }
1250
1251 while (dev) {
1252 int rc;
1253
1254 rc = nfc_genl_send_se(skb, dev, NETLINK_CB(cb->skb).portid,
1255 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
1256 if (rc < 0)
1257 break;
1258
1259 dev = nfc_device_iter_next(iter);
1260 }
1261
1262 mutex_unlock(&nfc_devlist_mutex);
1263
1264 cb->args[1] = (long) dev;
1265
1266 return skb->len;
1267}
1268
1269static int nfc_genl_dump_ses_done(struct netlink_callback *cb)
1270{
1271 struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
1272
1273 nfc_device_iter_exit(iter);
1274 kfree(iter);
1275
1276 return 0;
1277}
1278
1194static struct genl_ops nfc_genl_ops[] = { 1279static struct genl_ops nfc_genl_ops[] = {
1195 { 1280 {
1196 .cmd = NFC_CMD_GET_DEVICE, 1281 .cmd = NFC_CMD_GET_DEVICE,
@@ -1265,6 +1350,12 @@ static struct genl_ops nfc_genl_ops[] = {
1265 .doit = nfc_genl_disable_se, 1350 .doit = nfc_genl_disable_se,
1266 .policy = nfc_genl_policy, 1351 .policy = nfc_genl_policy,
1267 }, 1352 },
1353 {
1354 .cmd = NFC_CMD_GET_SE,
1355 .dumpit = nfc_genl_dump_ses,
1356 .done = nfc_genl_dump_ses_done,
1357 .policy = nfc_genl_policy,
1358 },
1268}; 1359};
1269 1360
1270 1361