Commit 615b524a authored by Christophe Ricard's avatar Christophe Ricard Committed by Samuel Ortiz

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: default avatarChristophe Ricard <christophe-h.ricard@st.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent af775223
......@@ -193,52 +193,66 @@ void nfc_hci_resp_received(struct nfc_hci_dev *hdev, u8 result,
void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
struct sk_buff *skb)
{
int r = 0;
u8 gate = hdev->pipes[pipe].gate;
u8 local_gate, new_pipe;
u8 gate_opened = 0x00;
u8 status = NFC_HCI_ANY_OK;
struct hci_create_pipe_resp *create_info;
struct hci_delete_pipe_noti *delete_info;
struct hci_all_pipe_cleared_noti *cleared_info;
pr_debug("from gate %x pipe %x cmd %x\n", gate, pipe, cmd);
switch (cmd) {
case NFC_HCI_ADM_NOTIFY_PIPE_CREATED:
if (skb->len != 5) {
r = -EPROTO;
break;
status = NFC_HCI_ANY_E_NOK;
goto exit;
}
create_info = (struct hci_create_pipe_resp *)skb->data;
local_gate = skb->data[3];
new_pipe = skb->data[4];
nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE,
NFC_HCI_ANY_OK, NULL, 0, NULL, NULL, 0);
/* save the new created pipe and bind with local gate,
/* Save the new created pipe and bind with local gate,
* the description for skb->data[3] is destination gate id
* but since we received this cmd from host controller, we
* are the destination and it is our local gate
*/
hdev->gate2pipe[local_gate] = new_pipe;
hdev->gate2pipe[create_info->dest_gate] = create_info->pipe;
hdev->pipes[create_info->pipe].gate = create_info->dest_gate;
hdev->pipes[create_info->pipe].dest_host =
create_info->src_host;
break;
case NFC_HCI_ANY_OPEN_PIPE:
/* if the pipe is already created, we allow remote host to
* open it
*/
if (gate != 0xff)
nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE,
NFC_HCI_ANY_OK, &gate_opened, 1,
NULL, NULL, 0);
if (gate == NFC_HCI_INVALID_GATE) {
status = NFC_HCI_ANY_E_NOK;
goto exit;
}
break;
case NFC_HCI_ADM_NOTIFY_PIPE_DELETED:
if (skb->len != 1) {
status = NFC_HCI_ANY_E_NOK;
goto exit;
}
delete_info = (struct hci_delete_pipe_noti *)skb->data;
hdev->pipes[delete_info->pipe].gate = NFC_HCI_INVALID_GATE;
hdev->pipes[delete_info->pipe].dest_host = NFC_HCI_INVALID_HOST;
break;
case NFC_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE,
NFC_HCI_ANY_OK, NULL, 0, NULL, NULL, 0);
if (skb->len != 1) {
status = NFC_HCI_ANY_E_NOK;
goto exit;
}
cleared_info = (struct hci_all_pipe_cleared_noti *)skb->data;
nfc_hci_reset_pipes_per_host(hdev, cleared_info->host);
break;
default:
pr_info("Discarded unknown cmd %x to gate %x\n", cmd, gate);
r = -EINVAL;
break;
}
exit:
nfc_hci_hcp_message_tx(hdev, pipe, NFC_HCI_HCP_RESPONSE,
status, NULL, 0, NULL, NULL, 0);
kfree_skb(skb);
}
......
......@@ -65,6 +65,14 @@ struct hci_create_pipe_resp {
u8 pipe;
} __packed;
struct hci_delete_pipe_noti {
u8 pipe;
} __packed;
struct hci_all_pipe_cleared_noti {
u8 host;
} __packed;
#define NFC_HCI_FRAGMENT 0x7f
#define HCP_HEADER(type, instr) ((((type) & 0x03) << 6) | ((instr) & 0x3f))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment