diff options
author | Christophe Ricard <christophe.ricard@gmail.com> | 2015-01-26 19:18:14 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2015-01-27 18:03:29 -0500 |
commit | 615b524aca0bff52ce6654ddf26546546eb02e93 (patch) | |
tree | 11a9c76a55d8617978208b5ffbbbcb733442563b /net/nfc | |
parent | af77522320aa0e5b4b52dce615ad067d92e15fbf (diff) |
NFC: hci: Reference every pipe information according to notification
We update the tracked pipes status when receiving HCI commands.
Also we forward HCI errors and we reply to any HCI command, even though
we don't support it.
Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/hci/core.c | 58 | ||||
-rw-r--r-- | net/nfc/hci/hci.h | 8 |
2 files changed, 44 insertions, 22 deletions
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index e351e94f8d40..a664a67dff1c 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c | |||
@@ -193,52 +193,66 @@ exit: | |||
193 | void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, | 193 | void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, |
194 | struct sk_buff *skb) | 194 | struct sk_buff *skb) |
195 | { | 195 | { |
196 | int r = 0; | ||
197 | u8 gate = hdev->pipes[pipe].gate; | 196 | u8 gate = hdev->pipes[pipe].gate; |
198 | u8 local_gate, new_pipe; | 197 | u8 status = NFC_HCI_ANY_OK; |
199 | u8 gate_opened = 0x00; | 198 | struct hci_create_pipe_resp *create_info; |
199 | struct hci_delete_pipe_noti *delete_info; | ||
200 | struct hci_all_pipe_cleared_noti *cleared_info; | ||
200 | 201 | ||
201 | pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); | 202 | pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd); |
202 | 203 | ||
203 | switch (cmd) { | 204 | switch (cmd) { |
204 | case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: | 205 | case NFC_HCI_ADM_NOTIFY_PIPE_CREATED: |
205 | if (skb->len != 5) { | 206 | if (skb->len != 5) { |
206 | r = -EPROTO; | 207 | status = NFC_HCI_ANY_E_NOK; |
207 | break; | 208 | goto exit; |
208 | } | 209 | } |
210 | create_info = (struct hci_create_pipe_resp *)skb->data; | ||
209 | 211 | ||
210 | local_gate = skb->data[3]; | 212 | /* Save the new created pipe and bind with local gate, |
211 | new_pipe = skb->data[4]; | ||
212 | nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE, | ||
213 | NFC_HCI_ANY_OK, NULL, 0, NULL, NULL, 0); | ||
214 | |||
215 | /* save the new created pipe and bind with local gate, | ||
216 | * the description for skb->data[3] is destination gate id | 213 | * the description for skb->data[3] is destination gate id |
217 | * but since we received this cmd from host controller, we | 214 | * but since we received this cmd from host controller, we |
218 | * are the destination and it is our local gate | 215 | * are the destination and it is our local gate |
219 | */ | 216 | */ |
220 | hdev->gate2pipe[local_gate] = new_pipe; | 217 | hdev->gate2pipe[create_info->dest_gate] = create_info->pipe; |
218 | hdev->pipes[create_info->pipe].gate = create_info->dest_gate; | ||
219 | hdev->pipes[create_info->pipe].dest_host = | ||
220 | create_info->src_host; | ||
221 | break; | 221 | break; |
222 | case NFC_HCI_ANY_OPEN_PIPE: | 222 | case NFC_HCI_ANY_OPEN_PIPE: |
223 | /* if the pipe is already created, we allow remote host to | 223 | if (gate == NFC_HCI_INVALID_GATE) { |
224 | * open it | 224 | status = NFC_HCI_ANY_E_NOK; |
225 | */ | 225 | goto exit; |
226 | if (gate != 0xff) | 226 | } |
227 | nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE, | 227 | break; |
228 | NFC_HCI_ANY_OK, &gate_opened, 1, | 228 | case NFC_HCI_ADM_NOTIFY_PIPE_DELETED: |
229 | NULL, NULL, 0); | 229 | if (skb->len != 1) { |
230 | status = NFC_HCI_ANY_E_NOK; | ||
231 | goto exit; | ||
232 | } | ||
233 | delete_info = (struct hci_delete_pipe_noti *)skb->data; | ||
234 | |||
235 | hdev->pipes[delete_info->pipe].gate = NFC_HCI_INVALID_GATE; | ||
236 | hdev->pipes[delete_info->pipe].dest_host = NFC_HCI_INVALID_HOST; | ||
230 | break; | 237 | break; |
231 | case NFC_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: | 238 | case NFC_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED: |
232 | nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE, | 239 | if (skb->len != 1) { |
233 | NFC_HCI_ANY_OK, NULL, 0, NULL, NULL, 0); | 240 | status = NFC_HCI_ANY_E_NOK; |
241 | goto exit; | ||
242 | } | ||
243 | cleared_info = (struct hci_all_pipe_cleared_noti *)skb->data; | ||
234 | 244 | ||
245 | nfc_hci_reset_pipes_per_host(hdev, cleared_info->host); | ||
235 | break; | 246 | break; |
236 | default: | 247 | default: |
237 | pr_info("Discarded unknown cmd %x to gate %x\n", cmd, gate); | 248 | pr_info("Discarded unknown cmd %x to gate %x\n", cmd, gate); |
238 | r = -EINVAL; | ||
239 | break; | 249 | break; |
240 | } | 250 | } |
241 | 251 | ||
252 | exit: | ||
253 | nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE, | ||
254 | status, NULL, 0, NULL, NULL, 0); | ||
255 | |||
242 | kfree_skb(skb); | 256 | kfree_skb(skb); |
243 | } | 257 | } |
244 | 258 | ||
diff --git a/net/nfc/hci/hci.h b/net/nfc/hci/hci.h index c3d2e2c1394c..c1278bd0fc5e 100644 --- a/net/nfc/hci/hci.h +++ b/net/nfc/hci/hci.h | |||
@@ -65,6 +65,14 @@ struct hci_create_pipe_resp { | |||
65 | u8 pipe; | 65 | u8 pipe; |
66 | } __packed; | 66 | } __packed; |
67 | 67 | ||
68 | struct hci_delete_pipe_noti { | ||
69 | u8 pipe; | ||
70 | } __packed; | ||
71 | |||
72 | struct hci_all_pipe_cleared_noti { | ||
73 | u8 host; | ||
74 | } __packed; | ||
75 | |||
68 | #define NFC_HCI_FRAGMENT 0x7f | 76 | #define NFC_HCI_FRAGMENT 0x7f |
69 | 77 | ||
70 | #define HCP_HEADER(type, instr) ((((type) & 0x03) << 6) | ((instr) & 0x3f)) | 78 | #define HCP_HEADER(type, instr) ((((type) & 0x03) << 6) | ((instr) & 0x3f)) |