Skip to content

Commit

Permalink
NFC: Add a GET_SE netlink API
Browse files Browse the repository at this point in the history
In order to fetch the discovered secure elements from an NFC controller,
we need to send a netlink command that will dump the list of available
SEs from NFC.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
  • Loading branch information
Samuel Ortiz committed Aug 13, 2013
1 parent 369f4d5 commit ac22ac4
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/uapi/linux/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
* @NFC_EVENT_SE_TRANSACTION: This event is sent when an application running on
* a specific SE notifies us about the end of a transaction. The parameter
* for this event is the application ID (AID).
* @NFC_CMD_GET_SE: Dump all discovered secure elements from an NFC controller.
*/
enum nfc_commands {
NFC_CMD_UNSPEC,
Expand Down Expand Up @@ -112,6 +113,7 @@ enum nfc_commands {
NFC_EVENT_SE_REMOVED,
NFC_EVENT_SE_CONNECTIVITY,
NFC_EVENT_SE_TRANSACTION,
NFC_CMD_GET_SE,
/* private: internal use only */
__NFC_CMD_AFTER_LAST
};
Expand Down
91 changes: 91 additions & 0 deletions net/nfc/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,91 @@ static int nfc_genl_disable_se(struct sk_buff *skb, struct genl_info *info)
return rc;
}

static int nfc_genl_send_se(struct sk_buff *msg, struct nfc_dev *dev,
u32 portid, u32 seq,
struct netlink_callback *cb,
int flags)
{
void *hdr;
struct nfc_se *se, *n;

list_for_each_entry_safe(se, n, &dev->secure_elements, list) {
hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
NFC_CMD_GET_SE);
if (!hdr)
goto nla_put_failure;

if (cb)
genl_dump_check_consistent(cb, hdr, &nfc_genl_family);

if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
nla_put_u32(msg, NFC_ATTR_SE_INDEX, se->idx) ||
nla_put_u8(msg, NFC_ATTR_SE_TYPE, se->type))
goto nla_put_failure;

if (genlmsg_end(msg, hdr) < 0)
goto nla_put_failure;
}

return 0;

nla_put_failure:
genlmsg_cancel(msg, hdr);
return -EMSGSIZE;
}

static int nfc_genl_dump_ses(struct sk_buff *skb,
struct netlink_callback *cb)
{
struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];
struct nfc_dev *dev = (struct nfc_dev *) cb->args[1];
bool first_call = false;

if (!iter) {
first_call = true;
iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL);
if (!iter)
return -ENOMEM;
cb->args[0] = (long) iter;
}

mutex_lock(&nfc_devlist_mutex);

cb->seq = nfc_devlist_generation;

if (first_call) {
nfc_device_iter_init(iter);
dev = nfc_device_iter_next(iter);
}

while (dev) {
int rc;

rc = nfc_genl_send_se(skb, dev, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
if (rc < 0)
break;

dev = nfc_device_iter_next(iter);
}

mutex_unlock(&nfc_devlist_mutex);

cb->args[1] = (long) dev;

return skb->len;
}

static int nfc_genl_dump_ses_done(struct netlink_callback *cb)
{
struct class_dev_iter *iter = (struct class_dev_iter *) cb->args[0];

nfc_device_iter_exit(iter);
kfree(iter);

return 0;
}

static struct genl_ops nfc_genl_ops[] = {
{
.cmd = NFC_CMD_GET_DEVICE,
Expand Down Expand Up @@ -1265,6 +1350,12 @@ static struct genl_ops nfc_genl_ops[] = {
.doit = nfc_genl_disable_se,
.policy = nfc_genl_policy,
},
{
.cmd = NFC_CMD_GET_SE,
.dumpit = nfc_genl_dump_ses,
.done = nfc_genl_dump_ses_done,
.policy = nfc_genl_policy,
},
};


Expand Down

0 comments on commit ac22ac4

Please sign in to comment.