提交 485fdc9b 编写于 作者: M Mark A. Greer 提交者: Samuel Ortiz

NFC: digital: Enforce NFC-DEP PNI sequencing

NFC-DEP DEP_REQ and DEP_RES exchanges using 'I'
and 'ACK/NACK' PDUs have a sequence number called
the Packet Number Information (PNI).  The PNI
is incremented (modulo 4) after every DEP_REQ/
DEP_RES pair and should be verified by the digital
layer code.  That verification isn't always done,
though, so add code to make sure that it is done.
Reviewed-by: NThierry Escande <thierry.escande@linux.intel.com>
Tested-by: NThierry Escande <thierry.escande@linux.intel.com>
Signed-off-by: NMark A. Greer <mgreer@animalcreek.com>
Signed-off-by: NSamuel Ortiz <sameo@linux.intel.com>
上级 3e6b0de8
...@@ -447,8 +447,18 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, ...@@ -447,8 +447,18 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
pr_err("Received a ACK/NACK PDU\n"); pr_err("Received a ACK/NACK PDU\n");
if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
PROTOCOL_ERR("14.12.3.3");
rc = -EIO; rc = -EIO;
goto error; goto exit;
}
ddev->curr_nfc_dep_pni =
DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
rc = -EINVAL;
goto exit;
case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) {
...@@ -592,9 +602,22 @@ static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg, ...@@ -592,9 +602,22 @@ static void digital_tg_recv_dep_req(struct nfc_digital_dev *ddev, void *arg,
switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) { switch (DIGITAL_NFC_DEP_PFB_TYPE(pfb)) {
case DIGITAL_NFC_DEP_PFB_I_PDU: case DIGITAL_NFC_DEP_PFB_I_PDU:
pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n"); pr_debug("DIGITAL_NFC_DEP_PFB_I_PDU\n");
ddev->curr_nfc_dep_pni = DIGITAL_NFC_DEP_PFB_PNI(pfb);
if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
PROTOCOL_ERR("14.12.3.4");
rc = -EIO;
goto exit;
}
rc = 0;
break; break;
case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
PROTOCOL_ERR("14.12.3.4");
rc = -EIO;
goto exit;
}
pr_err("Received a ACK/NACK PDU\n"); pr_err("Received a ACK/NACK PDU\n");
rc = -EINVAL; rc = -EINVAL;
goto exit; goto exit;
...@@ -629,6 +652,9 @@ int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb) ...@@ -629,6 +652,9 @@ int digital_tg_send_dep_res(struct nfc_digital_dev *ddev, struct sk_buff *skb)
sizeof(ddev->did)); sizeof(ddev->did));
} }
ddev->curr_nfc_dep_pni =
DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
digital_skb_push_dep_sod(ddev, skb); digital_skb_push_dep_sod(ddev, skb);
ddev->skb_add_crc(skb); ddev->skb_add_crc(skb);
...@@ -677,6 +703,8 @@ static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did, ...@@ -677,6 +703,8 @@ static int digital_tg_send_psl_res(struct nfc_digital_dev *ddev, u8 did,
ddev->skb_add_crc(skb); ddev->skb_add_crc(skb);
ddev->curr_nfc_dep_pni = 0;
rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete, rc = digital_tg_send_cmd(ddev, skb, 0, digital_tg_send_psl_res_complete,
(void *)(unsigned long)rf_tech); (void *)(unsigned long)rf_tech);
if (rc) if (rc)
...@@ -800,6 +828,8 @@ static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev, ...@@ -800,6 +828,8 @@ static int digital_tg_send_atr_res(struct nfc_digital_dev *ddev,
ddev->skb_add_crc(skb); ddev->skb_add_crc(skb);
ddev->curr_nfc_dep_pni = 0;
rc = digital_tg_send_cmd(ddev, skb, 999, rc = digital_tg_send_cmd(ddev, skb, 999,
digital_tg_send_atr_res_complete, NULL); digital_tg_send_atr_res_complete, NULL);
if (rc) if (rc)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册