diff options
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)) |