Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 340965
b: refs/heads/master
c: 52feb44
h: refs/heads/master
i:
  340963: 7329164
v: v3
  • Loading branch information
Thierry Escande authored and Samuel Ortiz committed Oct 28, 2012
1 parent 022ff3d commit 61ca9c2
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f31652a58bee6ef145c066c8d0ae6d0b11dca1e8
refs/heads/master: 52feb444a90304eb13c03115bb9758101dbb9254
15 changes: 15 additions & 0 deletions trunk/include/uapi/linux/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@
* target mode.
* @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated
* from target mode.
* @NFC_CMD_LLC_GET_PARAMS: request LTO, RW, and MIUX parameters for a device
* @NFC_CMD_LLC_SET_PARAMS: set one or more of LTO, RW, and MIUX parameters for
* a device. LTO must be set before the link is up otherwise -EINPROGRESS
* is returned. RW and MIUX can be set at anytime and will be passed in
* subsequent CONNECT and CC messages.
* If one of the passed parameters is wrong none is set and -EINVAL is
* returned.
*/
enum nfc_commands {
NFC_CMD_UNSPEC,
Expand All @@ -77,6 +84,8 @@ enum nfc_commands {
NFC_EVENT_TARGET_LOST,
NFC_EVENT_TM_ACTIVATED,
NFC_EVENT_TM_DEACTIVATED,
NFC_CMD_LLC_GET_PARAMS,
NFC_CMD_LLC_SET_PARAMS,
/* private: internal use only */
__NFC_CMD_AFTER_LAST
};
Expand All @@ -102,6 +111,9 @@ enum nfc_commands {
* @NFC_ATTR_RF_MODE: Initiator or target
* @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for
* @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for
* @NFC_ATTR_LLC_PARAM_LTO: Link TimeOut parameter
* @NFC_ATTR_LLC_PARAM_RW: Receive Window size parameter
* @NFC_ATTR_LLC_PARAM_MIUX: MIU eXtension parameter
*/
enum nfc_attrs {
NFC_ATTR_UNSPEC,
Expand All @@ -119,6 +131,9 @@ enum nfc_attrs {
NFC_ATTR_DEVICE_POWERED,
NFC_ATTR_IM_PROTOCOLS,
NFC_ATTR_TM_PROTOCOLS,
NFC_ATTR_LLC_PARAM_LTO,
NFC_ATTR_LLC_PARAM_RW,
NFC_ATTR_LLC_PARAM_MIUX,
/* private: internal use only */
__NFC_ATTR_AFTER_LAST
};
Expand Down
18 changes: 6 additions & 12 deletions trunk/net/nfc/llcp/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,7 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
struct sk_buff *skb;
u8 *service_name_tlv = NULL, service_name_tlv_length;
u8 *miux_tlv = NULL, miux_tlv_length;
u8 *rw_tlv = NULL, rw_tlv_length, rw;
__be16 miux;
u8 *rw_tlv = NULL, rw_tlv_length;
int err;
u16 size = 0;

Expand All @@ -335,13 +334,11 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock)
size += service_name_tlv_length;
}

miux = cpu_to_be16(LLCP_MAX_MIUX);
miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0,
&miux_tlv_length);
size += miux_tlv_length;

rw = LLCP_MAX_RW;
rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length);
size += rw_tlv_length;

pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len);
Expand Down Expand Up @@ -378,8 +375,7 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
struct nfc_llcp_local *local;
struct sk_buff *skb;
u8 *miux_tlv = NULL, miux_tlv_length;
u8 *rw_tlv = NULL, rw_tlv_length, rw;
__be16 miux;
u8 *rw_tlv = NULL, rw_tlv_length;
int err;
u16 size = 0;

Expand All @@ -389,13 +385,11 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock)
if (local == NULL)
return -ENODEV;

miux = cpu_to_be16(LLCP_MAX_MIUX);
miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0,
&miux_tlv_length);
size += miux_tlv_length;

rw = LLCP_MAX_RW;
rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length);
rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &local->rw, 0, &rw_tlv_length);
size += rw_tlv_length;

skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size);
Expand Down
14 changes: 7 additions & 7 deletions trunk/net/nfc/llcp/llcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,9 @@ static u8 nfc_llcp_reserve_sdp_ssap(struct nfc_llcp_local *local)
static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
{
u8 *gb_cur, *version_tlv, version, version_length;
u8 *lto_tlv, lto, lto_length;
u8 *lto_tlv, lto_length;
u8 *wks_tlv, wks_length;
u8 *miux_tlv, miux_length;
__be16 miux;
u8 gb_len = 0;
int ret = 0;

Expand All @@ -479,18 +478,15 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local)
1, &version_length);
gb_len += version_length;

/* 1500 ms */
lto = 150;
lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &lto, 1, &lto_length);
lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, &lto_length);
gb_len += lto_length;

pr_debug("Local wks 0x%lx\n", local->local_wks);
wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&local->local_wks, 2,
&wks_length);
gb_len += wks_length;

miux = cpu_to_be16(LLCP_MAX_MIUX);
miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0,
miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0,
&miux_length);
gb_len += miux_length;

Expand Down Expand Up @@ -1383,6 +1379,10 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
rwlock_init(&local->connecting_sockets.lock);
rwlock_init(&local->raw_sockets.lock);

local->lto = 150; /* 1500 ms */
local->rw = LLCP_MAX_RW;
local->miux = cpu_to_be16(LLCP_MAX_MIUX);

nfc_llcp_build_gb(local);

local->remote_miu = LLCP_DEFAULT_MIU;
Expand Down
3 changes: 3 additions & 0 deletions trunk/net/nfc/llcp/llcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ struct nfc_llcp_local {
u32 target_idx;
u8 rf_mode;
u8 comm_mode;
u8 lto;
u8 rw;
__be16 miux;
unsigned long local_wks; /* Well known services */
unsigned long local_sdp; /* Local services */
unsigned long local_sap; /* Local SAPs, not available for discovery */
Expand Down
152 changes: 152 additions & 0 deletions trunk/net/nfc/netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

#include "nfc.h"

#include "llcp/llcp.h"

static struct genl_multicast_group nfc_genl_event_mcgrp = {
.name = NFC_GENL_MCAST_EVENT_NAME,
};
Expand Down Expand Up @@ -716,6 +718,146 @@ static int nfc_genl_dep_link_down(struct sk_buff *skb, struct genl_info *info)
return rc;
}

static int nfc_genl_send_params(struct sk_buff *msg,
struct nfc_llcp_local *local,
u32 portid, u32 seq)
{
void *hdr;

hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, 0,
NFC_CMD_LLC_GET_PARAMS);
if (!hdr)
return -EMSGSIZE;

if (nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, local->dev->idx) ||
nla_put_u8(msg, NFC_ATTR_LLC_PARAM_LTO, local->lto) ||
nla_put_u8(msg, NFC_ATTR_LLC_PARAM_RW, local->rw) ||
nla_put_u16(msg, NFC_ATTR_LLC_PARAM_MIUX, be16_to_cpu(local->miux)))
goto nla_put_failure;

return genlmsg_end(msg, hdr);

nla_put_failure:

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

static int nfc_genl_llc_get_params(struct sk_buff *skb, struct genl_info *info)
{
struct nfc_dev *dev;
struct nfc_llcp_local *local;
int rc = 0;
struct sk_buff *msg = NULL;
u32 idx;

if (!info->attrs[NFC_ATTR_DEVICE_INDEX])
return -EINVAL;

idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);

dev = nfc_get_device(idx);
if (!dev)
return -ENODEV;

device_lock(&dev->dev);

local = nfc_llcp_find_local(dev);
if (!local) {
rc = -ENODEV;
goto exit;
}

msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) {
rc = -ENOMEM;
goto exit;
}

rc = nfc_genl_send_params(msg, local, info->snd_portid, info->snd_seq);

exit:
device_unlock(&dev->dev);

nfc_put_device(dev);

if (rc < 0) {
if (msg)
nlmsg_free(msg);

return rc;
}

return genlmsg_reply(msg, info);
}

static int nfc_genl_llc_set_params(struct sk_buff *skb, struct genl_info *info)
{
struct nfc_dev *dev;
struct nfc_llcp_local *local;
u8 rw = 0;
u16 miux = 0;
u32 idx;
int rc = 0;

if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
(!info->attrs[NFC_ATTR_LLC_PARAM_LTO] &&
!info->attrs[NFC_ATTR_LLC_PARAM_RW] &&
!info->attrs[NFC_ATTR_LLC_PARAM_MIUX]))
return -EINVAL;

if (info->attrs[NFC_ATTR_LLC_PARAM_RW]) {
rw = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_RW]);

if (rw > LLCP_MAX_RW)
return -EINVAL;
}

if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX]) {
miux = nla_get_u16(info->attrs[NFC_ATTR_LLC_PARAM_MIUX]);

if (miux > LLCP_MAX_MIUX)
return -EINVAL;
}

idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);

dev = nfc_get_device(idx);
if (!dev)
return -ENODEV;

device_lock(&dev->dev);

local = nfc_llcp_find_local(dev);
if (!local) {
nfc_put_device(dev);
rc = -ENODEV;
goto exit;
}

if (info->attrs[NFC_ATTR_LLC_PARAM_LTO]) {
if (dev->dep_link_up) {
rc = -EINPROGRESS;
goto exit;
}

local->lto = nla_get_u8(info->attrs[NFC_ATTR_LLC_PARAM_LTO]);
}

if (info->attrs[NFC_ATTR_LLC_PARAM_RW])
local->rw = rw;

if (info->attrs[NFC_ATTR_LLC_PARAM_MIUX])
local->miux = cpu_to_be16(miux);

exit:
device_unlock(&dev->dev);

nfc_put_device(dev);

return rc;
}

static struct genl_ops nfc_genl_ops[] = {
{
.cmd = NFC_CMD_GET_DEVICE,
Expand Down Expand Up @@ -760,6 +902,16 @@ static struct genl_ops nfc_genl_ops[] = {
.done = nfc_genl_dump_targets_done,
.policy = nfc_genl_policy,
},
{
.cmd = NFC_CMD_LLC_GET_PARAMS,
.doit = nfc_genl_llc_get_params,
.policy = nfc_genl_policy,
},
{
.cmd = NFC_CMD_LLC_SET_PARAMS,
.doit = nfc_genl_llc_set_params,
.policy = nfc_genl_policy,
},
};


Expand Down
6 changes: 6 additions & 0 deletions trunk/net/nfc/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev);
int nfc_llcp_set_remote_gb(struct nfc_dev *dev, u8 *gb, u8 gb_len);
u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
int __init nfc_llcp_init(void);
void nfc_llcp_exit(void);

Expand Down Expand Up @@ -97,6 +98,11 @@ static inline int nfc_llcp_data_received(struct nfc_dev *dev,
return 0;
}

static inline struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev)
{
return NULL;
}

static inline int nfc_llcp_init(void)
{
return 0;
Expand Down

0 comments on commit 61ca9c2

Please sign in to comment.