aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorChristophe Ricard <christophe.ricard@gmail.com>2015-01-26 19:18:14 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2015-01-27 18:03:29 -0500
commit615b524aca0bff52ce6654ddf26546546eb02e93 (patch)
tree11a9c76a55d8617978208b5ffbbbcb733442563b /net/nfc
parentaf77522320aa0e5b4b52dce615ad067d92e15fbf (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.c58
-rw-r--r--net/nfc/hci/hci.h8
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:
193void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, 193void 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
252exit:
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
68struct hci_delete_pipe_noti {
69 u8 pipe;
70} __packed;
71
72struct 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))