diff options
author | Christophe Ricard <christophe.ricard@gmail.com> | 2016-04-30 03:12:51 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2016-05-03 19:43:21 -0400 |
commit | 9b8d1a4cf2aa819d606b4e423a6523fc0d4460a2 (patch) | |
tree | 5862df9d18bb3e54f90b6fb81a23ac68ea0107a8 | |
parent | de5ea8517c2ae40785fe5d0a2d02fc71bef1761b (diff) |
nfc: nci: Add an additional parameter to identify a connection id
According to NCI specification, destination type and destination
specific parameters shall uniquely identify a single destination
for the Logical Connection.
Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/nfc/fdp/fdp.c | 3 | ||||
-rw-r--r-- | drivers/nfc/st-nci/se.c | 6 | ||||
-rw-r--r-- | include/net/nfc/nci_core.h | 15 | ||||
-rw-r--r-- | net/nfc/nci/core.c | 25 | ||||
-rw-r--r-- | net/nfc/nci/ntf.c | 2 | ||||
-rw-r--r-- | net/nfc/nci/rsp.c | 20 |
6 files changed, 54 insertions, 17 deletions
diff --git a/drivers/nfc/fdp/fdp.c b/drivers/nfc/fdp/fdp.c index ccb07a1b153d..e44a7a2f4061 100644 --- a/drivers/nfc/fdp/fdp.c +++ b/drivers/nfc/fdp/fdp.c | |||
@@ -102,7 +102,8 @@ static int fdp_nci_create_conn(struct nci_dev *ndev) | |||
102 | if (r) | 102 | if (r) |
103 | return r; | 103 | return r; |
104 | 104 | ||
105 | return nci_get_conn_info_by_id(ndev, 0); | 105 | return nci_get_conn_info_by_dest_type_params(ndev, |
106 | FDP_PATCH_CONN_DEST, NULL); | ||
106 | } | 107 | } |
107 | 108 | ||
108 | static inline int fdp_nci_get_versions(struct nci_dev *ndev) | 109 | static inline int fdp_nci_get_versions(struct nci_dev *ndev) |
diff --git a/drivers/nfc/st-nci/se.c b/drivers/nfc/st-nci/se.c index e7f25f4e3dc3..420f019cc42f 100644 --- a/drivers/nfc/st-nci/se.c +++ b/drivers/nfc/st-nci/se.c | |||
@@ -600,10 +600,12 @@ static int st_nci_hci_network_init(struct nci_dev *ndev) | |||
600 | * HCI will be used here only for proprietary commands. | 600 | * HCI will be used here only for proprietary commands. |
601 | */ | 601 | */ |
602 | if (test_bit(ST_NCI_FACTORY_MODE, &info->flags)) | 602 | if (test_bit(ST_NCI_FACTORY_MODE, &info->flags)) |
603 | r = nci_nfcee_mode_set(ndev, ndev->hci_dev->conn_info->id, | 603 | r = nci_nfcee_mode_set(ndev, |
604 | ndev->hci_dev->conn_info->dest_params->id, | ||
604 | NCI_NFCEE_DISABLE); | 605 | NCI_NFCEE_DISABLE); |
605 | else | 606 | else |
606 | r = nci_nfcee_mode_set(ndev, ndev->hci_dev->conn_info->id, | 607 | r = nci_nfcee_mode_set(ndev, |
608 | ndev->hci_dev->conn_info->dest_params->id, | ||
607 | NCI_NFCEE_ENABLE); | 609 | NCI_NFCEE_ENABLE); |
608 | 610 | ||
609 | free_dest_params: | 611 | free_dest_params: |
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index 57ce24fb0047..ebb50d286ef6 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h | |||
@@ -109,7 +109,13 @@ struct nci_ops { | |||
109 | 109 | ||
110 | struct nci_conn_info { | 110 | struct nci_conn_info { |
111 | struct list_head list; | 111 | struct list_head list; |
112 | __u8 id; /* can be an RF Discovery ID or an NFCEE ID */ | 112 | /* NCI specification 4.4.2 Connection Creation |
113 | * The combination of destination type and destination specific | ||
114 | * parameters shall uniquely identify a single destination for the | ||
115 | * Logical Connection | ||
116 | */ | ||
117 | struct dest_spec_params *dest_params; | ||
118 | __u8 dest_type; | ||
113 | __u8 conn_id; | 119 | __u8 conn_id; |
114 | __u8 max_pkt_payload_len; | 120 | __u8 max_pkt_payload_len; |
115 | 121 | ||
@@ -260,7 +266,9 @@ struct nci_dev { | |||
260 | __u32 manufact_specific_info; | 266 | __u32 manufact_specific_info; |
261 | 267 | ||
262 | /* Save RF Discovery ID or NFCEE ID under conn_create */ | 268 | /* Save RF Discovery ID or NFCEE ID under conn_create */ |
263 | __u8 cur_id; | 269 | struct dest_spec_params cur_params; |
270 | /* Save destination type under conn_create */ | ||
271 | __u8 cur_dest_type; | ||
264 | 272 | ||
265 | /* stored during nci_data_exchange */ | 273 | /* stored during nci_data_exchange */ |
266 | struct sk_buff *rx_data_reassembly; | 274 | struct sk_buff *rx_data_reassembly; |
@@ -378,7 +386,8 @@ void nci_clear_target_list(struct nci_dev *ndev); | |||
378 | void nci_req_complete(struct nci_dev *ndev, int result); | 386 | void nci_req_complete(struct nci_dev *ndev, int result); |
379 | struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev, | 387 | struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev, |
380 | int conn_id); | 388 | int conn_id); |
381 | int nci_get_conn_info_by_id(struct nci_dev *ndev, u8 id); | 389 | int nci_get_conn_info_by_dest_type_params(struct nci_dev *ndev, u8 dest_type, |
390 | struct dest_spec_params *params); | ||
382 | 391 | ||
383 | /* ----- NCI status code ----- */ | 392 | /* ----- NCI status code ----- */ |
384 | int nci_to_errno(__u8 code); | 393 | int nci_to_errno(__u8 code); |
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 0884f1444817..74f2d54df4fc 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -64,18 +64,26 @@ struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev, | |||
64 | return NULL; | 64 | return NULL; |
65 | } | 65 | } |
66 | 66 | ||
67 | int nci_get_conn_info_by_id(struct nci_dev *ndev, u8 id) | 67 | int nci_get_conn_info_by_dest_type_params(struct nci_dev *ndev, u8 dest_type, |
68 | struct dest_spec_params *params) | ||
68 | { | 69 | { |
69 | struct nci_conn_info *conn_info; | 70 | struct nci_conn_info *conn_info; |
70 | 71 | ||
71 | list_for_each_entry(conn_info, &ndev->conn_info_list, list) { | 72 | list_for_each_entry(conn_info, &ndev->conn_info_list, list) { |
72 | if (conn_info->id == id) | 73 | if (conn_info->dest_type == dest_type) { |
73 | return conn_info->conn_id; | 74 | if (!params) |
75 | return conn_info->conn_id; | ||
76 | if (conn_info) { | ||
77 | if (params->id == conn_info->dest_params->id && | ||
78 | params->protocol == conn_info->dest_params->protocol) | ||
79 | return conn_info->conn_id; | ||
80 | } | ||
81 | } | ||
74 | } | 82 | } |
75 | 83 | ||
76 | return -EINVAL; | 84 | return -EINVAL; |
77 | } | 85 | } |
78 | EXPORT_SYMBOL(nci_get_conn_info_by_id); | 86 | EXPORT_SYMBOL(nci_get_conn_info_by_dest_type_params); |
79 | 87 | ||
80 | /* ---- NCI requests ---- */ | 88 | /* ---- NCI requests ---- */ |
81 | 89 | ||
@@ -623,12 +631,15 @@ int nci_core_conn_create(struct nci_dev *ndev, u8 destination_type, | |||
623 | if (params) { | 631 | if (params) { |
624 | memcpy(cmd->params, params, params_len); | 632 | memcpy(cmd->params, params, params_len); |
625 | if (params->length > 0) | 633 | if (params->length > 0) |
626 | ndev->cur_id = params->value[DEST_SPEC_PARAMS_ID_INDEX]; | 634 | memcpy(&ndev->cur_params, |
635 | ¶ms->value[DEST_SPEC_PARAMS_ID_INDEX], | ||
636 | sizeof(struct dest_spec_params)); | ||
627 | else | 637 | else |
628 | ndev->cur_id = 0; | 638 | ndev->cur_params.id = 0; |
629 | } else { | 639 | } else { |
630 | ndev->cur_id = 0; | 640 | ndev->cur_params.id = 0; |
631 | } | 641 | } |
642 | ndev->cur_dest_type = destination_type; | ||
632 | 643 | ||
633 | r = __nci_request(ndev, nci_core_conn_create_req, (unsigned long)&data, | 644 | r = __nci_request(ndev, nci_core_conn_create_req, (unsigned long)&data, |
634 | msecs_to_jiffies(NCI_CMD_TIMEOUT)); | 645 | msecs_to_jiffies(NCI_CMD_TIMEOUT)); |
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 2ada2b39e355..1e8c1a12aaec 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
@@ -734,7 +734,7 @@ static void nci_nfcee_discover_ntf_packet(struct nci_dev *ndev, | |||
734 | * “HCI Access”, even if the HCI Network contains multiple NFCEEs. | 734 | * “HCI Access”, even if the HCI Network contains multiple NFCEEs. |
735 | */ | 735 | */ |
736 | ndev->hci_dev->nfcee_id = nfcee_ntf->nfcee_id; | 736 | ndev->hci_dev->nfcee_id = nfcee_ntf->nfcee_id; |
737 | ndev->cur_id = nfcee_ntf->nfcee_id; | 737 | ndev->cur_params.id = nfcee_ntf->nfcee_id; |
738 | 738 | ||
739 | nci_req_complete(ndev, status); | 739 | nci_req_complete(ndev, status); |
740 | } | 740 | } |
diff --git a/net/nfc/nci/rsp.c b/net/nfc/nci/rsp.c index 69fe163b7350..e3bbf1937d0e 100644 --- a/net/nfc/nci/rsp.c +++ b/net/nfc/nci/rsp.c | |||
@@ -226,7 +226,7 @@ static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, | |||
226 | struct sk_buff *skb) | 226 | struct sk_buff *skb) |
227 | { | 227 | { |
228 | __u8 status = skb->data[0]; | 228 | __u8 status = skb->data[0]; |
229 | struct nci_conn_info *conn_info; | 229 | struct nci_conn_info *conn_info = NULL; |
230 | struct nci_core_conn_create_rsp *rsp; | 230 | struct nci_core_conn_create_rsp *rsp; |
231 | 231 | ||
232 | pr_debug("status 0x%x\n", status); | 232 | pr_debug("status 0x%x\n", status); |
@@ -241,7 +241,17 @@ static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, | |||
241 | goto exit; | 241 | goto exit; |
242 | } | 242 | } |
243 | 243 | ||
244 | conn_info->id = ndev->cur_id; | 244 | conn_info->dest_params = devm_kzalloc(&ndev->nfc_dev->dev, |
245 | sizeof(struct dest_spec_params), | ||
246 | GFP_KERNEL); | ||
247 | if (!conn_info->dest_params) { | ||
248 | status = NCI_STATUS_REJECTED; | ||
249 | goto free_conn_info; | ||
250 | } | ||
251 | |||
252 | conn_info->dest_type = ndev->cur_dest_type; | ||
253 | conn_info->dest_params->id = ndev->cur_params.id; | ||
254 | conn_info->dest_params->protocol = ndev->cur_params.protocol; | ||
245 | conn_info->conn_id = rsp->conn_id; | 255 | conn_info->conn_id = rsp->conn_id; |
246 | 256 | ||
247 | /* Note: data_exchange_cb and data_exchange_cb_context need to | 257 | /* Note: data_exchange_cb and data_exchange_cb_context need to |
@@ -251,7 +261,7 @@ static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, | |||
251 | INIT_LIST_HEAD(&conn_info->list); | 261 | INIT_LIST_HEAD(&conn_info->list); |
252 | list_add(&conn_info->list, &ndev->conn_info_list); | 262 | list_add(&conn_info->list, &ndev->conn_info_list); |
253 | 263 | ||
254 | if (ndev->cur_id == ndev->hci_dev->nfcee_id) | 264 | if (ndev->cur_params.id == ndev->hci_dev->nfcee_id) |
255 | ndev->hci_dev->conn_info = conn_info; | 265 | ndev->hci_dev->conn_info = conn_info; |
256 | 266 | ||
257 | conn_info->conn_id = rsp->conn_id; | 267 | conn_info->conn_id = rsp->conn_id; |
@@ -259,7 +269,11 @@ static void nci_core_conn_create_rsp_packet(struct nci_dev *ndev, | |||
259 | atomic_set(&conn_info->credits_cnt, rsp->credits_cnt); | 269 | atomic_set(&conn_info->credits_cnt, rsp->credits_cnt); |
260 | } | 270 | } |
261 | 271 | ||
272 | free_conn_info: | ||
273 | if (status == NCI_STATUS_REJECTED) | ||
274 | devm_kfree(&ndev->nfc_dev->dev, conn_info); | ||
262 | exit: | 275 | exit: |
276 | |||
263 | nci_req_complete(ndev, status); | 277 | nci_req_complete(ndev, status); |
264 | } | 278 | } |
265 | 279 | ||