diff options
| author | Ilan Elias <ilane@ti.com> | 2012-01-17 04:06:43 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2012-01-24 14:21:15 -0500 |
| commit | d5a2ca60e41fec4ede7b82d3608278523cffe77b (patch) | |
| tree | 64faf8e66edaf03fe35b9bd61e8263817a17cca9 | |
| parent | bfeb4dbc5cb36ae774fabe7b0e0d559e621a2ccd (diff) | |
NFC: Export new attributes sensb_res and sensf_res
Export new attributes sensb_res for tech B and sensf_res
for tech F in the target info (returned as a response to
NFC_CMD_GET_TARGET).
The max size of the attributes nfcid1, sensb_res and sensf_res
is exported to user space though include/linux/nfc.
Signed-off-by: Ilan Elias <ilane@ti.com>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | include/linux/nfc.h | 7 | ||||
| -rw-r--r-- | include/net/nfc/nci.h | 19 | ||||
| -rw-r--r-- | include/net/nfc/nfc.h | 8 | ||||
| -rw-r--r-- | net/nfc/nci/ntf.c | 111 | ||||
| -rw-r--r-- | net/nfc/netlink.c | 6 |
5 files changed, 136 insertions, 15 deletions
diff --git a/include/linux/nfc.h b/include/linux/nfc.h index 01d4e5d60325..b4999abcb2a2 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h | |||
| @@ -89,6 +89,8 @@ enum nfc_commands { | |||
| 89 | * @NFC_ATTR_TARGET_SEL_RES: NFC-A targets extra information (useful if the | 89 | * @NFC_ATTR_TARGET_SEL_RES: NFC-A targets extra information (useful if the |
| 90 | * target is not NFC-Forum compliant) | 90 | * target is not NFC-Forum compliant) |
| 91 | * @NFC_ATTR_TARGET_NFCID1: NFC-A targets identifier, max 10 bytes | 91 | * @NFC_ATTR_TARGET_NFCID1: NFC-A targets identifier, max 10 bytes |
| 92 | * @NFC_ATTR_TARGET_SENSB_RES: NFC-B targets extra information, max 12 bytes | ||
| 93 | * @NFC_ATTR_TARGET_SENSF_RES: NFC-F targets extra information, max 18 bytes | ||
| 92 | * @NFC_ATTR_COMM_MODE: Passive or active mode | 94 | * @NFC_ATTR_COMM_MODE: Passive or active mode |
| 93 | * @NFC_ATTR_RF_MODE: Initiator or target | 95 | * @NFC_ATTR_RF_MODE: Initiator or target |
| 94 | */ | 96 | */ |
| @@ -101,6 +103,8 @@ enum nfc_attrs { | |||
| 101 | NFC_ATTR_TARGET_SENS_RES, | 103 | NFC_ATTR_TARGET_SENS_RES, |
| 102 | NFC_ATTR_TARGET_SEL_RES, | 104 | NFC_ATTR_TARGET_SEL_RES, |
| 103 | NFC_ATTR_TARGET_NFCID1, | 105 | NFC_ATTR_TARGET_NFCID1, |
| 106 | NFC_ATTR_TARGET_SENSB_RES, | ||
| 107 | NFC_ATTR_TARGET_SENSF_RES, | ||
| 104 | NFC_ATTR_COMM_MODE, | 108 | NFC_ATTR_COMM_MODE, |
| 105 | NFC_ATTR_RF_MODE, | 109 | NFC_ATTR_RF_MODE, |
| 106 | /* private: internal use only */ | 110 | /* private: internal use only */ |
| @@ -109,6 +113,9 @@ enum nfc_attrs { | |||
| 109 | #define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1) | 113 | #define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1) |
| 110 | 114 | ||
| 111 | #define NFC_DEVICE_NAME_MAXSIZE 8 | 115 | #define NFC_DEVICE_NAME_MAXSIZE 8 |
| 116 | #define NFC_NFCID1_MAXSIZE 10 | ||
| 117 | #define NFC_SENSB_RES_MAXSIZE 12 | ||
| 118 | #define NFC_SENSF_RES_MAXSIZE 18 | ||
| 112 | 119 | ||
| 113 | /* NFC protocols */ | 120 | /* NFC protocols */ |
| 114 | #define NFC_PROTO_JEWEL 1 | 121 | #define NFC_PROTO_JEWEL 1 |
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h index 2be95e2626c0..34f5ed29c3c1 100644 --- a/include/net/nfc/nci.h +++ b/include/net/nfc/nci.h | |||
| @@ -275,11 +275,27 @@ struct rf_tech_specific_params_nfca_poll { | |||
| 275 | __u8 sel_res; | 275 | __u8 sel_res; |
| 276 | } __packed; | 276 | } __packed; |
| 277 | 277 | ||
| 278 | struct rf_tech_specific_params_nfcb_poll { | ||
| 279 | __u8 sensb_res_len; | ||
| 280 | __u8 sensb_res[12]; /* 11 or 12 Bytes */ | ||
| 281 | } __packed; | ||
| 282 | |||
| 283 | struct rf_tech_specific_params_nfcf_poll { | ||
| 284 | __u8 bit_rate; | ||
| 285 | __u8 sensf_res_len; | ||
| 286 | __u8 sensf_res[18]; /* 16 or 18 Bytes */ | ||
| 287 | } __packed; | ||
| 288 | |||
| 278 | struct activation_params_nfca_poll_iso_dep { | 289 | struct activation_params_nfca_poll_iso_dep { |
| 279 | __u8 rats_res_len; | 290 | __u8 rats_res_len; |
| 280 | __u8 rats_res[20]; | 291 | __u8 rats_res[20]; |
| 281 | }; | 292 | }; |
| 282 | 293 | ||
| 294 | struct activation_params_nfcb_poll_iso_dep { | ||
| 295 | __u8 attrib_res_len; | ||
| 296 | __u8 attrib_res[50]; | ||
| 297 | }; | ||
| 298 | |||
| 283 | struct nci_rf_intf_activated_ntf { | 299 | struct nci_rf_intf_activated_ntf { |
| 284 | __u8 rf_discovery_id; | 300 | __u8 rf_discovery_id; |
| 285 | __u8 rf_interface; | 301 | __u8 rf_interface; |
| @@ -291,6 +307,8 @@ struct nci_rf_intf_activated_ntf { | |||
| 291 | 307 | ||
| 292 | union { | 308 | union { |
| 293 | struct rf_tech_specific_params_nfca_poll nfca_poll; | 309 | struct rf_tech_specific_params_nfca_poll nfca_poll; |
| 310 | struct rf_tech_specific_params_nfcb_poll nfcb_poll; | ||
| 311 | struct rf_tech_specific_params_nfcf_poll nfcf_poll; | ||
| 294 | } rf_tech_specific_params; | 312 | } rf_tech_specific_params; |
| 295 | 313 | ||
| 296 | __u8 data_exch_rf_tech_and_mode; | 314 | __u8 data_exch_rf_tech_and_mode; |
| @@ -300,6 +318,7 @@ struct nci_rf_intf_activated_ntf { | |||
| 300 | 318 | ||
| 301 | union { | 319 | union { |
| 302 | struct activation_params_nfca_poll_iso_dep nfca_poll_iso_dep; | 320 | struct activation_params_nfca_poll_iso_dep nfca_poll_iso_dep; |
| 321 | struct activation_params_nfcb_poll_iso_dep nfcb_poll_iso_dep; | ||
| 303 | } activation_params; | 322 | } activation_params; |
| 304 | 323 | ||
| 305 | } __packed; | 324 | } __packed; |
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 8696b773a695..819530d0e37f 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #ifndef __NET_NFC_H | 24 | #ifndef __NET_NFC_H |
| 25 | #define __NET_NFC_H | 25 | #define __NET_NFC_H |
| 26 | 26 | ||
| 27 | #include <linux/nfc.h> | ||
| 27 | #include <linux/device.h> | 28 | #include <linux/device.h> |
| 28 | #include <linux/skbuff.h> | 29 | #include <linux/skbuff.h> |
| 29 | 30 | ||
| @@ -65,7 +66,6 @@ struct nfc_ops { | |||
| 65 | 66 | ||
| 66 | #define NFC_TARGET_IDX_ANY -1 | 67 | #define NFC_TARGET_IDX_ANY -1 |
| 67 | #define NFC_MAX_GT_LEN 48 | 68 | #define NFC_MAX_GT_LEN 48 |
| 68 | #define NFC_MAX_NFCID1_LEN 10 | ||
| 69 | 69 | ||
| 70 | struct nfc_target { | 70 | struct nfc_target { |
| 71 | u32 idx; | 71 | u32 idx; |
| @@ -73,7 +73,11 @@ struct nfc_target { | |||
| 73 | u16 sens_res; | 73 | u16 sens_res; |
| 74 | u8 sel_res; | 74 | u8 sel_res; |
| 75 | u8 nfcid1_len; | 75 | u8 nfcid1_len; |
| 76 | u8 nfcid1[NFC_MAX_NFCID1_LEN]; | 76 | u8 nfcid1[NFC_NFCID1_MAXSIZE]; |
| 77 | u8 sensb_res_len; | ||
| 78 | u8 sensb_res[NFC_SENSB_RES_MAXSIZE]; | ||
| 79 | u8 sensf_res_len; | ||
| 80 | u8 sensf_res[NFC_SENSF_RES_MAXSIZE]; | ||
| 77 | }; | 81 | }; |
| 78 | 82 | ||
| 79 | struct nfc_genl_data { | 83 | struct nfc_genl_data { |
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 10682bf7029d..a88be91e973f 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
| @@ -115,15 +115,53 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, | |||
| 115 | return data; | 115 | return data; |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, | ||
| 119 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) | ||
| 120 | { | ||
| 121 | struct rf_tech_specific_params_nfcb_poll *nfcb_poll; | ||
| 122 | |||
| 123 | nfcb_poll = &ntf->rf_tech_specific_params.nfcb_poll; | ||
| 124 | |||
| 125 | nfcb_poll->sensb_res_len = *data++; | ||
| 126 | |||
| 127 | pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); | ||
| 128 | |||
| 129 | memcpy(nfcb_poll->sensb_res, data, nfcb_poll->sensb_res_len); | ||
| 130 | data += nfcb_poll->sensb_res_len; | ||
| 131 | |||
| 132 | return data; | ||
| 133 | } | ||
| 134 | |||
| 135 | static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, | ||
| 136 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) | ||
| 137 | { | ||
| 138 | struct rf_tech_specific_params_nfcf_poll *nfcf_poll; | ||
| 139 | |||
| 140 | nfcf_poll = &ntf->rf_tech_specific_params.nfcf_poll; | ||
| 141 | |||
| 142 | nfcf_poll->bit_rate = *data++; | ||
| 143 | nfcf_poll->sensf_res_len = *data++; | ||
| 144 | |||
| 145 | pr_debug("bit_rate %d, sensf_res_len %d\n", | ||
| 146 | nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); | ||
| 147 | |||
| 148 | memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len); | ||
| 149 | data += nfcf_poll->sensf_res_len; | ||
| 150 | |||
| 151 | return data; | ||
| 152 | } | ||
| 153 | |||
| 118 | static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, | 154 | static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, |
| 119 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) | 155 | struct nci_rf_intf_activated_ntf *ntf, __u8 *data) |
| 120 | { | 156 | { |
| 121 | struct activation_params_nfca_poll_iso_dep *nfca_poll; | 157 | struct activation_params_nfca_poll_iso_dep *nfca_poll; |
| 158 | struct activation_params_nfcb_poll_iso_dep *nfcb_poll; | ||
| 122 | 159 | ||
| 123 | switch (ntf->activation_rf_tech_and_mode) { | 160 | switch (ntf->activation_rf_tech_and_mode) { |
| 124 | case NCI_NFC_A_PASSIVE_POLL_MODE: | 161 | case NCI_NFC_A_PASSIVE_POLL_MODE: |
| 125 | nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; | 162 | nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; |
| 126 | nfca_poll->rats_res_len = *data++; | 163 | nfca_poll->rats_res_len = *data++; |
| 164 | pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); | ||
| 127 | if (nfca_poll->rats_res_len > 0) { | 165 | if (nfca_poll->rats_res_len > 0) { |
| 128 | memcpy(nfca_poll->rats_res, | 166 | memcpy(nfca_poll->rats_res, |
| 129 | data, | 167 | data, |
| @@ -131,6 +169,18 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, | |||
| 131 | } | 169 | } |
| 132 | break; | 170 | break; |
| 133 | 171 | ||
| 172 | case NCI_NFC_B_PASSIVE_POLL_MODE: | ||
| 173 | nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; | ||
| 174 | nfcb_poll->attrib_res_len = *data++; | ||
| 175 | pr_debug("attrib_res_len %d\n", | ||
| 176 | nfcb_poll->attrib_res_len); | ||
| 177 | if (nfcb_poll->attrib_res_len > 0) { | ||
| 178 | memcpy(nfcb_poll->attrib_res, | ||
| 179 | data, | ||
| 180 | nfcb_poll->attrib_res_len); | ||
| 181 | } | ||
| 182 | break; | ||
| 183 | |||
| 134 | default: | 184 | default: |
| 135 | pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", | 185 | pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", |
| 136 | ntf->activation_rf_tech_and_mode); | 186 | ntf->activation_rf_tech_and_mode); |
| @@ -145,21 +195,14 @@ static void nci_target_found(struct nci_dev *ndev, | |||
| 145 | { | 195 | { |
| 146 | struct nfc_target nfc_tgt; | 196 | struct nfc_target nfc_tgt; |
| 147 | 197 | ||
| 148 | if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T) /* T2T MifareUL */ | 198 | memset(&nfc_tgt, 0, sizeof(nfc_tgt)); |
| 199 | |||
| 200 | if (ntf->rf_protocol == NCI_RF_PROTOCOL_T2T) | ||
| 149 | nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; | 201 | nfc_tgt.supported_protocols = NFC_PROTO_MIFARE_MASK; |
| 150 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) /* 4A */ | 202 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_ISO_DEP) |
| 151 | nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; | 203 | nfc_tgt.supported_protocols = NFC_PROTO_ISO14443_MASK; |
| 152 | else | 204 | else if (ntf->rf_protocol == NCI_RF_PROTOCOL_T3T) |
| 153 | nfc_tgt.supported_protocols = 0; | 205 | nfc_tgt.supported_protocols = NFC_PROTO_FELICA_MASK; |
| 154 | |||
| 155 | nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res; | ||
| 156 | nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res; | ||
| 157 | nfc_tgt.nfcid1_len = ntf->rf_tech_specific_params.nfca_poll.nfcid1_len; | ||
| 158 | if (nfc_tgt.nfcid1_len > 0) { | ||
| 159 | memcpy(nfc_tgt.nfcid1, | ||
| 160 | ntf->rf_tech_specific_params.nfca_poll.nfcid1, | ||
| 161 | nfc_tgt.nfcid1_len); | ||
| 162 | } | ||
| 163 | 206 | ||
| 164 | if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) { | 207 | if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) { |
| 165 | pr_debug("the target found does not have the desired protocol\n"); | 208 | pr_debug("the target found does not have the desired protocol\n"); |
| @@ -169,6 +212,38 @@ static void nci_target_found(struct nci_dev *ndev, | |||
| 169 | pr_debug("new target found, supported_protocols 0x%x\n", | 212 | pr_debug("new target found, supported_protocols 0x%x\n", |
| 170 | nfc_tgt.supported_protocols); | 213 | nfc_tgt.supported_protocols); |
| 171 | 214 | ||
| 215 | if (ntf->activation_rf_tech_and_mode == NCI_NFC_A_PASSIVE_POLL_MODE) { | ||
| 216 | nfc_tgt.sens_res = | ||
| 217 | ntf->rf_tech_specific_params.nfca_poll.sens_res; | ||
| 218 | nfc_tgt.sel_res = | ||
| 219 | ntf->rf_tech_specific_params.nfca_poll.sel_res; | ||
| 220 | nfc_tgt.nfcid1_len = | ||
| 221 | ntf->rf_tech_specific_params.nfca_poll.nfcid1_len; | ||
| 222 | if (nfc_tgt.nfcid1_len > 0) { | ||
| 223 | memcpy(nfc_tgt.nfcid1, | ||
| 224 | ntf->rf_tech_specific_params.nfca_poll.nfcid1, | ||
| 225 | nfc_tgt.nfcid1_len); | ||
| 226 | } | ||
| 227 | } else if (ntf->activation_rf_tech_and_mode == | ||
| 228 | NCI_NFC_B_PASSIVE_POLL_MODE) { | ||
| 229 | nfc_tgt.sensb_res_len = | ||
| 230 | ntf->rf_tech_specific_params.nfcb_poll.sensb_res_len; | ||
| 231 | if (nfc_tgt.sensb_res_len > 0) { | ||
| 232 | memcpy(nfc_tgt.sensb_res, | ||
| 233 | ntf->rf_tech_specific_params.nfcb_poll.sensb_res, | ||
| 234 | nfc_tgt.sensb_res_len); | ||
| 235 | } | ||
| 236 | } else if (ntf->activation_rf_tech_and_mode == | ||
| 237 | NCI_NFC_F_PASSIVE_POLL_MODE) { | ||
| 238 | nfc_tgt.sensf_res_len = | ||
| 239 | ntf->rf_tech_specific_params.nfcf_poll.sensf_res_len; | ||
| 240 | if (nfc_tgt.sensf_res_len > 0) { | ||
| 241 | memcpy(nfc_tgt.sensf_res, | ||
| 242 | ntf->rf_tech_specific_params.nfcf_poll.sensf_res, | ||
| 243 | nfc_tgt.sensf_res_len); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 172 | ndev->target_available_prots = nfc_tgt.supported_protocols; | 247 | ndev->target_available_prots = nfc_tgt.supported_protocols; |
| 173 | ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size; | 248 | ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size; |
| 174 | ndev->initial_num_credits = ntf->initial_num_credits; | 249 | ndev->initial_num_credits = ntf->initial_num_credits; |
| @@ -215,6 +290,16 @@ static void nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, | |||
| 215 | &ntf, data); | 290 | &ntf, data); |
| 216 | break; | 291 | break; |
| 217 | 292 | ||
| 293 | case NCI_NFC_B_PASSIVE_POLL_MODE: | ||
| 294 | data = nci_extract_rf_params_nfcb_passive_poll(ndev, | ||
| 295 | &ntf, data); | ||
| 296 | break; | ||
| 297 | |||
| 298 | case NCI_NFC_F_PASSIVE_POLL_MODE: | ||
| 299 | data = nci_extract_rf_params_nfcf_passive_poll(ndev, | ||
| 300 | &ntf, data); | ||
| 301 | break; | ||
| 302 | |||
| 218 | default: | 303 | default: |
| 219 | pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", | 304 | pr_err("unsupported activation_rf_tech_and_mode 0x%x\n", |
| 220 | ntf.activation_rf_tech_and_mode); | 305 | ntf.activation_rf_tech_and_mode); |
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index 6989dfa28ee2..07f0348aabf5 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c | |||
| @@ -70,6 +70,12 @@ static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target, | |||
| 70 | if (target->nfcid1_len > 0) | 70 | if (target->nfcid1_len > 0) |
| 71 | NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, | 71 | NLA_PUT(msg, NFC_ATTR_TARGET_NFCID1, target->nfcid1_len, |
| 72 | target->nfcid1); | 72 | target->nfcid1); |
| 73 | if (target->sensb_res_len > 0) | ||
| 74 | NLA_PUT(msg, NFC_ATTR_TARGET_SENSB_RES, target->sensb_res_len, | ||
| 75 | target->sensb_res); | ||
| 76 | if (target->sensf_res_len > 0) | ||
| 77 | NLA_PUT(msg, NFC_ATTR_TARGET_SENSF_RES, target->sensf_res_len, | ||
| 78 | target->sensf_res); | ||
| 73 | 79 | ||
| 74 | return genlmsg_end(msg, hdr); | 80 | return genlmsg_end(msg, hdr); |
| 75 | 81 | ||
