Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc40a8c1 authored by Samuel Ortiz's avatar Samuel Ortiz
Browse files

NFC: Add target mode activation netlink event



Userspace gets a netlink event upon target mode activation.
The LLCP layer is also signaled when we get an ATR_REQ in order to get
the remote general bytes.

Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent ad3823ce
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -260,6 +260,10 @@ struct pn533_cmd_jump_dep_response {
#define PN533_INIT_TARGET_PASSIVE 0x1
#define PN533_INIT_TARGET_DEP 0x2

#define PN533_INIT_TARGET_RESP_FRAME_MASK 0x3
#define PN533_INIT_TARGET_RESP_ACTIVE     0x1
#define PN533_INIT_TARGET_RESP_DEP        0x4

struct pn533_cmd_init_target {
	u8 mode;
	u8 mifare[6];
@@ -1128,10 +1132,13 @@ static int pn533_init_target_frame(struct pn533_frame *frame,
	return 0;
}

#define ATR_REQ_GB_OFFSET 17
static int pn533_init_target_complete(struct pn533 *dev, void *arg,
				      u8 *params, int params_len)
{
	struct pn533_cmd_init_target_response *resp;
	u8 frame, comm_mode = NFC_COMM_PASSIVE, *gb;
	size_t gb_len;

	nfc_dev_dbg(&dev->interface->dev, "%s", __func__);

@@ -1143,11 +1150,27 @@ static int pn533_init_target_complete(struct pn533 *dev, void *arg,
		return params_len;
	}

	if (params_len < ATR_REQ_GB_OFFSET + 1)
		return -EINVAL;

	resp = (struct pn533_cmd_init_target_response *) params;

	nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x\n", resp->mode);
	nfc_dev_dbg(&dev->interface->dev, "Target mode 0x%x param len %d\n",
		    resp->mode, params_len);

	return 0;
	frame = resp->mode & PN533_INIT_TARGET_RESP_FRAME_MASK;
	if (frame == PN533_INIT_TARGET_RESP_ACTIVE)
		comm_mode = NFC_COMM_ACTIVE;

	/* Again, only DEP */
	if ((resp->mode & PN533_INIT_TARGET_RESP_DEP) == 0)
		return -EOPNOTSUPP;

	gb = resp->cmd + ATR_REQ_GB_OFFSET;
	gb_len = params_len - (ATR_REQ_GB_OFFSET + 1);

	return nfc_tm_activated(dev->nfc_dev, NFC_PROTO_NFC_DEP_MASK,
				comm_mode, gb, gb_len);
}

static int pn533_init_target(struct nfc_dev *nfc_dev, u32 protocols)
+7 −0
Original line number Diff line number Diff line
@@ -56,6 +56,10 @@
 *	%NFC_ATTR_PROTOCOLS)
 * @NFC_EVENT_DEVICE_REMOVED: event emitted when a device is removed
 *	(it sends %NFC_ATTR_DEVICE_INDEX)
 * @NFC_EVENT_TM_ACTIVATED: event emitted when the adapter is activated in
 *      target mode.
 * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated
 *      from target mode.
 */
enum nfc_commands {
	NFC_CMD_UNSPEC,
@@ -71,6 +75,8 @@ enum nfc_commands {
	NFC_EVENT_DEVICE_ADDED,
	NFC_EVENT_DEVICE_REMOVED,
	NFC_EVENT_TARGET_LOST,
	NFC_EVENT_TM_ACTIVATED,
	NFC_EVENT_TM_DEACTIVATED,
/* private: internal use only */
	__NFC_CMD_AFTER_LAST
};
@@ -122,6 +128,7 @@ enum nfc_attrs {
#define NFC_NFCID1_MAXSIZE 10
#define NFC_SENSB_RES_MAXSIZE 12
#define NFC_SENSF_RES_MAXSIZE 18
#define NFC_GB_MAXSIZE        48

/* NFC protocols */
#define NFC_PROTO_JEWEL		1
+4 −0
Original line number Diff line number Diff line
@@ -198,4 +198,8 @@ int nfc_target_lost(struct nfc_dev *dev, u32 target_idx);
int nfc_dep_link_is_up(struct nfc_dev *dev, u32 target_idx,
		       u8 comm_mode, u8 rf_mode);

int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
		     u8 *gb, size_t gb_len);
int nfc_tm_deactivated(struct nfc_dev *dev);

#endif /* __NET_NFC_H */
+35 −0
Original line number Diff line number Diff line
@@ -455,6 +455,41 @@ u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len)
}
EXPORT_SYMBOL(nfc_get_local_general_bytes);

int nfc_tm_activated(struct nfc_dev *dev, u32 protocol, u8 comm_mode,
		     u8 *gb, size_t gb_len)
{
	int rc;

	device_lock(&dev->dev);

	dev->polling = false;

	if (gb != NULL) {
		rc = nfc_set_remote_general_bytes(dev, gb, gb_len);
		if (rc < 0)
			goto out;
	}

	if (protocol == NFC_PROTO_NFC_DEP_MASK)
		nfc_dep_link_is_up(dev, 0, comm_mode, NFC_RF_TARGET);

	rc = nfc_genl_tm_activated(dev, protocol);

out:
	device_unlock(&dev->dev);

	return rc;
}
EXPORT_SYMBOL(nfc_tm_activated);

int nfc_tm_deactivated(struct nfc_dev *dev)
{
	dev->dep_link_up = false;

	return nfc_genl_tm_deactivated(dev);
}
EXPORT_SYMBOL(nfc_tm_deactivated);

/**
 * nfc_alloc_send_skb - allocate a skb for data exchange responses
 *
+62 −0
Original line number Diff line number Diff line
@@ -221,6 +221,68 @@ free_msg:
	return -EMSGSIZE;
}

int nfc_genl_tm_activated(struct nfc_dev *dev, u32 protocol)
{
	struct sk_buff *msg;
	void *hdr;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
			  NFC_EVENT_TM_ACTIVATED);
	if (!hdr)
		goto free_msg;

	if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
		goto nla_put_failure;
	if (nla_put_u32(msg, NFC_ATTR_TM_PROTOCOLS, protocol))
		goto nla_put_failure;

	genlmsg_end(msg, hdr);

	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);

	return 0;

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

int nfc_genl_tm_deactivated(struct nfc_dev *dev)
{
	struct sk_buff *msg;
	void *hdr;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, 0, 0, &nfc_genl_family, 0,
			  NFC_EVENT_TM_DEACTIVATED);
	if (!hdr)
		goto free_msg;

	if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx))
		goto nla_put_failure;

	genlmsg_end(msg, hdr);

	genlmsg_multicast(msg, 0, nfc_genl_event_mcgrp.id, GFP_KERNEL);

	return 0;

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

int nfc_genl_device_added(struct nfc_dev *dev)
{
	struct sk_buff *msg;
Loading