diff options
author | Nick Pelly <npelly@google.com> | 2011-10-19 18:36:47 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2011-10-21 16:03:23 -0700 |
commit | 5ea62ad25e2050f543d8e2104f5ffc1bb2c1ef28 (patch) | |
tree | 77c2c2d626ec36d1873be955fbcc161667b16be8 /src | |
parent | 31e4d8b1ad54c78cb667155ad4ed9ece33f4b075 (diff) | |
download | external_libnfc-nxp-5ea62ad25e2050f543d8e2104f5ffc1bb2c1ef28.zip external_libnfc-nxp-5ea62ad25e2050f543d8e2104f5ffc1bb2c1ef28.tar.gz external_libnfc-nxp-5ea62ad25e2050f543d8e2104f5ffc1bb2c1ef28.tar.bz2 |
Fixes to LLC and DAL to handle unreliable UART.
Use a 100ms timeout in uart_read() when reading LLC payload only.
Allow 200 retries on host.
Note that we use pn544 timeout retransmit instead of an explicit REJ
(do not use CRC_ERROR_REJ). The reason is that after a
dropped frame, a host timeout on read() is the only reliable way to recover
frame alignment, but if we send an immediate REJ then we are constantly reading
and can never regain frame alignment.
Also note that the pn544 timeout (200ms) is higher than the host (100ms). This
allows the host to abort a partial read and return to known state before the
pn544 re-transmits.
We have to turn off timeout for FW mode. Typical read time is ~100ms, but some
are 1 second+
Modify DAL & LLC layer to more reliably handle partial frames by searching for
a LLC length byte again, and log the various error paths.
Also introduce debugging tools:
debug.nfc.LOW_LEVEL_TRACES 2
Will enable LLC header decoding in the trace output.
Only read at NFC init time, use /data/local.prop to enable.
debug.nfc.UART_ERROR_RATE X
Will randomly inject errors at the uart transport, with a probability of X/1000
for every byte. 50% of those errors will be a dropped byte, 50% will be
corrupted. Recommend X=10. FW mode can't handle any errors. Can be enabled
after boot.
adb shell dumpsys nfc
Will now print the number of errors detected at the LLC layer.
Change-Id: I739ed193e3d4caa563a866b6a9d834c154917962
Diffstat (limited to 'src')
-rw-r--r-- | src/phLlcNfc_DataTypes.h | 4 | ||||
-rw-r--r-- | src/phLlcNfc_Interface.c | 31 | ||||
-rw-r--r-- | src/phOsalNfc.h | 3 |
3 files changed, 32 insertions, 6 deletions
diff --git a/src/phLlcNfc_DataTypes.h b/src/phLlcNfc_DataTypes.h index 9d5b588..b84cd3e 100644 --- a/src/phLlcNfc_DataTypes.h +++ b/src/phLlcNfc_DataTypes.h @@ -132,7 +132,7 @@ DEFINED : then if the received NS = (expected NR - 1) then instead of REJ RR frame is sent COMMENTED : then REJ frame is sent */ -#define LLC_RR_INSTEAD_OF_REJ +// #define LLC_RR_INSTEAD_OF_REJ #define SEND_UFRAME @@ -205,7 +205,7 @@ COMMENTED : then exception is raised #define PH_LLCNFC_READPEND_REMAIN_BYTE (0x02U) /** Read pending not done */ #define PH_LLCNFC_READPEND_FLAG_OFF FALSE -#define PH_LLCNFC_MAX_REJ_RETRY_COUNT (10) +#define PH_LLCNFC_MAX_REJ_RETRY_COUNT (200) /**** Macros for state machine ****/ diff --git a/src/phLlcNfc_Interface.c b/src/phLlcNfc_Interface.c index a1e9938..175462d 100644 --- a/src/phLlcNfc_Interface.c +++ b/src/phLlcNfc_Interface.c @@ -43,6 +43,9 @@ #ifdef PH_LLCNFC_DALINT #include <phDal4Nfc.h> #endif +#define LOG_TAG "NFC-LLC" + +#include <utils/Log.h> /*********************** End of includes ****************************/ /***************************** Macros *******************************/ @@ -70,6 +73,7 @@ phLlcNfc_RdResp_Cb( /******************** End of Local functions ************************/ /********************** Global variables ****************************/ +int libnfc_llc_error_count = 0; /******************** End of Global Variables ***********************/ @@ -666,7 +670,7 @@ phLlcNfc_RdResp_Cb( PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB CALLED\n\n"); if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo) - && (pCompInfo->length != 0) && (NULL != pCompInfo->buffer)) + && (NULL != pCompInfo->buffer)) { ps_frame_info = &(ps_llc_ctxt->s_frameinfo); ps_recv_pkt = &(ps_frame_info->s_recvpacket); @@ -782,19 +786,19 @@ phLlcNfc_RdResp_Cb( else if (ps_frame_info->recv_error_count < PH_LLCNFC_MAX_REJ_RETRY_COUNT) { + LOGW("LLC bad crc"); PH_LLCNFC_PRINT("CRC ERROR RECVD \n"); PH_LLCNFC_DEBUG("RECV ERROR COUNT : 0x%02X\n", ps_frame_info->recv_error_count); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); + libnfc_llc_error_count++; result = phLlcNfc_Interface_Read(ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), PH_LLCNFC_BYTES_INIT_READ); - #ifdef CRC_ERROR_REJ - /* Send REJ (S frame), as the CRC received has error */ result = phLlcNfc_H_SendRejectFrame (ps_llc_ctxt); @@ -803,6 +807,7 @@ phLlcNfc_RdResp_Cb( } else { + LOGE("max LLC retries exceeded, stack restart"); result = phLlcNfc_Interface_Read (ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), @@ -827,6 +832,7 @@ phLlcNfc_RdResp_Cb( else if (ps_frame_info->recv_error_count >= PH_LLCNFC_MAX_REJ_RETRY_COUNT) { + LOGE("max LLC retries exceeded, stack restart"); result = phLlcNfc_Interface_Read (ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), @@ -849,8 +855,10 @@ phLlcNfc_RdResp_Cb( (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > pCompInfo->length) && (pCompInfo->length != ps_recv_pkt->s_llcbuf.llc_length_byte)) { + LOGE("bad LLC length1 %d", pCompInfo->length); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); + libnfc_llc_error_count++; result = phLlcNfc_Interface_Read(ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, @@ -875,8 +883,10 @@ phLlcNfc_RdResp_Cb( value is greater than (0x21 - 1), then pend a read to get 1 byte again */ + LOGW("bad LLC length byte %x\n", *(pCompInfo->buffer)); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); + libnfc_llc_error_count++; result = phLlcNfc_Interface_Read(ps_llc_ctxt, PH_LLCNFC_READWAIT_OFF, @@ -885,8 +895,10 @@ phLlcNfc_RdResp_Cb( } else { + LOGW("unknown LLC error1"); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); + libnfc_llc_error_count++; phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, ps_llc_ctxt->s_timerinfo.guard_to_count); @@ -905,11 +917,24 @@ phLlcNfc_RdResp_Cb( pHwInfo, pCompInfo); } } + } else if (NFCSTATUS_READ_FAILED == pCompInfo->status) { + // partial read - try reading the length byte again + LOGW("LLC length mis-match\n"); + ps_frame_info->recv_error_count = (uint8_t) + (ps_frame_info->recv_error_count + 1); + libnfc_llc_error_count++; + + result = phLlcNfc_Interface_Read(ps_llc_ctxt, + PH_LLCNFC_READWAIT_OFF, + (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), + PH_LLCNFC_BYTES_INIT_READ); } else { + LOGW("unknown LLC error2"); ps_frame_info->recv_error_count = (uint8_t) (ps_frame_info->recv_error_count + 1); + libnfc_llc_error_count++; phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, ps_llc_ctxt->s_timerinfo.guard_to_count); diff --git a/src/phOsalNfc.h b/src/phOsalNfc.h index 246c2e6..e522263 100644 --- a/src/phOsalNfc.h +++ b/src/phOsalNfc.h @@ -166,7 +166,8 @@ void phOsalNfc_DbgString(const char *pString); * * \retval None */ -void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer); +void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer, + int verbosity); /*! * \ingroup grp_osal_nfc |