Use timeout value calculated from PMm for T3T Check and Update commands.
Change-Id: I0c6cbf0f8ceb52305c3f3ba1df9db715193f57b0
diff --git a/src/nfc/tags/rw_t3t.c b/src/nfc/tags/rw_t3t.c
index 323ee75..b24eefa 100644
--- a/src/nfc/tags/rw_t3t.c
+++ b/src/nfc/tags/rw_t3t.c
@@ -49,6 +49,7 @@
#define RW_T3T_POLL_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*2*QUICK_TIMER_TICKS_PER_SEC) / 1000)
#define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS ((RW_T3T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000)
#define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
+#define RW_T3T_MIN_TIMEOUT_TICKS 3
/* Macro to extract major version from NDEF version byte */
#define T3T_GET_MAJOR_VERSION(ver) (ver>>4)
@@ -160,10 +161,53 @@
};
-/*****************************************************************************
-** Type3 TAG COMMANDS
-*****************************************************************************/
+/* This is (T/t3t * 4^E) , E is the index of the array. The unit is .0001 ms */
+static const UINT32 rw_t3t_mrti_base [] =
+{
+ 302,
+ 1208,
+ 4832,
+ 19328
+};
+
+/*******************************************************************************
+**
+** Function rw_t3t_check_timeout
+**
+** Description The timeout value is a + b * number_blocks)
+**
+** Returns timeout value in ticks
+**
+*******************************************************************************/
+static UINT32 rw_t3t_check_timeout (UINT16 num_blocks)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ UINT32 timeout;
+ timeout = (p_cb->check_tout_a + num_blocks * p_cb->check_tout_b)*QUICK_TIMER_TICKS_PER_SEC/1000000;
+ if (timeout < RW_T3T_MIN_TIMEOUT_TICKS)
+ timeout = RW_T3T_MIN_TIMEOUT_TICKS;
+ return timeout;
+}
+
+/*******************************************************************************
+**
+** Function rw_t3t_update_timeout
+**
+** Description The timeout value is a + b * number_blocks)
+**
+** Returns timeout value in ticks
+**
+*******************************************************************************/
+static UINT32 rw_t3t_update_timeout (UINT16 num_blocks)
+{
+ tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
+ UINT32 timeout;
+ timeout = (p_cb->update_tout_a + num_blocks * p_cb->update_tout_b)*QUICK_TIMER_TICKS_PER_SEC/1000000;
+ if (timeout < RW_T3T_MIN_TIMEOUT_TICKS)
+ timeout = RW_T3T_MIN_TIMEOUT_TICKS;
+ return timeout;
+}
/*******************************************************************************
**
** Function rw_t3t_process_error
@@ -582,7 +626,7 @@
** Returns tNFC_STATUS
**
*****************************************************************************/
-tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_ms)
+tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_ticks)
{
tNFC_STATUS retval;
@@ -591,13 +635,13 @@
memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (BT_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
p_cb->cur_cmd = rw_t3t_cmd;
- p_cb->cur_tout = timeout_ms;
+ p_cb->cur_tout = timeout_ticks;
p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
{
/* Start timer for waiting for response */
- nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ms);
+ nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ticks);
}
else
{
@@ -605,6 +649,7 @@
p_cb->rw_state = RW_T3T_STATE_IDLE;
}
+ RW_TRACE_DEBUG3 ("rw_t3t_send_cmd: cur_tout: %d, timeout_ticks: %d ret:%d",p_cb->cur_tout, timeout_ticks, retval);
return (retval);
}
@@ -688,7 +733,7 @@
p_cmd_buf->len = (UINT16) (p - p_cmd_start);
/* Send the T3T message */
- retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, rw_t3t_update_timeout(1));
}
else
{
@@ -779,7 +824,7 @@
/* Add number of blocks in this UPDATE command */
UINT8_TO_STREAM (p, ndef_blocks_to_write); /* Number of blocks to write in this command */
- timeout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) ndef_blocks_to_write;
+ timeout = rw_t3t_update_timeout(ndef_blocks_to_write);
for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++)
{
@@ -896,9 +941,7 @@
RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
- /* Write to command header for UPDATE */
-
- /* Add UPDATE opcode to message */
+ /* Add CHECK opcode to message */
UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
/* Add IDm to message */
@@ -917,7 +960,7 @@
UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);
}
- /* Add number of blocks in this UPDATE command */
+ /* Add number of blocks in this CHECK command */
UINT8_TO_STREAM (p, cur_blocks_to_read); /* Number of blocks to check in this command */
for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++)
@@ -941,7 +984,7 @@
p_cmd_buf->len = (UINT16) (p - p_cmd_start);
/* Send the T3T message */
- retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) cur_blocks_to_read);
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf, rw_t3t_check_timeout (cur_blocks_to_read));
}
else
{
@@ -1060,7 +1103,7 @@
p_cmd_buf->len = (UINT16) (p - p_cmd_start);
/* Send the T3T message */
- retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks);
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, rw_t3t_check_timeout(num_blocks));
}
else
{
@@ -1099,7 +1142,7 @@
p_cmd_buf->len = (UINT16) (p - p_cmd_start);
/* Send the T3T message */
- retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks);
+ retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, rw_t3t_update_timeout(num_blocks));
}
else
{
@@ -1150,7 +1193,7 @@
p_cmd_buf->len = (UINT16) (p - p_cmd_start);
/* Send the T3T message */
- return rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+ return rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, rw_t3t_check_timeout(1));
}
else
{
@@ -1716,7 +1759,7 @@
p_cmd_buf->len = (UINT16) (p - p_cmd_start);
/* Send the T3T message */
- if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS)) == NFC_STATUS_OK)
+ if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, rw_t3t_check_timeout(1))) == NFC_STATUS_OK)
{
/* CHECK command sent. Wait for response */
return;
@@ -1823,7 +1866,7 @@
p_cmd_buf->len = (UINT16) (p_dst - p_cmd_start);
/* Send the T3T message */
- status = rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
+ status = rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, rw_t3t_update_timeout(1));
}
else
{
@@ -2343,6 +2386,31 @@
/*******************************************************************************
**
+** Function rw_t3t_mrti_to_a_b
+**
+** Description Converts the given MRTI (Maximum Response Time Information)
+** to the base to calculate timeout value.
+** (The timeout value is a + b * number_blocks)
+**
+** Returns NFC_STATUS_OK
+**
+*******************************************************************************/
+static void rw_t3t_mrti_to_a_b (UINT8 mrti, UINT32 *p_a, UINT32 *p_b)
+{
+ UINT8 a, b, e;
+
+ a = (mrti & 0x7) + 1; /* A is bit 0 ~ bit 2 */
+ mrti >>=3;
+ b = (mrti & 0x7) + 1; /* B is bit 3 ~ bit 5 */
+ mrti >>=3;
+ e = mrti & 0x3; /* E is bit 6 ~ bit 7 */
+ *p_a = rw_t3t_mrti_base[e] * a; /* (A+1) * base (i.e T/t3t * 4^E) */
+ *p_b = rw_t3t_mrti_base[e] * b; /* (B+1) * base (i.e T/t3t * 4^E) */
+}
+
+
+/*******************************************************************************
+**
** Function rw_t3t_select
**
** Description Called by NFC manager when a Type3 tag has been activated
@@ -2360,6 +2428,8 @@
p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED; /* Indicate that NDEF detection has not been performed yet */
p_cb->rw_state = RW_T3T_STATE_IDLE;
p_cb->flags = 0;
+ rw_t3t_mrti_to_a_b (mrti_check, &p_cb->check_tout_a, &p_cb->check_tout_b);
+ rw_t3t_mrti_to_a_b (mrti_update, &p_cb->update_tout_a, &p_cb->update_tout_b);
/* Alloc cmd buf for retransmissions */
if (p_cb->p_cur_cmd_buf == NULL)