diff options
42 files changed, 1580 insertions, 975 deletions
@@ -6,7 +6,6 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_PRELINK_MODULE := false LOCAL_ARM_MODE := arm #phLibNfc @@ -105,28 +104,23 @@ LOCAL_SRC_FILES += Linux_x86/phDal4Nfc.c LOCAL_SRC_FILES += Linux_x86/phDal4Nfc_i2c.c LOCAL_SRC_FILES += Linux_x86/phDal4Nfc_messageQueueLib.c -# Really verbose: -#LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -DDEBUG -DDAL_TRACE -DINCLUDE_DALINIT_DEINIT -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -Werror-implicit-function-declaration -fno-strict-aliasing -fpic -# Just show I2C traffic: -#LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -DINCLUDE_DALINIT_DEINIT -DLOW_LEVEL_TRACES -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -Werror-implicit-function-declaration -fno-strict-aliasing -fpic -# Quiet: -LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -DINCLUDE_DALINIT_DEINIT -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -Werror-implicit-function-declaration -fno-strict-aliasing -fpic - -ifeq ($(TARGET_ARCH),arm) -LOCAL_CFLAGS += -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -endif - -ifeq ($(NFC_BUILD_VARIANT),debug) -LOCAL_CFLAGS += -DDEBUG -D_DEBUG -LOCAL_CFLAGS += -O0 -g -$(info DEBUG) -endif -ifeq ($(NFC_BUILD_VARIANT),release) -LOCAL_CFLAGS += -DNDEBUG -LOCAL_CFLAGS += -Os -LOCAL_CFLAGS += -Wl,-s -$(info RELEASE) -endif +LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -fno-strict-aliasing + +# Uncomment for Chipset command/responses +# Or use "setprop debug.nfc.LOW_LEVEL_TRACES" at run-time +# LOCAL_CFLAGS += -DLOW_LEVEL_TRACES + +# Uncomment for DAL traces +# LOCAL_CFLAGS += -DDEBUG -DDAL_TRACE + +# Uncomment for LLC traces +# LOCAL_CFLAGS += -DDEBUG -DLLC_TRACE + +# Uncomment for LLCP traces +# LOCAL_CFLAGS += -DDEBUG -DLLCP_TRACE + +# Uncomment for HCI traces +# LOCAL_CFLAGS += -DDEBUG -DHCI_TRACE #includes LOCAL_CFLAGS += -I$(LOCAL_PATH)/inc @@ -145,8 +139,6 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) -LOCAL_PRELINK_MODULE := false - LOCAL_SRC_FILES += src/phFriNfc_NdefRecord.c LOCAL_CFLAGS += -I$(LOCAL_PATH)/inc @@ -157,4 +149,3 @@ LOCAL_MODULE_TAGS := optional LOCAL_SHARED_LIBRARIES := libcutils include $(BUILD_SHARED_LIBRARY) - diff --git a/CleanSpec.mk b/CleanSpec.mk new file mode 100644 index 0000000..5a4aac6 --- /dev/null +++ b/CleanSpec.mk @@ -0,0 +1,53 @@ +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) + +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libnfc_intermediates/) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libnfc_ndef_intermediates/) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libnfc.so) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libnfc_ndef.so) diff --git a/Linux_x86/phDal4Nfc.c b/Linux_x86/phDal4Nfc.c index ec92566..9bedaf9 100644 --- a/Linux_x86/phDal4Nfc.c +++ b/Linux_x86/phDal4Nfc.c @@ -33,6 +33,8 @@ #include <stdlib.h> #ifdef ANDROID #include <linux/ipc.h> +#include <cutils/log.h> +#include <cutils/properties.h> // for property_get #else #include <sys/msg.h> #endif @@ -98,6 +100,7 @@ static phDal4Nfc_SContext_t gDalContext; static pphDal4Nfc_SContext_t pgDalContext; static phHal_sHwReference_t * pgDalHwContext; static sem_t nfc_read_sem; +static int low_level_traces; #ifdef USE_MQ_MESSAGE_QUEUE static phDal4Nfc_DeferredCall_Msg_t nDeferedMessage; static mqd_t nDeferedCallMessageQueueId; @@ -117,6 +120,31 @@ static void phDal4Nfc_FillMsg (phDal4Nfc_Message_t *pDalMsg, phOsalN DAL API IMPLEMENTATION ------------------------------------------------------------------------------------*/ +static void refresh_low_level_traces() { +#ifdef LOW_LEVEL_TRACES + low_level_traces = 1; + return; +#else + +#ifdef ANDROID + char value[PROPERTY_VALUE_MAX]; + + property_get("ro.debuggable", value, ""); + if (!value[0] || !atoi(value)) { + low_level_traces = 0; // user build, do not allow debug + return; + } + + property_get("debug.nfc.LOW_LEVEL_TRACES", value, ""); + if (value[0]) { + low_level_traces = atoi(value) ? 1 : 0; + return; + } +#endif + low_level_traces = 0; +#endif +} + /*----------------------------------------------------------------------------- FUNCTION: phDal4Nfc_Register @@ -216,6 +244,8 @@ NFCSTATUS phDal4Nfc_Init(void *pContext, void *pHwRef ) { NFCSTATUS result = NFCSTATUS_SUCCESS; + refresh_low_level_traces(); + if ((NULL != pContext) && (NULL != pHwRef)) { pContext = pgDalContext; @@ -530,7 +560,6 @@ NFCSTATUS phDal4Nfc_Config(pphDal4Nfc_sConfig_t config,void **phwref) gLinkFunc.open_and_configure = phDal4Nfc_uart_open_and_configure; gLinkFunc.read = phDal4Nfc_uart_read; gLinkFunc.write = phDal4Nfc_uart_write; - gLinkFunc.download = phDal4Nfc_uart_download; gLinkFunc.reset = phDal4Nfc_uart_reset; } break; @@ -605,7 +634,7 @@ NFCSTATUS phDal4Nfc_Reset(long level) { NFCSTATUS retstatus = NFCSTATUS_SUCCESS; - DAL_DEBUG("phDal4Nfc_Reset: VEN to %d",level); + DAL_DEBUG("phDal4Nfc_Reset: VEN to %ld",level); retstatus = gLinkFunc.reset(level); @@ -720,17 +749,19 @@ retry: else { i2c_error_count = 0; -#ifdef LOW_LEVEL_TRACES - phOsalNfc_PrintData("Received buffer", (uint16_t)gReadWriteContext.nNbOfBytesRead, gReadWriteContext.pReadBuffer); -#endif + + if (low_level_traces) + { + phOsalNfc_PrintData("RECV", (uint16_t)gReadWriteContext.nNbOfBytesRead, gReadWriteContext.pReadBuffer); + } DAL_DEBUG("RX Thread Read ok. nbToRead=%d\n", gReadWriteContext.nNbOfBytesToRead); DAL_DEBUG("RX Thread NbReallyRead=%d\n", gReadWriteContext.nNbOfBytesRead); - DAL_PRINT("RX Thread ReadBuff[]={ "); +/* DAL_PRINT("RX Thread ReadBuff[]={ "); for (i = 0; i < gReadWriteContext.nNbOfBytesRead; i++) { DAL_DEBUG("RX Thread 0x%x ", gReadWriteContext.pReadBuffer[i]); } - DAL_PRINT("RX Thread }\n"); + DAL_PRINT("RX Thread }\n"); */ /* read completed immediately */ sMsg.eMsgType= PHDAL4NFC_READ_MESSAGE; @@ -867,9 +898,10 @@ void phDal4Nfc_DeferredCb (void *params) case PHDAL4NFC_WRITE_MESSAGE: DAL_PRINT(" Dal deferred write called \n"); -#ifdef LOW_LEVEL_TRACES - phOsalNfc_PrintData("Send buffer", (uint16_t)gReadWriteContext.nNbOfBytesToWrite, gReadWriteContext.pWriteBuffer); -#endif + if(low_level_traces) + { + phOsalNfc_PrintData("SEND", (uint16_t)gReadWriteContext.nNbOfBytesToWrite, gReadWriteContext.pWriteBuffer); + } /* DAL_DEBUG("dalMsg->transactInfo.length : %d\n", dalMsg->transactInfo.length); */ /* Make a Physical WRITE */ @@ -894,12 +926,12 @@ void phDal4Nfc_DeferredCb (void *params) DAL_PRINT(" Physical Write Success \n"); TransactionInfo.length=(uint16_t)gReadWriteContext.nNbOfBytesWritten; TransactionInfo.status=NFCSTATUS_SUCCESS; - DAL_PRINT("WriteBuff[]={ "); +/* DAL_PRINT("WriteBuff[]={ "); for (i = 0; i < gReadWriteContext.nNbOfBytesWritten; i++) { DAL_DEBUG("0x%x ", gReadWriteContext.pWriteBuffer[i]); } - DAL_PRINT("}\n"); + DAL_PRINT("}\n"); */ // Free TempWriteBuffer if(gReadWriteContext.pTempWriteBuffer != NULL) diff --git a/Linux_x86/phDal4Nfc_i2c.c b/Linux_x86/phDal4Nfc_i2c.c index 2d0e113..72da8e7 100644 --- a/Linux_x86/phDal4Nfc_i2c.c +++ b/Linux_x86/phDal4Nfc_i2c.c @@ -23,7 +23,7 @@ */ #define LOG_TAG "NFC_i2c" -#include <utils/Log.h> +#include <cutils/log.h> #include <stdlib.h> #include <unistd.h> @@ -31,6 +31,7 @@ #include <termios.h> #include <sys/ioctl.h> #include <sys/select.h> +#include <errno.h> #include <phDal4Nfc_debug.h> #include <phDal4Nfc_i2c.h> @@ -188,20 +189,49 @@ PURPOSE: Reads nNbBytesToRead bytes and writes them in pBuffer. int phDal4Nfc_i2c_read(uint8_t * pBuffer, int nNbBytesToRead) { - int ret; - DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!"); - - DAL_DEBUG("Reading %d bytes\n", nNbBytesToRead); - ret = read(gI2cPortContext.nHandle, pBuffer, nNbBytesToRead); - if (ret < 0) - { - DAL_DEBUG("Read failed: read() returned %d\n", ret); - } - else - { - DAL_DEBUG("Read succeed (%d bytes)\n", ret); - } - return ret; + int ret; + int numRead = 0; + struct timeval tv; + fd_set rfds; + + DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!"); + DAL_DEBUG("_i2c_read() called to read %d bytes", nNbBytesToRead); + + // Read with 2 second timeout, so that the read thread can be aborted + // when the pn544 does not respond and we need to switch to FW download + // mode. This should be done via a control socket instead. + while (numRead < nNbBytesToRead) { + FD_ZERO(&rfds); + FD_SET(gI2cPortContext.nHandle, &rfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + ret = select(gI2cPortContext.nHandle + 1, &rfds, NULL, NULL, &tv); + if (ret < 0) { + DAL_DEBUG("select() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } else if (ret == 0) { + DAL_PRINT("timeout!"); + return -1; + } + ret = read(gI2cPortContext.nHandle, pBuffer + numRead, nNbBytesToRead - numRead); + if (ret > 0) { + DAL_DEBUG("read %d bytes", ret); + numRead += ret; + } else if (ret == 0) { + DAL_PRINT("_i2c_read() EOF"); + return -1; + } else { + DAL_DEBUG("_i2c_read() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + return numRead; } /*----------------------------------------------------------------------------- @@ -215,23 +245,32 @@ PURPOSE: Writes nNbBytesToWrite bytes from pBuffer to the link int phDal4Nfc_i2c_write(uint8_t * pBuffer, int nNbBytesToWrite) { - int ret; - DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!"); - - DAL_DEBUG("Writing %d bytes\n", nNbBytesToWrite); - ret = write(gI2cPortContext.nHandle, pBuffer, nNbBytesToWrite); - if (ret < 0) - { - DAL_DEBUG("Write failed: write() returned %d \n", ret); - } - else - { - DAL_DEBUG("Write succeed (%d bytes)\n", ret); - } - return ret; + int ret; + int numWrote = 0; + + DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!"); + DAL_DEBUG("_i2c_write() called to write %d bytes\n", nNbBytesToWrite); + + while (numWrote < nNbBytesToWrite) { + ret = write(gI2cPortContext.nHandle, pBuffer + numWrote, nNbBytesToWrite - numWrote); + if (ret > 0) { + DAL_DEBUG("wrote %d bytes", ret); + numWrote += ret; + } else if (ret == 0) { + DAL_PRINT("_i2c_write() EOF"); + return -1; + } else { + DAL_DEBUG("_i2c_write() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + + return numWrote; } - /*----------------------------------------------------------------------------- FUNCTION: phDal4Nfc_i2c_reset @@ -241,26 +280,7 @@ PURPOSE: Reset the PN544, using the VEN pin -----------------------------------------------------------------------------*/ int phDal4Nfc_i2c_reset(long level) { - int ret = NFCSTATUS_SUCCESS; - - DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld",level); - - ret = ioctl(gI2cPortContext.nHandle, PN544_SET_PWR, level); - - /* HACK to increase reset time - * TODO: move this to kernel - */ - if (level == 0) { - LOGW("sleeping a little longer..."); - usleep(50000); - } else { - usleep(10000); - } + DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld", level); - return ret; + return ioctl(gI2cPortContext.nHandle, PN544_SET_PWR, level); } - - - - - diff --git a/Linux_x86/phDal4Nfc_uart.c b/Linux_x86/phDal4Nfc_uart.c index 30cb500..bb891e3 100644 --- a/Linux_x86/phDal4Nfc_uart.c +++ b/Linux_x86/phDal4Nfc_uart.c @@ -26,11 +26,17 @@ * */ +#define LOG_TAG "NFC_uart" +#include <cutils/log.h> + #include <unistd.h> #include <fcntl.h> #include <termios.h> +#include <errno.h> #include <sys/ioctl.h> #include <sys/select.h> +#include <stdio.h> +#include <errno.h> #include <phDal4Nfc_debug.h> #include <phDal4Nfc_uart.h> @@ -161,28 +167,28 @@ NFCSTATUS phDal4Nfc_uart_open_and_configure(pphDal4Nfc_sConfig_t pConfig, void * switch(pConfig->nLinkType) { case ENUM_DAL_LINK_TYPE_COM1: - pComPort = "/dev/ttyS0"; + pComPort = "/dev/ttyO0"; break; case ENUM_DAL_LINK_TYPE_COM2: - pComPort = "/dev/ttyS1"; + pComPort = "/dev/ttyO1"; break; case ENUM_DAL_LINK_TYPE_COM3: - pComPort = "/dev/ttyS2"; + pComPort = "/dev/ttyO2"; break; case ENUM_DAL_LINK_TYPE_COM4: - pComPort = "/dev/ttyS3"; + pComPort = "/dev/ttyO3"; break; case ENUM_DAL_LINK_TYPE_COM5: - pComPort = "/dev/ttyS4"; + pComPort = "/dev/ttyO4"; break; case ENUM_DAL_LINK_TYPE_COM6: - pComPort = "/dev/ttyS5"; + pComPort = "/dev/ttyO5"; break; case ENUM_DAL_LINK_TYPE_COM7: - pComPort = "/dev/ttyS6"; + pComPort = "/dev/ttyO6"; break; case ENUM_DAL_LINK_TYPE_COM8: - pComPort = "/dev/ttyS7"; + pComPort = "/dev/ttyO7"; break; case ENUM_DAL_LINK_TYPE_USB: pComPort = "/dev/ttyUSB0"; @@ -263,31 +269,51 @@ PURPOSE: Reads nNbBytesToRead bytes and writes them in pBuffer. Returns the number of bytes really read or -1 in case of error. -----------------------------------------------------------------------------*/ - int phDal4Nfc_uart_read(uint8_t * pBuffer, int nNbBytesToRead) { - fd_set rfds; - struct timeval tv; - int ret; - - DAL_ASSERT_STR(gComPortContext.nOpened == 1, "read called but not opened!"); - - FD_ZERO(&rfds); - FD_SET(gComPortContext.nHandle, &rfds); - - /* select will block for 10 sec */ - tv.tv_sec = 2; - tv.tv_usec = 0; - - ret = select(gComPortContext.nHandle + 1, &rfds, NULL, NULL, &tv); - - if (ret == -1) - return -1; - - if (ret) - return read(gComPortContext.nHandle, pBuffer, nNbBytesToRead); - - return 0; + int ret; + int numRead = 0; + struct timeval tv; + fd_set rfds; + + DAL_ASSERT_STR(gComPortContext.nOpened == 1, "read called but not opened!"); + DAL_DEBUG("_uart_read() called to read %d bytes", nNbBytesToRead); + + // Read with 2 second timeout, so that the read thread can be aborted + // when the pn544 does not respond and we need to switch to FW download + // mode. This should be done via a control socket instead. + while (numRead < nNbBytesToRead) { + FD_ZERO(&rfds); + FD_SET(gComPortContext.nHandle, &rfds); + tv.tv_sec = 2; + tv.tv_usec = 0; + ret = select(gComPortContext.nHandle + 1, &rfds, NULL, NULL, NULL); + if (ret < 0) { + DAL_DEBUG("select() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } else if (ret == 0) { + DAL_PRINT("timeout!"); + break; // return partial response + } + ret = read(gComPortContext.nHandle, pBuffer + numRead, nNbBytesToRead - numRead); + if (ret > 0) { + DAL_DEBUG("read %d bytes", ret); + numRead += ret; + } else if (ret == 0) { + DAL_PRINT("_uart_read() EOF"); + return 0; + } else { + DAL_DEBUG("_uart_read() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + return numRead; } /*----------------------------------------------------------------------------- @@ -301,28 +327,30 @@ PURPOSE: Writes nNbBytesToWrite bytes from pBuffer to the link int phDal4Nfc_uart_write(uint8_t * pBuffer, int nNbBytesToWrite) { - fd_set wfds; - struct timeval tv; - int ret; - - DAL_ASSERT_STR(gComPortContext.nOpened == 1, "write called but not opened!"); - - FD_ZERO(&wfds); - FD_SET(gComPortContext.nHandle, &wfds); - - /* select will block for 10 sec */ - tv.tv_sec = 2; - tv.tv_usec = 0; - - ret = select(gComPortContext.nHandle + 1, NULL, &wfds, NULL, &tv); - - if (ret == -1) - return -1; - - if (ret) - return write(gComPortContext.nHandle, pBuffer, nNbBytesToWrite); - - return 0; + int ret; + int numWrote = 0; + + DAL_ASSERT_STR(gComPortContext.nOpened == 1, "write called but not opened!"); + DAL_DEBUG("_uart_write() called to write %d bytes\n", nNbBytesToWrite); + + while (numWrote < nNbBytesToWrite) { + ret = write(gComPortContext.nHandle, pBuffer + numWrote, nNbBytesToWrite - numWrote); + if (ret > 0) { + DAL_DEBUG("wrote %d bytes", ret); + numWrote += ret; + } else if (ret == 0) { + DAL_PRINT("_uart_write() EOF"); + return -1; + } else { + DAL_DEBUG("_uart_write() errno=%d", errno); + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return -1; + } + } + + return numWrote; } /*----------------------------------------------------------------------------- @@ -332,24 +360,38 @@ FUNCTION: phDal4Nfc_uart_reset PURPOSE: Reset the PN544, using the VEN pin -----------------------------------------------------------------------------*/ -int phDal4Nfc_uart_reset() +int phDal4Nfc_uart_reset(long level) { - DAL_PRINT("phDal4Nfc_uart_reset"); - - return NFCSTATUS_FEATURE_NOT_SUPPORTED; + static const char NFC_POWER_PATH[] = "/sys/devices/platform/nfc-power/nfc_power"; + int sz; + int fd = -1; + int ret = NFCSTATUS_FAILED; + char buffer[2]; + + DAL_DEBUG("phDal4Nfc_uart_reset, VEN level = %ld", level); + + if (snprintf(buffer, sizeof(buffer), "%u", (unsigned int)level) != 1) { + LOGE("Bad nfc power level (%u)", (unsigned int)level); + goto out; + } + + fd = open(NFC_POWER_PATH, O_WRONLY); + if (fd < 0) { + LOGE("open(%s) for write failed: %s (%d)", NFC_POWER_PATH, + strerror(errno), errno); + goto out; + } + sz = write(fd, &buffer, sizeof(buffer) - 1); + if (sz < 0) { + LOGE("write(%s) failed: %s (%d)", NFC_POWER_PATH, strerror(errno), + errno); + goto out; + } + ret = NFCSTATUS_SUCCESS; + +out: + if (fd >= 0) { + close(fd); + } + return ret; } - -/*----------------------------------------------------------------------------- - -FUNCTION: phDal4Nfc_uart_write - -PURPOSE: Put the PN544 in download mode, using the GPIO4 pin - ------------------------------------------------------------------------------*/ -int phDal4Nfc_uart_download() -{ - DAL_PRINT("phDal4Nfc_uart_download"); - - return NFCSTATUS_FEATURE_NOT_SUPPORTED; -} - diff --git a/Linux_x86/phOsalNfc.c b/Linux_x86/phOsalNfc.c index 9765e2c..0544309 100644 --- a/Linux_x86/phOsalNfc.c +++ b/Linux_x86/phOsalNfc.c @@ -160,16 +160,15 @@ void phOsalNfc_RaiseException(phOsalNfc_ExceptionType_t eExceptionType, uint16_t */ void phOsalNfc_PrintData(const char *pString, uint32_t length, uint8_t *pBuffer) { - char print_buffer[512]; // Max length 512 for the download mode + char print_buffer[length * 3 + 1]; int i; - if(NULL!=pString && length > 1 && length < 34) - { - print_buffer[0] = '\0'; - for (i = 0; i < length; i++) { - snprintf(&print_buffer[i*5], 6, " 0x%02X", pBuffer[i]); - } - LOGD("> NFC I2C %s: %s", pString,print_buffer); + if (pString == NULL) { + pString = ""; + } + print_buffer[0] = '\0'; + for (i = 0; i < length; i++) { + snprintf(&print_buffer[i*3], 4, " %02X", pBuffer[i]); } + LOGD("> %s:%s", pString, print_buffer); } - diff --git a/inc/phNfcConfig.h b/inc/phNfcConfig.h index 19a881b..e7386d9 100644 --- a/inc/phNfcConfig.h +++ b/inc/phNfcConfig.h @@ -176,7 +176,7 @@ #endif #ifndef NXP_MIFARE_XCHG_TIMEOUT -#define NXP_MIFARE_XCHG_TIMEOUT 0x03U +#define NXP_MIFARE_XCHG_TIMEOUT 0x0BU #endif #ifndef NXP_FELICA_XCHG_TIMEOUT @@ -223,6 +223,12 @@ #define LINK_CONNECTION_TIMEOUT 1000U #endif +/**< Defines ACK time out value for LLC timer, + 150 is in milliseconds */ +#ifndef LINK_ACK_TIMEOUT +#define LINK_ACK_TIMEOUT 1U +#endif + /**< Defines Firmware Download Completion Timeout value , 120000 is in milliseconds */ @@ -254,7 +260,7 @@ #ifndef NXP_NFC_HCI_TIMER -#define NXP_NFC_HCI_TIMER 0 +#define NXP_NFC_HCI_TIMER 1 #define NXP_NFC_HCI_TIMEOUT 6000 #endif diff --git a/inc/phNfcLlcpTypes.h b/inc/phNfcLlcpTypes.h index 3c555c2..2954d00 100644 --- a/inc/phNfcLlcpTypes.h +++ b/inc/phNfcLlcpTypes.h @@ -55,7 +55,7 @@ * */ /*@{*/ -#define PHFRINFC_LLCP_NB_SOCKET_MAX 5 /**< Max.number of simultaneous sockets */ +#define PHFRINFC_LLCP_NB_SOCKET_MAX 10 /**< Max.number of simultaneous sockets */ /*@}*/ /** diff --git a/src/phDnldNfc.c b/src/phDnldNfc.c index 76fd88b..796653e 100644..100755 --- a/src/phDnldNfc.c +++ b/src/phDnldNfc.c @@ -24,9 +24,9 @@ * * * Project: NFC-FRI-1.1 * * * -* $Date: Thu Sep 9 14:58:05 2010 $ * +* $Date: Tue Jun 28 14:25:44 2011 $ * * $Author: ing04880 $ * -* $Revision: 1.32 $ * +* $Revision: 1.33 $ * * $Aliases: $ * * * =========================================================================== * @@ -39,6 +39,7 @@ ################################################################################ */ #include <stdlib.h> +#include <unistd.h> #include <phNfcConfig.h> #include <phNfcCompId.h> #include <phNfcIoctlCode.h> @@ -46,8 +47,7 @@ #include <phOsalNfc.h> #include <phOsalNfc_Timer.h> #include <phDal4Nfc.h> - - +#include <utils/Log.h> /* ################################################################################ ****************************** Macro Definitions ******************************* @@ -60,7 +60,6 @@ #define SECTION_HDR - #if defined (DNLD_SUMMARY) && !defined (DNLD_TRACE) #define DNLD_TRACE #endif @@ -91,12 +90,21 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define DNLD_PRINT_BUFFER(msg,buf,len) #endif +#define DO_DELAY(period) usleep(period) + +/* delay after SW reset cmd in ms, required on uart for XTAL stability */ +#define PHDNLD_DNLD_DELAY 5000 +#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */ +#define PHDNLD_DATA_SIZE ((PHDNLD_MAX_PACKET)- 8U) /* 0x01F8U */ + /* Max Data Size is 504 */ +#define PHDNLD_MIN_PACKET 0x03U /* Minimum Packet Size is 3*/ + #define PHDNLD_FRAME_LEN_SIZE 0x02U #define PHDNLD_ADDR_SIZE 0x03U #define PHDNLD_DATA_LEN_SIZE 0x02U -#define PHDNLD_MIN_PACKET 0x03U /* Minimum Packet Size is 3*/ -#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */ -#define PHDNLD_DATA_SIZE 0x01F8U /* Max Data Size is 504 */ + + +#define PHDNLD_PAGE_SIZE 0x80U /* Page Size Configured for 64 Bytes */ #define FW_MAX_SECTION 0x15U /* Max Number of Sections */ @@ -104,9 +112,10 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define DNLD_CRC32_SIZE 0x04U -#define DNLD_FW_CODE_ADDR 0x00800000 -#define DNLD_PATCH_CODE_ADDR 0x00018800 -#define DNLD_PATCH_TABLE_ADDR 0x00008200 +#define DNLD_CFG_PG_ADDR 0x00008000U +#define DNLD_FW_CODE_ADDR 0x00800000U +#define DNLD_PATCH_CODE_ADDR 0x00018800U +#define DNLD_PATCH_TABLE_ADDR 0x00008200U /* Command to Reset the Device in Download Mode */ @@ -162,7 +171,7 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define NXP_MAX_DNLD_RETRY 0x02U -#define NXP_MAX_SECTION_WRITE 0x04U +#define NXP_MAX_SECTION_WRITE 0x05U #define NXP_PATCH_VER_INDEX 0x05U @@ -197,6 +206,8 @@ typedef enum phDnldNfc_eState typedef enum phDnldNfc_eSeq { phDnld_Reset_Seq = 0x00, + phDnld_Activate_Patch, + phDnld_Deactivate_Patch, phDnld_Update_Patch, phDnld_Update_Patchtable, phDnld_Lock_System, @@ -274,7 +285,7 @@ typedef struct section_type unsigned trim_val:1; unsigned reset_required:1; unsigned verify_mem:1; - unsigned trim_check:1; + unsigned critical_section:1; unsigned section_crc_check:1; unsigned section_type_rfu:2; unsigned section_type_pad:24; @@ -351,8 +362,8 @@ typedef struct phDnldNfc_sData union param { phDnldNfc_sParam_t data_param; - uint8_t response_data[PHDNLD_MAX_PACKET]; - uint8_t config_verify_param; + uint8_t response_data[PHDNLD_MAX_PACKET + 0]; + uint8_t cmd_param; }param_info; }phDnldNfc_sData_t; @@ -460,8 +471,21 @@ typedef struct phDnldNfc_sContext ******************** Global and Static Variables Definition ******************** ################################################################################ */ + static phDnldNfc_sContext_t *gpphDnldContext = NULL; +#ifdef NXP_FW_DNLD_CHECK_PHASE + +#define NXP_FW_DNLD_COMPLETE_PHASE 0x00U +#define NXP_FW_DNLD_SYSTEM_PHASE 0x01U +#define NXP_FW_DNLD_CFG_PHASE 0x02U +#define NXP_FW_DNLD_DATA_PHASE 0x03U +#define NXP_FW_DNLD_INVALID_PHASE 0xFFU + +static uint8_t gphDnldPhase = NXP_FW_DNLD_COMPLETE_PHASE; + +#endif /* #ifdef NXP_FW_DNLD_CHECK_PHASE */ + /**/ /* @@ -627,8 +651,8 @@ phDnldNfc_Read( STATIC void phDnldNfc_Abort ( - uint32_t abort_id , - void * pcontext + uint32_t abort_id, + void *pContext ); @@ -796,7 +820,6 @@ phDnldNfc_Release_Resources ( phDnldNfc_sContext_t **ppsDnldContext ) { - if(NULL != (*ppsDnldContext)->p_resp_buffer) { phOsalNfc_FreeMemory((*ppsDnldContext)->p_resp_buffer); @@ -894,7 +917,7 @@ phDnldNfc_Set_Seq( NFCSTATUS status = NFCSTATUS_SUCCESS; static uint8_t prev_temp_state = 0; static uint8_t prev_temp_seq = - (uint8_t) phDnld_Update_Patch; + (uint8_t) phDnld_Activate_Patch; switch(seq_type) { @@ -911,26 +934,40 @@ phDnldNfc_Set_Seq( psDnldContext->cur_dnld_seq; break; } - case DNLD_SEQ_LOCK: + case DNLD_SEQ_UNLOCK: { psDnldContext->cur_dnld_state = (uint8_t) phDnld_Reset_State; - psDnldContext->next_dnld_state = - (uint8_t) phDnld_Reset_State; - psDnldContext->cur_dnld_seq = - (uint8_t) phDnld_Lock_System; + +#ifdef NXP_FW_DNLD_CHECK_PHASE + if( NXP_FW_DNLD_SYSTEM_PHASE < gphDnldPhase ) + { + psDnldContext->next_dnld_state = + (uint8_t)phDnld_Upgrade_State; + psDnldContext->next_dnld_seq = + (uint8_t)phDnld_Upgrade_Section; + } + else +#endif /* NXP_FW_DNLD_CHECK_PHASE */ + { + psDnldContext->next_dnld_state = + (uint8_t) phDnld_Unlock_State; + psDnldContext->cur_dnld_seq = + (uint8_t) phDnld_Activate_Patch; + } + psDnldContext->next_dnld_seq = psDnldContext->cur_dnld_seq; break; } - case DNLD_SEQ_UNLOCK: + case DNLD_SEQ_LOCK: { psDnldContext->cur_dnld_state = (uint8_t) phDnld_Reset_State; psDnldContext->next_dnld_state = - (uint8_t) phDnld_Unlock_State; + (uint8_t) phDnld_Reset_State; psDnldContext->cur_dnld_seq = - (uint8_t) phDnld_Update_Patch; + (uint8_t) phDnld_Lock_System; psDnldContext->next_dnld_seq = psDnldContext->cur_dnld_seq; break; @@ -1107,18 +1144,25 @@ phDnldNfc_Read( } else { -#ifdef FW_DOWNLOAD_VERIFY - if (( FALSE == p_sec_info->section_read ) + if (( FALSE == p_sec_info->section_read ) && (TRUE == ((section_type_t *)(&sec_type))->verify_mem )) { read_size = (uint16_t)(psDnldContext->prev_dnld_size ); DNLD_DEBUG(" FW_DNLD: Section Read = %X \n", read_size); } - else -#endif /* #ifdef FW_DOWNLOAD_VERIFY */ + else if( ( TRUE == p_sec_info->section_read ) + && ( TRUE == p_sec_info->section_write ) + ) { /*Already Read the Data Hence Ignore the Read */ - DNLD_DEBUG(" FW_DNLD: Already Read/Read Back Ignored = %X \n", read_size); + DNLD_DEBUG(" FW_DNLD: Already Read, Read Ignored, read_size = %X \n", read_size); + } + else + { + /* Ignore the Read */ + DNLD_DEBUG(" FW_DNLD: Section Read Status = %X \n", p_sec_info->section_read); + DNLD_DEBUG(" FW_DNLD: Section Write Status = %X \n", p_sec_info->section_write); + DNLD_DEBUG(" FW_DNLD: No Read Required, Read_size = %X \n", read_size); } } @@ -1185,9 +1229,7 @@ phDnldNfc_Process_Write( static unsigned sec_type = 0; uint8_t i = 0; uint16_t dnld_size = 0; -#ifdef FW_DOWNLOAD_VERIFY - int cmp_val = 0x00; -#endif /* #ifdef FW_DOWNLOAD_VERIFY */ + int cmp_val = 0x00; sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type; @@ -1197,27 +1239,38 @@ phDnldNfc_Process_Write( { if( (TRUE == p_sec_info->trim_write) && (TRUE == p_sec_info->section_read) + && (TRUE == ((section_type_t *)(&sec_type))->verify_mem ) ) { -#ifdef FW_DOWNLOAD_VERIFY if(NULL != psDnldContext->trim_store.buffer) { + uint32_t trim_cmp_size = psDnldContext->prev_dnld_size; + + if( p_sec_info->p_sec_hdr->section_address + < (DNLD_CFG_PG_ADDR + PHDNLD_PAGE_SIZE) ) + { + trim_cmp_size = trim_cmp_size - 2; + } + /* Below Comparison fails due to the checksum */ cmp_val = phOsalNfc_MemCompare( psDnldContext->trim_store.buffer, &psDnldContext->dnld_resp. param_info.response_data[0] - ,psDnldContext->prev_dnld_size); + ,trim_cmp_size); + DNLD_DEBUG(" FW_DNLD: %X Bytes Trim Write Complete ", + psDnldContext->prev_dnld_size); + DNLD_DEBUG(" Comparison Status %X\n", cmp_val); } -#endif /* #ifdef FW_DOWNLOAD_VERIFY */ p_sec_info->trim_write = FALSE; DNLD_DEBUG(" FW_DNLD: TRIMMED %X Bytes Write Complete\n", psDnldContext->prev_dnld_size); } else { -#ifdef FW_DOWNLOAD_VERIFY if((NULL != psDnldContext->dnld_store.buffer) && (TRUE == ((section_type_t *)(&sec_type))->verify_mem ) + && (TRUE == p_sec_info->section_write) + && (TRUE == p_sec_info->section_read) ) { cmp_val = phOsalNfc_MemCompare( @@ -1225,18 +1278,26 @@ phDnldNfc_Process_Write( &psDnldContext->dnld_resp. param_info.response_data[0] ,psDnldContext->dnld_store.length); + p_sec_info->section_read = FALSE; + p_sec_info->section_write = FALSE; DNLD_DEBUG(" FW_DNLD: %X Bytes Write Complete ", psDnldContext->dnld_store.length); DNLD_DEBUG(" Comparison Status %X\n", cmp_val); } -#endif /* #ifdef FW_DOWNLOAD_VERIFY */ + else + { + if(( TRUE == p_sec_info->section_write) + && ( FALSE == p_sec_info->section_read) + ) + { + p_sec_info->section_write = FALSE; + } + } /* p_sec_info->section_read = FALSE; */ } if (( 0 == psDnldContext->dnld_retry ) -#ifdef FW_DOWNLOAD_VERIFY && (0 == cmp_val) -#endif ) { p_sec_info->sec_verify_retry = 0; @@ -1296,9 +1357,17 @@ phDnldNfc_Process_Write( dnld_data->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK); (void)memcpy( dnld_data->data_packet, - (p_sec_info->p_sec_data + *p_sec_offset), dnld_size ); + (p_sec_info->p_sec_data + *p_sec_offset), dnld_size ); if((TRUE == ((section_type_t *)(&sec_type))->trim_val ) + && (p_sec_info->sec_verify_retry != 0) + && (NULL != psDnldContext->trim_store.buffer) + ) + { + (void)memcpy( dnld_data->data_packet, + psDnldContext->trim_store.buffer, dnld_size ); + } + else if((TRUE == ((section_type_t *)(&sec_type))->trim_val ) && ( TRUE == p_sec_info->section_read ) ) { @@ -1388,10 +1457,11 @@ else status = phDnldNfc_Send_Command( psDnldContext, pHwRef, PHDNLD_CMD_WRITE, NULL , 0 ); - DNLD_DEBUG(" : Memory Write Status = %X \n", status); + DNLD_DEBUG(" FW_DNLD: Memory Write Status = %X \n", status); if ( NFCSTATUS_PENDING == status ) { psDnldContext->prev_dnld_size = dnld_size; + cmp_val = 0x00; if(TRUE == ((section_type_t *)(&sec_type))->trim_val ) { p_sec_info->trim_write = TRUE; @@ -1400,6 +1470,7 @@ else } else { + p_sec_info->section_write = TRUE; DNLD_DEBUG(" FW_DNLD: Bytes Downloaded = %X : ", (*p_sec_offset + dnld_size)); DNLD_DEBUG(" Bytes Remaining = %X \n", @@ -1440,6 +1511,7 @@ phDnldNfc_Resume_Write( p_sec_info->section_offset = 0; p_sec_info->section_read = FALSE; + p_sec_info->section_write = FALSE; p_sec_info->trim_write = FALSE; DNLD_DEBUG(" FW_DNLD: Section %02X Download Complete\n", sec_index); @@ -1452,7 +1524,36 @@ phDnldNfc_Resume_Write( DNLD_PRINT("*******************************************\n\n"); sec_index++; + +#ifdef NXP_FW_DNLD_CHECK_PHASE + if( p_sec_info->p_sec_hdr->section_address + < (DNLD_CFG_PG_ADDR + PHDNLD_PAGE_SIZE) ) + { + gphDnldPhase = NXP_FW_DNLD_DATA_PHASE; + + } + p_sec_info = (psDnldContext->p_fw_sec + sec_index); + + if( (sec_index < psDnldContext->p_fw_hdr->no_of_sections) + && ( p_sec_info->p_sec_hdr->section_address + < (DNLD_CFG_PG_ADDR + PHDNLD_PAGE_SIZE) ) + ) + { + if( NXP_FW_DNLD_CFG_PHASE >= gphDnldPhase ) + { + gphDnldPhase = NXP_FW_DNLD_CFG_PHASE; + } + else + { + sec_index++; + p_sec_info = (psDnldContext->p_fw_sec + sec_index); + } + } +#else + p_sec_info = (psDnldContext->p_fw_sec + sec_index); +#endif /* #ifdef NXP_FW_DNLD_CHECK_PHASE */ + psDnldContext->section_index = sec_index; /* psDnldContext->next_dnld_state = (uint8_t) phDnld_Upgrade_State; */ } @@ -1548,6 +1649,32 @@ phDnldNfc_Sequence( break; } + case phDnld_Activate_Patch: + { + uint8_t patch_activate = 0x01; + psDnldContext->next_dnld_seq = + (uint8_t)phDnld_Update_Patch; +#ifdef NXP_FW_DNLD_CHECK_PHASE + gphDnldPhase = NXP_FW_DNLD_SYSTEM_PHASE; +#endif /* NXP_FW_DNLD_CHECK_PHASE */ + + status = phDnldNfc_Send_Command( psDnldContext, pHwRef, + PHDNLD_CMD_ACTIVATE_PATCH , &patch_activate, sizeof(patch_activate) ); + DNLD_PRINT(" FW_DNLD: Activate the Patch Update .... \n"); + break; + } + case phDnld_Deactivate_Patch: + { + uint8_t patch_activate = 0x00; + + psDnldContext->next_dnld_state = + (uint8_t)phDnld_Reset_State; + + status = phDnldNfc_Send_Command( psDnldContext, pHwRef, + PHDNLD_CMD_ACTIVATE_PATCH , &patch_activate, sizeof(patch_activate) ); + DNLD_PRINT(" FW_DNLD: Deactivate the Patch Update .... \n"); + break; + } case phDnld_Update_Patch: { dnld_addr = NXP_DNLD_PATCH_ADDR; @@ -1575,8 +1702,14 @@ phDnldNfc_Sequence( dnld_addr = NXP_DNLD_SM_UNLOCK_ADDR; patch_size = sizeof(unlock_data) ; p_data = unlock_data; +#define NXP_FW_PATCH_DISABLE +#ifdef NXP_FW_PATCH_DISABLE + psDnldContext->next_dnld_seq = + (uint8_t)phDnld_Deactivate_Patch; +#else psDnldContext->next_dnld_state = (uint8_t)phDnld_Reset_State; +#endif DNLD_PRINT(" FW_DNLD: System Memory Unlock Seq.... \n"); break; @@ -1690,7 +1823,7 @@ phDnldNfc_Resume( NFCSTATUS status = NFCSTATUS_SUCCESS; phDnldNfc_eState_t dnld_next_state = (phDnldNfc_eState_t) psDnldContext->cur_dnld_state; - phNfc_sCompletionInfo_t comp_info = {0}; + phNfc_sCompletionInfo_t comp_info = {0,0,0}; switch( dnld_next_state ) { @@ -1708,27 +1841,34 @@ phDnldNfc_Resume( (uint8_t)phDnld_Unlock_System; break; } +#ifdef NXP_FW_PATCH_DISABLE + case phDnld_Deactivate_Patch: +#else case phDnld_Unlock_System: +#endif { psDnldContext->next_dnld_state = (uint8_t)phDnld_Upgrade_State; psDnldContext->next_dnld_seq = (uint8_t)phDnld_Upgrade_Section; +#ifdef NXP_FW_DNLD_CHECK_PHASE + gphDnldPhase = NXP_FW_DNLD_CFG_PHASE; +#endif /* NXP_FW_DNLD_CHECK_PHASE */ break; } case phDnld_Lock_System: { -//#if(NXP_FW_INTEGRITY_CHK >= 0x01) -// psDnldContext->next_dnld_state = -// (uint8_t)phDnld_Verify_State; -// psDnldContext->next_dnld_seq = -// (uint8_t)phDnld_Verify_Integrity; -//#else +#if (NXP_FW_INTEGRITY_CHK >= 0x01) + psDnldContext->next_dnld_state = + (uint8_t)phDnld_Verify_State; + psDnldContext->next_dnld_seq = + (uint8_t)phDnld_Verify_Integrity; +#else /* (void ) memset( (void *) &psDnldContext->chk_integrity_crc, 0, sizeof(psDnldContext->chk_integrity_crc)); */ psDnldContext->next_dnld_state = (uint8_t) phDnld_Complete_State; -//#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ +#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ break; } case phDnld_Verify_Integrity: @@ -1766,21 +1906,21 @@ phDnldNfc_Resume( psDnldContext->next_dnld_seq = psDnldContext->cur_dnld_seq; #endif -//#if (NXP_FW_INTEGRITY_CHK >= 0x01) -// psDnldContext->next_dnld_state = -// (uint8_t)phDnld_Verify_State; -// psDnldContext->next_dnld_seq = -// (uint8_t)phDnld_Verify_Integrity; -// psDnldContext->cur_dnld_seq = -// psDnldContext->next_dnld_seq; -// status = phDnldNfc_Sequence( psDnldContext, -// pHwRef, pdata, length); -//#else +#if (NXP_FW_INTEGRITY_CHK >= 0x01) + psDnldContext->next_dnld_state = + (uint8_t)phDnld_Verify_State; + psDnldContext->next_dnld_seq = + (uint8_t)phDnld_Verify_Integrity; + psDnldContext->cur_dnld_seq = + psDnldContext->next_dnld_seq; + status = phDnldNfc_Sequence( psDnldContext, + pHwRef, pdata, length); +#else /* (void ) memset( (void *) &psDnldContext->chk_integrity_crc, 0, sizeof(psDnldContext->chk_integrity_crc)); */ psDnldContext->next_dnld_state = (uint8_t) phDnld_Complete_State; -//#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ +#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ } break; } @@ -1811,7 +1951,7 @@ phDnldNfc_Resume( { if (crc_i < DNLD_CRC16_SIZE ) { - patch_table_crc = patch_table_crc + patch_table_crc = patch_table_crc | psDnldContext->chk_integrity_crc.patch_table.Chk_Crc16[crc_i] << (crc_i * BYTE_SIZE) ; } @@ -1960,7 +2100,7 @@ phDnldNfc_Receive_Complete ( void *pdata = NULL ; phDnldNfc_sData_Hdr_t *resp_data = NULL; uint16_t length = 0 ; - phNfc_sCompletionInfo_t comp_info = {0}; + phNfc_sCompletionInfo_t comp_info = {0,0,0}; DNLD_PRINT("\n FW_DNLD: Receive Response .... "); if ( (NULL != psContext) @@ -2213,6 +2353,11 @@ phDnldNfc_Send_Complete ( { psDnldContext->resp_length = 0; psDnldContext->dnld_retry = 0; + /* clock unstable after SW reset command, especially on UART + * platform because of its sensitivity to clock. Experimentally + * we found clock unstable for 750us. Delay for 5ms to be sure. + */ + usleep(5000); status = phDnldNfc_Set_Seq(psDnldContext, DNLD_SEQ_UPDATE); } @@ -2305,8 +2450,18 @@ phDnldNfc_Send_Command( } case PHDNLD_CMD_ACTIVATE_PATCH: { - tx_length++; psDnldContext->resp_length = PHDNLD_MIN_PACKET; + if ((NULL != params) && ( param_length > 0 )) + { + psDnldContext->dnld_data.param_info.cmd_param = + (*(uint8_t *)params); + tx_length = param_length; + } + else + { + psDnldContext->dnld_data.param_info.cmd_param = FALSE; + tx_length++; + } break; } case PHDNLD_CMD_CHECK_INTEGRITY: @@ -2316,14 +2471,14 @@ phDnldNfc_Send_Command( { psDnldContext->chk_integrity_param = (phDnldNfc_eChkCrc_t)(*(uint8_t *)params); - tx_length = param_length ; + tx_length = param_length; } else { psDnldContext->chk_integrity_param = CHK_INTEGRITY_COMPLETE_CRC; tx_length++; } - psDnldContext->dnld_data.param_info.config_verify_param = + psDnldContext->dnld_data.param_info.cmd_param = (uint8_t) psDnldContext->chk_integrity_param; switch(psDnldContext->chk_integrity_param) { @@ -2351,7 +2506,7 @@ phDnldNfc_Send_Command( } #else tx_length++; - psDnldContext->dnld_data.param_info.config_verify_param = + psDnldContext->dnld_data.param_info.cmd_param = (uint8_t) CHK_INTEGRITY_COMPLETE_CRC; #endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */ @@ -2378,6 +2533,9 @@ phDnldNfc_Send_Command( if(NFCSTATUS_PENDING == status) { psDnldContext->prev_cmd = cmd; + + if( PHDNLD_CMD_RESET == cmd ) + DO_DELAY(PHDNLD_DNLD_DELAY); //this seems like its on the wrong thread } } @@ -2385,6 +2543,7 @@ phDnldNfc_Send_Command( return status; } + static NFCSTATUS phDnldNfc_Process_FW( @@ -2648,12 +2807,12 @@ phDnldNfc_Run_Check( STATIC void phDnldNfc_Abort ( - uint32_t abort_id , - void * pContext + uint32_t abort_id, + void *pContext ) { - phNfc_sCompletionInfo_t comp_info = {0}; + phNfc_sCompletionInfo_t comp_info = {0,0,0}; if ( ( NULL != gpphDnldContext) && (abort_id == gpphDnldContext->timer_id )) @@ -2694,7 +2853,7 @@ phDnldNfc_Upgrade ( ) { phDnldNfc_sContext_t *psDnldContext = NULL; - phNfcIF_sReference_t dnldReference = { NULL }; + phNfcIF_sReference_t dnldReference = { NULL,0,0 }; phNfcIF_sCallBack_t if_callback = { NULL, NULL, NULL, NULL }; phNfc_sLowerIF_t *plower_if = NULL; NFCSTATUS status = NFCSTATUS_SUCCESS; @@ -2795,6 +2954,7 @@ phDnldNfc_Upgrade ( */ status = phDnldNfc_Send_Command( psDnldContext, pHwRef, PHDNLD_CMD_RESET , NULL , 0 ); + if (NFCSTATUS_PENDING == status) { DNLD_PRINT("\n FW_DNLD: Integrity Reset .... \n"); @@ -2836,9 +2996,3 @@ phDnldNfc_Upgrade ( return status; } - - - - - - diff --git a/src/phFriNfc_FelicaMap.c b/src/phFriNfc_FelicaMap.c index 2604649..8a810f9 100644 --- a/src/phFriNfc_FelicaMap.c +++ b/src/phFriNfc_FelicaMap.c @@ -57,13 +57,10 @@ static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer, uint8_t EndIndex, uint16_t RecvChkSum); -#ifndef PH_HAL4_ENABLE /* Helpers for Poll Related Operations*/ static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, const uint8_t sysCode[], uint8_t state); -#endif /* #ifndef PH_HAL4_ENABLE */ - static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap); @@ -2118,39 +2115,65 @@ static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap) NFCSTATUS phFriNfc_Felica_ChkNdef( phFriNfc_NdefMap_t *NdefMap) { NFCSTATUS status = NFCSTATUS_PENDING; - -#ifndef PH_HAL4_ENABLE uint8_t sysCode[2]; -#endif /* #ifndef PH_HAL4_ENABLE */ -#ifdef PH_HAL4_ENABLE - - /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/ - status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap); - - if (status == NFCSTATUS_SUCCESS) - { - - /* set the operation type to Check ndef type*/ - NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP; - status = phFriNfc_Felica_HRdAttrInfo(NdefMap); - } -#else - /* set the system code for selecting the wild card*/ sysCode[0] = 0x12; sysCode[1] = 0xFC; status = phFriNfc_Felica_HPollCard( NdefMap,sysCode,PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP); -#endif /* #ifdef PH_HAL4_ENABLE */ return (status); } /*! * \brief Check whether a particular Remote Device is NDEF compliant. - * selects the wild card and then NFC Forum Reference Applications + * selects the sysCode and then NFC Forum Reference Applications */ +#ifdef PH_HAL4_ENABLE +static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, + const uint8_t sysCode[], + uint8_t state) +{ + NFCSTATUS status = NFCSTATUS_PENDING; + + /*Format the Poll Packet for selecting the system code passed as parameter */ + NdefMap->SendRecvBuf[0] = 0x06; + NdefMap->SendRecvBuf[1] = 0x00; + NdefMap->SendRecvBuf[2] = sysCode[0]; + NdefMap->SendRecvBuf[3] = sysCode[1]; + NdefMap->SendRecvBuf[4] = 0x01; + NdefMap->SendRecvBuf[5] = 0x03; + + NdefMap->SendLength = 6; + + /*set the completion routines for the felica card operations*/ + NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process; + NdefMap->MapCompletionInfo.Context = NdefMap; + + /*Set Ndef State*/ + NdefMap->State = state; + + /* set the felica cmd */ + NdefMap->Cmd.FelCmd = phHal_eFelica_Raw; + + /*set the additional informations for the data exchange*/ + NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0; + NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0; + + status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice, + &NdefMap->MapCompletionInfo, + NdefMap->psRemoteDevInfo, + NdefMap->Cmd, + &NdefMap->psDepAdditionalInfo, + NdefMap->SendRecvBuf, + NdefMap->SendLength, + NdefMap->SendRecvBuf, + NdefMap->SendRecvLength); + return (status); +} +#endif + #ifndef PH_HAL4_ENABLE static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap, @@ -2210,50 +2233,45 @@ static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_ { NFCSTATUS status = NFCSTATUS_PENDING; -#ifdef PH_HAL4_ENABLE - /* copy the IDm and PMm in Manufacture Details Structure*/ - (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), - (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, - 8); - (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), - (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm, - 8); - status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); -#else - - - /* Check the System Code for 0x12,0xFC*/ - if( (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCodeAvailable == 1) - && (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCode[0] == 0x12) - && (NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.SystemCode[1] == 0xFC)) + /* Get the details from Poll Response packet */ + if (NdefMap->SendRecvLength >= 20) { - - /* copy the IDm and PMm in Manufacture Details Structure*/ - (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), - (uint8_t *)NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t, - 8); - (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), - (uint8_t *)NdefMap->FelicaPollDetails.psTempRemoteDevInfo.RemoteDevInfo.CardInfo212_424.Startup212_424.PMm, - 8); - + (void)memcpy( (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, + (uint8_t *)&NdefMap->SendRecvBuf[2], 8); + (void)memcpy( (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm, + (uint8_t *)&NdefMap->SendRecvBuf[10], 8); + NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] = NdefMap->SendRecvBuf[18]; + NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] = NdefMap->SendRecvBuf[19]; + NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength = 8; - status = PHNFCSTVAL(CID_NFC_NONE, - NFCSTATUS_SUCCESS); - + /* copy the IDm and PMm in Manufacture Details Structure*/ + (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID), + (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm, + 8); + (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter), + (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm, + 8); + if((NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] == 0x12) + && (NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] == 0xFC)) + { + status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS); + } + else + { + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); + } } else { - status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, - NFCSTATUS_NO_NDEF_SUPPORT); + status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, + NFCSTATUS_NO_NDEF_SUPPORT); } -#endif /* #ifdef PH_HAL4_ENABLE */ - - return (status); + return (status); } - /*! * \brief Completion Routine, Processing function, needed to avoid long blocking. * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion diff --git a/src/phFriNfc_ISO15693Format.c b/src/phFriNfc_ISO15693Format.c index 574c107..077035e 100644 --- a/src/phFriNfc_ISO15693Format.c +++ b/src/phFriNfc_ISO15693Format.c @@ -1,5 +1,5 @@ /* -/* + * * Copyright (C) 2010 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -112,7 +112,7 @@ CC BYTE 0 - Magic Number - 0xE1 typedef enum phFriNfc_ISO15693_FormatSeq { ISO15693_GET_SYS_INFO, - ISO15693_RD_MULTIPLE_BLKS_CHECK, + ISO15693_RD_SINGLE_BLK_CHECK, ISO15693_WRITE_CC_FMT, ISO15693_WRITE_NDEF_TLV }phFriNfc_ISO15693_FormatSeq_t; @@ -351,27 +351,12 @@ phFriNfc_ISO15693_H_ProFormat ( (uint8_t)(*psNdefSmtCrdFmt->SendRecvLength - ISO15693_EXTRA_RESPONSE_FLAG))) { - /* Send the READ MULTIPLE BLOCKS COMMAND */ - command_type = ISO15693_RD_MULTIPLE_BLKS_CMD; - e_format_seq = ISO15693_RD_MULTIPLE_BLKS_CHECK; + /* Send the READ SINGLE BLOCK COMMAND */ + command_type = ISO15693_RD_SINGLE_BLK_CMD; + e_format_seq = ISO15693_RD_SINGLE_BLK_CHECK; - /* Prepare data for the command, - First add the current block */ - *a_send_byte = (uint8_t)ps_iso15693_info->current_block; - send_index = (uint8_t)(send_index + 1); - - /* Second, add number of blocks to read, here 2 blocks means - 8 bytes. 1 is decremented because to read multiple block. - the first block is read by default, apart from the first block, - next block shall be read, that means remaining block to read is 1 - So, if for eg: 2 blocks needs to be read from block number 0, then 1 - is number of blocks to read. This will read both block 0 and 1 - */ - *(a_send_byte + send_index) = (uint8_t) - (ISO15693_RD_2_BLOCKS - 1); - send_index = (uint8_t)(send_index + 1); - - send_length = send_index; + /* Block number 0 to read */ + psNdefSmtCrdFmt->AddInfo.s_iso15693_info.current_block = 0x00; } else { @@ -381,67 +366,76 @@ phFriNfc_ISO15693_H_ProFormat ( break; } - case ISO15693_RD_MULTIPLE_BLKS_CHECK: + case ISO15693_RD_SINGLE_BLK_CHECK: { - /* RESPONSE received for READ MULTIPLE BLOCKS - received, prepare data for writing CC bytes */ - - command_type = ISO15693_WR_SINGLE_BLK_CMD; - e_format_seq = ISO15693_WRITE_CC_FMT; + /* RESPONSE received for READ SINGLE BLOCK + received*/ - /* CC magic number */ - *a_send_byte = (uint8_t)ISO15693_CC_MAGIC_NUM; - send_index = (uint8_t)(send_index + 1); + /* Check if Card is really fresh + First 4 bytes must be 0 for fresh card */ - /* CC Version and read/write access */ - *(a_send_byte + send_index) = (uint8_t) - ISO15693_CC_VER_RW; - send_index = (uint8_t)(send_index + 1); + if ((psNdefSmtCrdFmt->AddInfo.s_iso15693_info.current_block == 0x00) && + (psNdefSmtCrdFmt->SendRecvBuf[1] != 0x00 || + psNdefSmtCrdFmt->SendRecvBuf[2] != 0x00 || + psNdefSmtCrdFmt->SendRecvBuf[3] != 0x00 || + psNdefSmtCrdFmt->SendRecvBuf[4] != 0x00)) + { + result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_FORMAT); + } + else + { + /* prepare data for writing CC bytes */ - /* CC MAX data size, calculated during GET system information */ - *(a_send_byte + send_index) = (uint8_t) - (ps_iso15693_info->max_data_size / - ISO15693_CC_MULTIPLE_FACTOR); - send_index = (uint8_t)(send_index + 1); + command_type = ISO15693_WR_SINGLE_BLK_CMD; + e_format_seq = ISO15693_WRITE_CC_FMT; - switch (ps_iso15693_info->max_data_size) - { - case ISO15693_SLI_X_MAX_SIZE: - { - /* For SLI tags : Inventory Page read not supported */ - *(a_send_byte + send_index) = (uint8_t) - ISO15693_RDMULBLKS_CMD_MASK; - break; - } + /* CC magic number */ + *a_send_byte = (uint8_t)ISO15693_CC_MAGIC_NUM; + send_index = (uint8_t)(send_index + 1); - case ISO15693_SLI_X_S_MAX_SIZE: - { - /* For SLI - S tags : Read multiple blocks not supported */ - *(a_send_byte + send_index) = (uint8_t) - ISO15693_INVENTORY_CMD_MASK; - break; - } + /* CC Version and read/write access */ + *(a_send_byte + send_index) = (uint8_t) ISO15693_CC_VER_RW; + send_index = (uint8_t)(send_index + 1); - case ISO15693_SLI_X_L_MAX_SIZE: - { - /* For SLI - L tags : Read multiple blocks not supported */ - *(a_send_byte + send_index) = (uint8_t) - ISO15693_INVENTORY_CMD_MASK; - break; - } + /* CC MAX data size, calculated during GET system information */ + *(a_send_byte + send_index) = (uint8_t) (ps_iso15693_info->max_data_size / ISO15693_CC_MULTIPLE_FACTOR); + send_index = (uint8_t)(send_index + 1); - default: + switch (ps_iso15693_info->max_data_size) { - result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, - NFCSTATUS_INVALID_DEVICE_REQUEST); - break; + case ISO15693_SLI_X_MAX_SIZE: + { + /* For SLI tags : Inventory Page read not supported */ + *(a_send_byte + send_index) = (uint8_t) ISO15693_RDMULBLKS_CMD_MASK; + break; + } + + case ISO15693_SLI_X_S_MAX_SIZE: + { + /* For SLI - S tags : Read multiple blocks not supported */ + *(a_send_byte + send_index) = (uint8_t) ISO15693_INVENTORY_CMD_MASK; + break; + } + + case ISO15693_SLI_X_L_MAX_SIZE: + { + /* For SLI - L tags : Read multiple blocks not supported */ + *(a_send_byte + send_index) = (uint8_t) ISO15693_INVENTORY_CMD_MASK; + break; + } + + default: + { + result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST); + break; + } } + + send_index = (uint8_t)(send_index + 1); + + send_length = sizeof (a_send_byte); } - - send_index = (uint8_t)(send_index + 1); - send_length = sizeof (a_send_byte); - break; } @@ -568,16 +562,8 @@ phFriNfc_ISO15693_FmtProcess ( } else { - if (ISO15693_RD_MULTIPLE_BLKS_CHECK == - (phFriNfc_ISO15693_FormatSeq_t)ps_iso15693_info->format_seq) - { - /* If READ MULTIPLE BLOCKS is not working then - do further formatting, disable the READ MULTIPLE BLOCK - flag in the CC 4th byte, this says that COMMAND is not - supported and dont use this command - */ - Status = phFriNfc_ISO15693_H_ProFormat (psNdefSmtCrdFmt); - } + Status = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, + NFCSTATUS_FORMAT_ERROR); } /* Handle the all the error cases */ diff --git a/src/phFriNfc_ISO15693Map.c b/src/phFriNfc_ISO15693Map.c index f07b1bf..a21d9c8 100644 --- a/src/phFriNfc_ISO15693Map.c +++ b/src/phFriNfc_ISO15693Map.c @@ -1,5 +1,5 @@ /* -/* + * * Copyright (C) 2010 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/phFriNfc_ISO15693Map.h b/src/phFriNfc_ISO15693Map.h index 596534a..f4c0c08 100644 --- a/src/phFriNfc_ISO15693Map.h +++ b/src/phFriNfc_ISO15693Map.h @@ -1,5 +1,5 @@ /* -/* + * * Copyright (C) 2010 NXP Semiconductors * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/phFriNfc_Llcp.c b/src/phFriNfc_Llcp.c index ac38311..2a4fcb4 100644 --- a/src/phFriNfc_Llcp.c +++ b/src/phFriNfc_Llcp.c @@ -196,24 +196,11 @@ static NFCSTATUS phFriNfc_Llcp_InternalDeactivate( phFriNfc_Llcp_t *Llcp ) static NFCSTATUS phFriNfc_Llcp_SendSymm( phFriNfc_Llcp_t *Llcp ) { phFriNfc_Llcp_sPacketHeader_t sHeader; - bool_t bPendingFlag; - /* Check for pending messages to send */ - bPendingFlag = phFriNfc_Llcp_HandlePendingSend(Llcp); - - if (bPendingFlag == FALSE) - { - /* No send pending, send a SYMM instead */ - sHeader.dsap = PHFRINFC_LLCP_SAP_LINK; - sHeader.ssap = PHFRINFC_LLCP_SAP_LINK; - sHeader.ptype = PHFRINFC_LLCP_PTYPE_SYMM; - return phFriNfc_Llcp_InternalSend(Llcp, &sHeader, NULL, NULL); - } - else - { - /* A pending send has been sent, there is no need to send SYMM */ - return NFCSTATUS_SUCCESS; - } + sHeader.dsap = PHFRINFC_LLCP_SAP_LINK; + sHeader.ssap = PHFRINFC_LLCP_SAP_LINK; + sHeader.ptype = PHFRINFC_LLCP_PTYPE_SYMM; + return phFriNfc_Llcp_InternalSend(Llcp, &sHeader, NULL, NULL); } @@ -423,7 +410,7 @@ static NFCSTATUS phFriNfc_Llcp_ParseLinkParams( phNfc_sData_t break; } /* Get MIU */ - sParams.miu = PHFRINFC_LLCP_MIU_DEFAULT + ((sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1]) & PHFRINFC_LLCP_TLV_MIUX_MASK; + sParams.miu = (PHFRINFC_LLCP_MIU_DEFAULT + ((sValueBuffer.buffer[0] << 8) | sValueBuffer.buffer[1])) & PHFRINFC_LLCP_TLV_MIUX_MASK; break; } case PHFRINFC_LLCP_TLV_TYPE_WKS: @@ -675,7 +662,7 @@ static void phFriNfc_Llcp_ChkLlcp_CB( void *pContext, static void phFriNfc_Llcp_LinkStatus_CB( void *pContext, phFriNfc_LlcpMac_eLinkStatus_t eLinkStatus, phNfc_sData_t *psParamsTLV, - phFriNfc_LlcpMac_eType_t PeerRemoteDevType) + phFriNfc_LlcpMac_ePeerType_t PeerRemoteDevType) { NFCSTATUS status; @@ -759,6 +746,8 @@ static void phFriNfc_Llcp_ResetLTO( phFriNfc_Llcp_t *Llcp ) nDuration = (Llcp->sLocalParams.lto * 10) / 2; } + LLCP_DEBUG("Starting LLCP timer with duration %d", nDuration); + /* Restart timer */ phOsalNfc_Timer_Start( Llcp->hSymmTimer, @@ -915,6 +904,11 @@ static bool_t phFriNfc_Llcp_HandlePendingSend ( phFriNfc_Llcp_t *Llcp ) phFriNfc_Llcp_InternalDeactivate(Llcp); } return_value = TRUE; + } else if (Llcp->pfSendCB == NULL) { + // Nothing to send, send SYMM instead to allow peer to send something + // if it wants. + phFriNfc_Llcp_SendSymm(Llcp); + return_value = TRUE; } clean_and_return: @@ -1441,6 +1435,10 @@ NFCSTATUS phFriNfc_Llcp_Send( phFriNfc_Llcp_t *Llcp, /* Incorrect state for sending ! */ result = PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_STATE);; } + + if (result != NFCSTATUS_PENDING) { + Llcp->pfSendCB = NULL; + } return result; } diff --git a/src/phFriNfc_Llcp.h b/src/phFriNfc_Llcp.h index 73fa486..287f9f9 100644 --- a/src/phFriNfc_Llcp.h +++ b/src/phFriNfc_Llcp.h @@ -117,6 +117,7 @@ extern char phOsalNfc_DbgTraceBuffer[]; /*@{*/ #define PHFRINFC_LLCP_SAP_LINK 0x00 /**< Link SAP.*/ #define PHFRINFC_LLCP_SAP_SDP 0x01 /**< Service Discovery Protocol SAP.*/ +#define PHFRINFC_LLCP_SAP_WKS_FIRST 0x02 /**< Other Well-Known Services defined by the NFC Forum.*/ #define PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST 0x10 /**< First SAP number from SDP-avertised SAP range.*/ #define PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST 0x20 /**< First SAP number from SDP-unavertised SAP range.*/ #define PHFRINFC_LLCP_SAP_NUMBER 0x40 /**< Number of possible SAP values (also first invalid value).*/ @@ -289,7 +290,7 @@ typedef struct phFriNfc_Llcp phFriNfc_LlcpMac_t MAC; /**< Local LLC role*/ - phFriNfc_LlcpMac_eType_t eRole; + phFriNfc_LlcpMac_ePeerType_t eRole; /**< Local link parameters*/ phFriNfc_Llcp_sLinkParameters_t sLocalParams; diff --git a/src/phFriNfc_LlcpTransport.c b/src/phFriNfc_LlcpTransport.c index 130564d..960a33a 100644 --- a/src/phFriNfc_LlcpTransport.c +++ b/src/phFriNfc_LlcpTransport.c @@ -32,6 +32,44 @@ #include <phFriNfc_LlcpTransport_Connectionless.h> #include <phFriNfc_LlcpTransport_Connection.h> +/* local macros */ + +/* Check if (a <= x < b) */ +#define IS_BETWEEN(x, a, b) (((x)>=(a)) && ((x)<(b))) + + +static NFCSTATUS phFriNfc_LlcpTransport_AutoBind(phFriNfc_LlcpTransport_Socket_t *pSocket) +{ + uint8_t i; + uint8_t sap; + phFriNfc_LlcpTransport_Socket_t* pSocketTable = pSocket->psTransport->pSocketTable; + + /* Try all possible SAPs */ + for(sap=PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST ; sap<PHFRINFC_LLCP_SAP_NUMBER ; sap++) + { + /* Go through socket list to check if current SAP is in use */ + for(i=0 ; i<PHFRINFC_LLCP_NB_SOCKET_MAX ; i++) + { + if((pSocketTable[i].eSocket_State >= phFriNfc_LlcpTransportSocket_eSocketBound) && + (pSocketTable[i].socket_sSap == sap)) + { + /* SAP is already in use */ + break; + } + } + + if (i >= PHFRINFC_LLCP_NB_SOCKET_MAX) + { + /* No socket is using current SAP, proceed with binding */ + pSocket->socket_sSap = sap; + pSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound; + return NFCSTATUS_SUCCESS; + } + } + + /* If we reach this point, it means that no SAP is free */ + return NFCSTATUS_INSUFFICIENT_RESOURCES; +} /* TODO: comment function Transport recv CB */ static void phFriNfc_LlcpTransport__Recv_CB(void *pContext, @@ -227,6 +265,7 @@ NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransp case phFriNfc_LlcpTransportSocket_eSocketRejected: phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]); break; + default: break; } } else @@ -234,7 +273,6 @@ NFCSTATUS phFriNfc_LlcpTransport_CloseAll (phFriNfc_LlcpTransport_t *pLlcpTransp phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]); } } - return status; } @@ -644,6 +682,20 @@ NFCSTATUS phFriNfc_LlcpTransport_Listen(phFriNfc_LlcpTransport_Socket_t* { status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); } + /* Test the SAP range for SDP-advertised services */ + else if((psServiceName->length > 0) && + (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST)) && + (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST))) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + } + /* Test the SAP range for non SDP-advertised services */ + else if((psServiceName->length == 0) && + (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER)) && + (!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_WKS_FIRST, PHFRINFC_LLCP_SAP_SDP_ADVERTISED_FIRST))) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + } else { status = phFriNfc_LlcpTransport_ConnectionOriented_Listen(pLlcpSocket, @@ -835,26 +887,29 @@ NFCSTATUS phFriNfc_LlcpTransport_Connect( phFriNfc_LlcpTransport_Socket_t* } else { + /* Implicit bind if socket is not already bound */ if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound) { - /* Bind with a sSap Free */ - pLlcpSocket->socket_sSap = 32; - - for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++) + status = phFriNfc_LlcpTransport_AutoBind(pLlcpSocket); + if (status != NFCSTATUS_SUCCESS) { - if(pLlcpSocket->socket_sSap == pLlcpSocket->psTransport->pSocketTable[i].socket_sSap) - { - pLlcpSocket->socket_sSap++; - } + return status; } } - pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketBound; - status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket, - nSap, - NULL, - pConnect_RspCb, - pContext); + /* Test the SAP range for non SDP-advertised services */ + if(!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER)) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + } + else + { + status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket, + nSap, + NULL, + pConnect_RspCb, + pContext); + } } return status; @@ -915,24 +970,29 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectByUri(phFriNfc_LlcpTransport_Socket_t* } else { + /* Implicit bind if socket is not already bound */ if(pLlcpSocket->eSocket_State != phFriNfc_LlcpTransportSocket_eSocketBound) { - /* Bind with a sSap Free */ - pLlcpSocket->socket_sSap = 32; - - for(i=0;i<PHFRINFC_LLCP_NB_SOCKET_MAX;i++) + status = phFriNfc_LlcpTransport_AutoBind(pLlcpSocket); + if (status != NFCSTATUS_SUCCESS) { - if(pLlcpSocket->socket_sSap == pLlcpSocket->psTransport->pSocketTable[i].socket_sSap) - { - pLlcpSocket->socket_sSap++; - } + return status; } } - status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket, - PHFRINFC_LLCP_SAP_DEFAULT, - psUri, - pConnect_RspCb, - pContext); + + /* Test the SAP range for non SDP-advertised services */ + if(!IS_BETWEEN(pLlcpSocket->socket_sSap, PHFRINFC_LLCP_SAP_SDP_UNADVERTISED_FIRST, PHFRINFC_LLCP_SAP_NUMBER)) + { + status = PHNFCSTVAL(CID_FRI_NFC_LLCP_TRANSPORT, NFCSTATUS_INVALID_PARAMETER); + } + else + { + status = phFriNfc_LlcpTransport_ConnectionOriented_Connect(pLlcpSocket, + PHFRINFC_LLCP_SAP_DEFAULT, + psUri, + pConnect_RspCb, + pContext); + } } return status; diff --git a/src/phFriNfc_LlcpTransport_Connection.c b/src/phFriNfc_LlcpTransport_Connection.c index fcdb246..b75406b 100644 --- a/src/phFriNfc_LlcpTransport_Connection.c +++ b/src/phFriNfc_LlcpTransport_Connection.c @@ -31,7 +31,6 @@ #include <phFriNfc_Llcp.h> #include <phFriNfc_LlcpUtils.h> - /* Function definition */ static NFCSTATUS phFriNfc_Llcp_Send_DisconnectMode_Frame(phFriNfc_LlcpTransport_t* psTransport, uint8_t dsap, @@ -42,8 +41,24 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_So static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_Socket_t* pLlcpSocket); +static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket); + /********** End Function definition ***********/ +NFCSTATUS phFriNfc_LlcpConnTransport_Send( phFriNfc_Llcp_t *Llcp, + phFriNfc_Llcp_sPacketHeader_t *psHeader, + phFriNfc_Llcp_sPacketSequence_t *psSequence, + phNfc_sData_t *psInfo, + phFriNfc_Llcp_Send_CB_t pfSend_CB, + phFriNfc_LlcpTransport_t* psTransport ) { + NFCSTATUS result = phFriNfc_Llcp_Send(Llcp, psHeader, psSequence, psInfo, + pfSend_CB, psTransport); + if (result == NFCSTATUS_PENDING) { + psTransport->bSendPending = TRUE; + } + return result; +} + /* TODO: comment functionphFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB */ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* pContext, NFCSTATUS status) @@ -73,16 +88,12 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer; sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */ - /* Send Pending */ - psTransport->bSendPending = TRUE; - - result = phFriNfc_Llcp_Send(psTransport->pLlcp, + result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, &psTransport->sLlcpHeader, NULL, &sFrmrBuffer, phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, psTransport); - } else if(psTransport->bDmPending) { @@ -131,9 +142,9 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p psTransport->pSocketTable[psTransport->socketIndex].pfSocketSend_Cb = NULL; } }break; + default: break; } - /* Update Index value with the next socket */ index = psTransport->socketIndex+1; @@ -183,31 +194,7 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p /* Test the RW window */ if(CHECK_SEND_RW(psLocalLlcpSocket)) { - /* Set the Header */ - psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap; - psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; - psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap; - - /* Set Sequence Numbers */ - psLocalLlcpSocket->sSequence.ns = psLocalLlcpSocket->socket_VS; - psLocalLlcpSocket->sSequence.nr = psLocalLlcpSocket->socket_VR; - - /* Send Pending */ - psTransport->bSendPending = TRUE; - - /* Store the index of the socket */ - psTransport->socketIndex = psLocalLlcpSocket->index ; - - /* Send I_PDU */ - result = phFriNfc_Llcp_Send(psTransport->pLlcp, - &psLocalLlcpSocket->sLlcpHeader, - &psLocalLlcpSocket->sSequence, - &psLocalLlcpSocket->sSocketSendBuffer, - phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, - psTransport); - - /* Update VS */ - psLocalLlcpSocket->socket_VS = (psLocalLlcpSocket->socket_VS+1)%16; + result = static_performSendInfo(psLocalLlcpSocket); /* Reset Send Pending Flag */ psLocalLlcpSocket->bSocketSendPending = FALSE; @@ -243,9 +230,6 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC; psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap; - /* Send Pending */ - psTransport->bSendPending = TRUE; - /* Set the socket state to accepted */ psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted; @@ -253,7 +237,7 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p psTransport->socketIndex = psLocalLlcpSocket->index; /* Send a CC Frame */ - result = phFriNfc_Llcp_Send(psTransport->pLlcp, + result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, &psLocalLlcpSocket->sLlcpHeader, NULL, &psLocalLlcpSocket->sSocketSendBuffer, @@ -266,9 +250,6 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p /* Reset Accept pending */ psLocalLlcpSocket->bSocketConnectPending = FALSE; - /* Send Pending */ - psTransport->bSendPending = TRUE; - /* Store the index of the socket */ psTransport->socketIndex = psLocalLlcpSocket->index; @@ -276,7 +257,7 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketConnecting; /* send CONNECT */ - result = phFriNfc_Llcp_Send(psTransport->pLlcp, + result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, &psLocalLlcpSocket->sLlcpHeader, NULL, &psLocalLlcpSocket->sSocketSendBuffer, @@ -289,9 +270,6 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p /* Reset Disc Pending */ psLocalLlcpSocket->bSocketDiscPending = FALSE; - /* Send Pending */ - psTransport->bSendPending = TRUE; - /* Set the socket in connecting state */ psLocalLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketDisconnecting; @@ -299,7 +277,7 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p psTransport->socketIndex = psLocalLlcpSocket->index; /* Send DISC */ - result = phFriNfc_Llcp_Send(psTransport->pLlcp, + result = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, &psLocalLlcpSocket->sLlcpHeader, NULL, &psLocalLlcpSocket->sSocketSendBuffer, @@ -330,6 +308,43 @@ static void phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB(void* p } } +static NFCSTATUS static_performSendInfo(phFriNfc_LlcpTransport_Socket_t * psLlcpSocket) +{ + phFriNfc_LlcpTransport_t *psTransport = psLlcpSocket->psTransport; + NFCSTATUS status; + + /* Reset Send Pending */ + psLlcpSocket->bSocketSendPending = FALSE; + + /* Set the Header */ + psLlcpSocket->sLlcpHeader.dsap = psLlcpSocket->socket_dSap; + psLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; + psLlcpSocket->sLlcpHeader.ssap = psLlcpSocket->socket_sSap; + + /* Set Sequence Numbers */ + psLlcpSocket->sSequence.ns = psLlcpSocket->socket_VS; + psLlcpSocket->sSequence.nr = psLlcpSocket->socket_VR; + + /* Update the VRA */ + psLlcpSocket->socket_VRA = psLlcpSocket->socket_VR; + + /* Store the index of the socket */ + psTransport->socketIndex = psLlcpSocket->index; + + /* Send I_PDU */ + status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, + &psLlcpSocket->sLlcpHeader, + &psLlcpSocket->sSequence, + &psLlcpSocket->sSocketSendBuffer, + phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, + psTransport); + + /* Update VS */ + psLlcpSocket->socket_VS = (psLlcpSocket->socket_VS+1)%16; + + return status; +} + static void phFriNfc_LlcpTransport_ConnectionOriented_Abort(phFriNfc_LlcpTransport_Socket_t * pLlcpSocket) { if (pLlcpSocket->pfSocketSend_Cb != NULL) @@ -400,11 +415,8 @@ static NFCSTATUS phFriNfc_Llcp_Send_DisconnectMode_Frame(phFriNfc_LlcpTransport_ psTransport->sDmPayload.buffer = &psTransport->DmInfoBuffer[2]; psTransport->sDmPayload.length = PHFRINFC_LLCP_DM_LENGTH; - /* Send Pending */ - psTransport->bSendPending = TRUE; - /* Send DM frame */ - status = phFriNfc_Llcp_Send(psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, &psTransport->sDmHeader, NULL, &psTransport->sDmPayload, @@ -439,14 +451,11 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveReady_Frame(phFriNfc_LlcpTransport_So /* Update VRA */ pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr; - /* Send Pending */ - pLlcpSocket->psTransport->bSendPending = TRUE; - /* Store the index of the socket */ pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index; /* Send RR frame */ - status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp, &pLlcpSocket->sLlcpHeader, &pLlcpSocket->sSequence, NULL, @@ -482,14 +491,11 @@ static NFCSTATUS phFriNfc_Llcp_Send_ReceiveNotReady_Frame(phFriNfc_LlcpTransport /* Update VRA */ pLlcpSocket->socket_VRA = (uint8_t)pLlcpSocket->sSequence.nr; - /* Send Pending */ - pLlcpSocket->psTransport->bSendPending = TRUE; - /* Store the index of the socket */ pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index; /* Send RNR frame */ - status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp, &pLlcpSocket->sLlcpHeader, &pLlcpSocket->sSequence, NULL, @@ -573,11 +579,8 @@ static NFCSTATUS phFriNfc_Llcp_Send_FrameReject_Frame(phFriNfc_LlcpTransport_t sFrmrBuffer.buffer = psTransport->FrmrInfoBuffer; sFrmrBuffer.length = 0x04; /* Size of FRMR Information field */ - /* Send Pending */ - psTransport->bSendPending = TRUE; - /* Send FRMR frame */ - status = phFriNfc_Llcp_Send(psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(psTransport->pLlcp, &psTransport->sLlcpHeader, NULL, &sFrmrBuffer, @@ -1269,34 +1272,7 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport, /* Test if a send is pending at LLC layer */ if(psTransport->bSendPending != TRUE) { - /* Reset Send Pending */ - psLocalLlcpSocket->bSocketSendPending = FALSE; - - /* Send Pending */ - psTransport->bSendPending = TRUE; - - /* Store the index of the socket */ - psTransport->socketIndex = psLocalLlcpSocket->index; - - /* Set the Header */ - psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap; - psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; - psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap; - - /* Set Sequence Numbers */ - psLocalLlcpSocket->sSequence.ns = psLocalLlcpSocket->socket_VS; - psLocalLlcpSocket->sSequence.nr = psLocalLlcpSocket->socket_VR; - - /* Send I_PDU */ - status = phFriNfc_Llcp_Send(psTransport->pLlcp, - &psLocalLlcpSocket->sLlcpHeader, - &psLocalLlcpSocket->sSequence, - &psLocalLlcpSocket->sSocketSendBuffer, - phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, - psTransport); - - /* Update VS */ - psLocalLlcpSocket->socket_VS = (psLocalLlcpSocket->socket_VS+1)%16; + status = static_performSendInfo(psLocalLlcpSocket); } } else @@ -1375,34 +1351,7 @@ static void Handle_Receive_IFrame(phFriNfc_LlcpTransport_t *psTransport, /* Test if a send is pending at LLC layer */ if(psTransport->bSendPending != TRUE) { - /* Reset Send Pending */ - psLocalLlcpSocket->bSocketSendPending = FALSE; - - /* Send Pending */ - psTransport->bSendPending = TRUE; - - /* Store the index of the socket */ - psTransport->socketIndex = psLocalLlcpSocket->index; - - /* Set the Header */ - psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap; - psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; - psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap; - - /* Set Sequence Numbers */ - psLocalLlcpSocket->sSequence.ns = psLocalLlcpSocket->socket_VS; - psLocalLlcpSocket->sSequence.nr = psLocalLlcpSocket->socket_VR; - - /* Send I_PDU */ - status = phFriNfc_Llcp_Send(psTransport->pLlcp, - &psLocalLlcpSocket->sLlcpHeader, - &psLocalLlcpSocket->sSequence, - &psLocalLlcpSocket->sSocketSendBuffer, - phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, - psTransport); - - /* Update VS */ - psLocalLlcpSocket->socket_VS = (psLocalLlcpSocket->socket_VS+1)%16; + status = static_performSendInfo(psLocalLlcpSocket); } } else @@ -1537,34 +1486,7 @@ static void Handle_ReceiveReady_Frame(phFriNfc_LlcpTransport_t *psTransport /* Test if a send is pending at LLC layer */ if(psTransport->bSendPending != TRUE) { - /* Reset Send Pending */ - psLocalLlcpSocket->bSocketSendPending = FALSE;; - - /* Send Pending */ - psTransport->bSendPending = TRUE; - - /* Store the index of the socket */ - psTransport->socketIndex = psLocalLlcpSocket->index; - - /* Set the Header */ - psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap; - psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; - psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap; - - /* Set Sequence Numbers */ - psLocalLlcpSocket->sSequence.ns = psLocalLlcpSocket->socket_VS; - psLocalLlcpSocket->sSequence.nr = psLocalLlcpSocket->socket_VR; - - /* Send I_PDU */ - status = phFriNfc_Llcp_Send(psTransport->pLlcp, - &psLocalLlcpSocket->sLlcpHeader, - &psLocalLlcpSocket->sSequence, - &psLocalLlcpSocket->sSocketSendBuffer, - phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, - psTransport); - - /* Update VS */ - psLocalLlcpSocket->socket_VS = (psLocalLlcpSocket->socket_VS+1)%16; + status = static_performSendInfo(psLocalLlcpSocket); } } } @@ -1673,34 +1595,7 @@ static void Handle_ReceiveNotReady_Frame(phFriNfc_LlcpTransport_t *psTransp /* Test if a send is pending at LLC layer */ if(psTransport->bSendPending != TRUE) { - /* Reset Send Pending */ - psLocalLlcpSocket->bSocketSendPending = FALSE; - - /* Send Pending */ - psTransport->bSendPending = TRUE; - - /* Set the Header */ - psLocalLlcpSocket->sLlcpHeader.dsap = psLocalLlcpSocket->socket_dSap; - psLocalLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; - psLocalLlcpSocket->sLlcpHeader.ssap = psLocalLlcpSocket->socket_sSap; - - /* Set Sequence Numbers */ - psLocalLlcpSocket->sSequence.ns = psLocalLlcpSocket->socket_VS; - psLocalLlcpSocket->sSequence.nr = psLocalLlcpSocket->socket_VR; - - /* Store the index of the socket */ - psTransport->socketIndex = psLocalLlcpSocket->index; - - /* Send I_PDU */ - status = phFriNfc_Llcp_Send(psTransport->pLlcp, - &psLocalLlcpSocket->sLlcpHeader, - &psLocalLlcpSocket->sSequence, - &psLocalLlcpSocket->sSocketSendBuffer, - phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, - psTransport); - - /* Update VS */ - psLocalLlcpSocket->socket_VS = (psLocalLlcpSocket->socket_VS+1)%16; + status = static_performSendInfo(psLocalLlcpSocket); } } } @@ -2129,9 +2024,6 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Accept(phFriNfc_LlcpTranspor pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_CC; pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap; - /* Send Pending */ - pLlcpSocket->psTransport->bSendPending = TRUE; - /* Set the socket state to accepted */ pLlcpSocket->eSocket_State = phFriNfc_LlcpTransportSocket_eSocketAccepted; @@ -2142,7 +2034,7 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Accept(phFriNfc_LlcpTranspor pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index; /* Send a CC Frame */ - status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp, &pLlcpSocket->sLlcpHeader, NULL, &pLlcpSocket->sSocketSendBuffer, @@ -2324,9 +2216,6 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Connect( phFriNfc_LlcpTransp } else { - /* Send Pending */ - pLlcpSocket->psTransport->bSendPending = TRUE; - /* Update Send Buffer length value */ pLlcpSocket->sSocketSendBuffer.length = offset; @@ -2335,8 +2224,7 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Connect( phFriNfc_LlcpTransp /* Store the index of the socket */ pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index; - - status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp, &pLlcpSocket->sLlcpHeader, NULL, &pLlcpSocket->sSocketSendBuffer, @@ -2437,13 +2325,10 @@ NFCSTATUS phLibNfc_LlcpTransport_ConnectionOriented_Disconnect(phFriNfc_LlcpTran } else { - /* Send Pending */ - pLlcpSocket->psTransport->bSendPending = TRUE; - /* Store the index of the socket */ pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index; - status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp, + status = phFriNfc_LlcpConnTransport_Send(pLlcpSocket->psTransport->pLlcp, &pLlcpSocket->sLlcpHeader, NULL, NULL, @@ -2610,59 +2495,32 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Send(phFriNfc_LlcpTransport_ } else { + /* Store send buffer pointer */ + pLlcpSocket->sSocketSendBuffer = *psBuffer; + + /* Store the Send CB and context */ + pLlcpSocket->pfSocketSend_Cb = pSend_RspCb; + pLlcpSocket->pSendContext = pContext; + /* Test if a send is pending */ if(pLlcpSocket->psTransport->bSendPending == TRUE) { - /* Store the Send CB and context */ - pLlcpSocket->pfSocketSend_Cb = pSend_RspCb; - pLlcpSocket->pSendContext = pContext; - /* Set Send pending */ pLlcpSocket->bSocketSendPending = TRUE; - /* Store send buffer pointer */ - pLlcpSocket->sSocketSendBuffer = *psBuffer; - /* Set status */ status = NFCSTATUS_PENDING; } else { - /* Store the Send CB and context */ - pLlcpSocket->pfSocketSend_Cb = pSend_RspCb; - pLlcpSocket->pSendContext = pContext; - - /* Set the Header */ - pLlcpSocket->sLlcpHeader.dsap = pLlcpSocket->socket_dSap; - pLlcpSocket->sLlcpHeader.ptype = PHFRINFC_LLCP_PTYPE_I; - pLlcpSocket->sLlcpHeader.ssap = pLlcpSocket->socket_sSap; - - /* Set Sequence Numbers */ - pLlcpSocket->sSequence.ns = pLlcpSocket->socket_VS; - pLlcpSocket->sSequence.nr = pLlcpSocket->socket_VR; - - /* Send Pending */ - pLlcpSocket->psTransport->bSendPending = TRUE; - - /* Store the index of the socket */ - pLlcpSocket->psTransport->socketIndex = pLlcpSocket->index; - - /* Send I_PDU */ - status = phFriNfc_Llcp_Send(pLlcpSocket->psTransport->pLlcp, - &pLlcpSocket->sLlcpHeader, - &pLlcpSocket->sSequence, - psBuffer, - phFriNfc_LlcpTransport_ConnectionOriented_SendLlcp_CB, - pLlcpSocket->psTransport); + /* Perform I-Frame send */ + status = static_performSendInfo(pLlcpSocket); if(status != NFCSTATUS_PENDING) { LLCP_PRINT("Release Send callback"); pLlcpSocket->pfSocketSend_Cb = NULL; pLlcpSocket->pSendContext = NULL; } - - /* Update VS */ - pLlcpSocket->socket_VS = (pLlcpSocket->socket_VS+1)%16; } } @@ -2789,33 +2647,32 @@ NFCSTATUS phFriNfc_LlcpTransport_ConnectionOriented_Recv( phFriNfc_LlcpTransport if(dataLengthRead != 0) { /* Test If data is present in the RW Buffer */ - if(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite) + while(pLlcpSocket->indexRwRead != pLlcpSocket->indexRwWrite) { - do + /* Get the data length available in the linear buffer */ + dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer); + + /* Exit if not enough memory available in linear buffer */ + if(dataLengthAvailable < pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length) { - /* Get the data length available in the linear buffer */ - dataLengthAvailable = phFriNfc_Llcp_CyclicFifoAvailable(&pLlcpSocket->sCyclicFifoBuffer); + break; + } - /* Test if enought place is available */ - if(dataLengthAvailable > pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length ) - { - /* Write data into the linear buffer */ - dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&pLlcpSocket->sCyclicFifoBuffer, - pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer, - pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length); - /* Update VR */ - pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16; + /* Write data into the linear buffer */ + dataLengthWrite = phFriNfc_Llcp_CyclicFifoWrite(&pLlcpSocket->sCyclicFifoBuffer, + pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].buffer, + pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length); + /* Update VR */ + pLlcpSocket->socket_VR = (pLlcpSocket->socket_VR+1)%16; - /* Set flag bufferized to TRUE */ - dataBufferized = TRUE; + /* Set flag bufferized to TRUE */ + dataBufferized = TRUE; - /* Update RW Buffer length */ - pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0; + /* Update RW Buffer length */ + pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length = 0; - /* Update Value Rw Read Index*/ - pLlcpSocket->indexRwRead++; - } - }while(dataLengthAvailable > pLlcpSocket->sSocketRwBufferTable[(pLlcpSocket->indexRwRead%pLlcpSocket->localRW)].length); + /* Update Value Rw Read Index*/ + pLlcpSocket->indexRwRead++; } /* Test if data has been bufferized after a read access */ diff --git a/src/phFriNfc_TopazDynamicMap.c b/src/phFriNfc_TopazDynamicMap.c index 697604d..2aa29ea 100644 --- a/src/phFriNfc_TopazDynamicMap.c +++ b/src/phFriNfc_TopazDynamicMap.c @@ -1010,7 +1010,7 @@ phFriNfc_Tpz_H_UpdateAndWriteLockBits ( lock_byte_index = (uint8_t)(lock_byte_index + 1); byte_index = (uint8_t)(byte_index + 1); } - } /* else of /* if (mod_value) */ + } /* else of if (mod_value) */ ps_tpz_info->lock_bytes_written = remaining_lock_bits; } else /* if (no_of_bits_left_in_block >= remaining_lock_bits) */ @@ -3848,7 +3848,7 @@ phFriNfc_Tpz_H_CopySendWrData ( #endif /* #ifdef TOPAZ_RAW_SUPPORT */ psNdefMap->State = (uint8_t)PH_FRINFC_TOPAZ_STATE_WRITE; - if ((write_len - psNdefMap->ApduBuffIndex) >= TOPAZ_WRITE_8_DATA_LENGTH) + if ((write_len - psNdefMap->ApduBuffIndex) >= (uint16_t)TOPAZ_WRITE_8_DATA_LENGTH) { copy_length = (uint8_t)TOPAZ_WRITE_8_DATA_LENGTH; (void)memcpy ((void *)write_buf, diff --git a/src/phHal4Nfc.c b/src/phHal4Nfc.c index 1263766..341f183 100644 --- a/src/phHal4Nfc.c +++ b/src/phHal4Nfc.c @@ -302,15 +302,17 @@ phHal4Nfc_Configure_Layers( #include <utils/Log.h> #include <dlfcn.h> +#define FW_PATH "/system/vendor/firmware/libpn544_fw.so" + const unsigned char *nxp_nfc_full_version = NULL; const unsigned char *nxp_nfc_fw = NULL; int dlopen_firmware() { void *p; - void *handle = dlopen("/system/lib/libpn544_fw.so", RTLD_NOW); + void *handle = dlopen(FW_PATH, RTLD_NOW); if (handle == NULL) { - LOGE("Could not open libpn544.so"); + LOGE("Could not open %s", FW_PATH); return -1; } diff --git a/src/phHal4Nfc_ADD.c b/src/phHal4Nfc_ADD.c index 0be1670..5751219 100644 --- a/src/phHal4Nfc_ADD.c +++ b/src/phHal4Nfc_ADD.c @@ -489,17 +489,13 @@ void phHal4Nfc_TargetDiscoveryComplete( psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength)) { aRemoteDevTypes[Count] = phHal_eMifare_PICC; - + Count++; } - else/*TYPE 3A*/ - { - aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; - } - Count++; } - else if ( !(Sak & ISO_14443_BITMASK) && - !(Sak & NFCIP_BITMASK) && (0 == Count)) + if ( !(Sak & NFCIP_BITMASK) ) { + // Always add a separate 3A target on a separate + // handle, so the upper layers can connect to it. aRemoteDevTypes[Count] = phHal_eISO14443_3A_PICC; Count++; } diff --git a/src/phHal4Nfc_Internal.h b/src/phHal4Nfc_Internal.h index 8675c55..50f4ea1 100644 --- a/src/phHal4Nfc_Internal.h +++ b/src/phHal4Nfc_Internal.h @@ -226,6 +226,7 @@ typedef struct phHal4Nfc_Hal4Ctxt{ /*used to ignore multiple Protected events*/ uint8_t Ignore_Event_Protected; #endif/*#ifdef IGNORE_EVT_PROTECTED*/ + uint8_t FelicaIDm[(PHHAL_FEL_ID_LEN + 2)]; }phHal4Nfc_Hal4Ctxt_t; diff --git a/src/phHal4Nfc_Reader.c b/src/phHal4Nfc_Reader.c index b767858..5a91e85 100644 --- a/src/phHal4Nfc_Reader.c +++ b/src/phHal4Nfc_Reader.c @@ -51,6 +51,7 @@ #define PH_HAL4NFC_SEL_SECTOR2_BYTE0 0x02 #define PH_HAL4NFC_SEL_SECTOR2_BYTE_RESERVED 0x00 +phHal4Nfc_Hal4Ctxt_t *gpHal4Ctxt; /* --------------------Structures and enumerations --------------------------*/ @@ -962,13 +963,24 @@ NFCSTATUS phHal4Nfc_PresenceCheck( /*allow only one Presence chk command at any point in time*/ if (eHal4StatePresenceCheck != Hal4Ctxt->Hal4NextState) { + /* Check if remote device is felica */ + if (Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType == + phHal_eFelica_PICC) + { + /* If felica PICC then copy existing IDm to compare later, + If IDm will be same then same PICC is present after presence check + else PICC is changed */ + (void) memcpy(Hal4Ctxt->FelicaIDm, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDm, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDmLength); + } Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt = context; Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb = pPresenceChkCb; RetStatus = phHciNfc_Presence_Check(Hal4Ctxt->psHciHandle, psHwReference ); Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == RetStatus? - eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState); + eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState); } else/*Ongoing presence chk*/ { @@ -990,6 +1002,28 @@ void phHal4Nfc_PresenceChkComplete( { Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened =(uint8_t)(NFCSTATUS_SUCCESS == RetStatus?TRUE:FALSE); + /* Check if remote device is felica */ + if (Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemDevType == + phHal_eFelica_PICC) + { + /* Check if IDm received is same as saved */ + if (0 != phOsalNfc_MemCompare(Hal4Ctxt->FelicaIDm, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDm, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDmLength)) + { + RetStatus = NFCSTATUS_FAILED; + + /* Presence check failed so reset remote device information */ + (void) memset(Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDm, + 0, PHHAL_FEL_ID_LEN + 2); + (void) memset(Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.PMm, + 0, PHHAL_FEL_PM_LEN); + } + + /* Cleanup for stored IDm value for using it next time */ + (void) memset(Hal4Ctxt->FelicaIDm, 0, PHHAL_FEL_ID_LEN + 2); + } + (*Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb)( Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, RetStatus @@ -1035,7 +1069,28 @@ void phHal4Nfc_ReactivationComplete( return; } +void phHal4Nfc_Felica_RePoll(void *context, + NFCSTATUS status) +{ + phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt = gpHal4Ctxt; + pphHal4Nfc_ConnectCallback_t pUpperConnectCb + = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb; + + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; + PHDBG_INFO("Hal4:Calling Connect callback"); + + if (pUpperConnectCb != NULL) + { + /*Notify to the upper layer*/ + (*pUpperConnectCb)( + Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, + status + ); + } + return; +} void phHal4Nfc_ConnectComplete( phHal4Nfc_Hal4Ctxt_t *Hal4Ctxt, void *pInfo @@ -1046,18 +1101,25 @@ void phHal4Nfc_ConnectComplete( = Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb; /*Flag to decide whether or not upper layer callback has to be called*/ uint8_t CallConnectCb = TRUE; + uint8_t felicaRePoll = FALSE; + /*Remote device Connect successful*/ if((NFCSTATUS_SUCCESS == ConnectStatus) ||(eHal4StateTargetConnected == Hal4Ctxt->Hal4CurrentState)) { + phHal_sRemoteDevInformation_t *psRmtTgtConnected = + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice; PHDBG_INFO("Hal4:Connect status Success"); Hal4Ctxt->Hal4CurrentState = eHal4StateTargetConnected; Hal4Ctxt->Hal4NextState = eHal4StateInvalid; /* Open the Session */ - Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->SessionOpened = + psRmtTgtConnected->SessionOpened = (uint8_t)(NFCSTATUS_SUCCESS == ConnectStatus?TRUE:FALSE); Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = NULL; - + if (psRmtTgtConnected->RemDevType == phHal_eFelica_PICC) + { + felicaRePoll = TRUE; + } } else/*Remote device Connect failed*/ { @@ -1094,13 +1156,37 @@ void phHal4Nfc_ConnectComplete( } if(TRUE == CallConnectCb) { - PHDBG_INFO("Hal4:Calling Connect callback"); - /*Notify to the upper layer*/ - (*pUpperConnectCb)( + if (felicaRePoll == TRUE) + { + /* Felica repoll through presence check */ + + /* If felica PICC then copy existing IDm to compare later, + If IDm will be same then same PICC is present after presence check + else PICC is changed */ + (void) memcpy(Hal4Ctxt->FelicaIDm, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDm, + Hal4Ctxt->sTgtConnectInfo.psConnectedDevice->RemoteDevInfo.Felica_Info.IDmLength); + + gpHal4Ctxt = Hal4Ctxt; + Hal4Ctxt->sTgtConnectInfo.pPresenceChkCb = phHal4Nfc_Felica_RePoll; + ConnectStatus = phHciNfc_Presence_Check(Hal4Ctxt->psHciHandle, + gpphHal4Nfc_Hwref + ); + Hal4Ctxt->Hal4NextState = (NFCSTATUS_PENDING == ConnectStatus? + eHal4StatePresenceCheck:Hal4Ctxt->Hal4NextState); + felicaRePoll = FALSE; + Hal4Ctxt->sTgtConnectInfo.pUpperConnectCb = pUpperConnectCb; + } + else + { + PHDBG_INFO("Hal4:Calling Connect callback"); + /*Notify to the upper layer*/ + (*pUpperConnectCb)( Hal4Ctxt->sUpperLayerInfo.psUpperLayerCtxt, Hal4Ctxt->sTgtConnectInfo.psConnectedDevice, ConnectStatus ); + } } else { diff --git a/src/phHciNfc.c b/src/phHciNfc.c index 9400820..d6990c1 100644 --- a/src/phHciNfc.c +++ b/src/phHciNfc.c @@ -95,7 +95,7 @@ phHciNfc_Config_Emulation ( ) { phHciNfc_sContext_t *psHciContext = NULL; - phNfcIF_sReference_t hciReference = { NULL }; + phNfcIF_sReference_t hciReference = { NULL, 0, 0 }; phNfcIF_sCallBack_t if_callback = { NULL, NULL, NULL, NULL }; phNfc_sLowerIF_t *plower_if = NULL; NFCSTATUS status = NFCSTATUS_SUCCESS; diff --git a/src/phHciNfc_DevMgmt.c b/src/phHciNfc_DevMgmt.c index 32662c1..ef3aa78 100644 --- a/src/phHciNfc_DevMgmt.c +++ b/src/phHciNfc_DevMgmt.c @@ -118,6 +118,7 @@ typedef enum phHciNfc_DevMgmt_Seq{ DEV_MGMT_LLC_GRD_TO_L, DEV_MGMT_LLC_ACK_TO_H, DEV_MGMT_LLC_ACK_TO_L, + DEV_MGMT_FELICA_RC, DEV_MGMT_EVT_AUTONOMOUS, DEV_MGMT_PIPE_CLOSE } phHciNfc_DevMgmt_Seq_t; @@ -517,17 +518,8 @@ phHciNfc_DevMgmt_Initialise( pHwRef, p_pipe_info ); if(status == NFCSTATUS_SUCCESS) { - - if (HCI_SELF_TEST == psHciContext->init_mode ) - { - p_device_mgmt_info->next_seq = - DEV_MGMT_GPIO_PDIR; - } - else - { - p_device_mgmt_info->next_seq = - DEV_MGMT_GET_EEPROM_INFO; - } + p_device_mgmt_info->next_seq = + DEV_MGMT_FELICA_RC; status = NFCSTATUS_PENDING; } break; @@ -579,6 +571,26 @@ phHciNfc_DevMgmt_Initialise( } break; } + case DEV_MGMT_FELICA_RC: + { + config = 0x00; + status = phHciNfc_DevMgmt_Configure( psHciContext, pHwRef, + NFC_FELICA_RC_ADDR , config ); + if(NFCSTATUS_PENDING == status ) + { + if (HCI_SELF_TEST == psHciContext->init_mode ) + { + p_device_mgmt_info->next_seq = + DEV_MGMT_GPIO_PDIR; + } + else + { + p_device_mgmt_info->next_seq = + DEV_MGMT_GET_EEPROM_INFO; + } + } + break; + } #if ( NXP_NFC_IFC_TIMEOUT & 0x01 ) @@ -1339,6 +1351,7 @@ phHciNfc_Recv_DevMgmt_Event( case NXP_EVT_INFO_MEM_VIOLATION: { event_info.eventType = NFC_INFO_MEM_VIOLATION; + LOGW("Your NFC controller is kinda hosed, take it to npelly@ to fix"); break; } case NXP_EVT_INFO_TEMP_OVERHEAT: diff --git a/src/phHciNfc_DevMgmt.h b/src/phHciNfc_DevMgmt.h index 571fac2..e886013 100644 --- a/src/phHciNfc_DevMgmt.h +++ b/src/phHciNfc_DevMgmt.h @@ -119,6 +119,7 @@ #define NFC_ADDRESS_PMOS_MOD 0x997AU #endif +#define NFC_FELICA_RC_ADDR 0x9F9AU /* The Address Definition for the Enabling the EVT_HOT_PLUG */ #define NFC_ADDRESS_HOTPLUG_EVT 0x9FF0U diff --git a/src/phHciNfc_Felica.c b/src/phHciNfc_Felica.c index 1a353a5..2897690 100644 --- a/src/phHciNfc_Felica.c +++ b/src/phHciNfc_Felica.c @@ -51,6 +51,7 @@ #define NXP_WRA_CONTINUE_ACTIVATION 0x12U #define NXP_FEL_SYS_CODE 0x01U +#define NXP_FEL_POLREQ_SYS_CODE 0x02U #define NXP_FEL_CURRENTIDM 0x04U #define NXP_FEL_CURRENTPMM 0x05U @@ -58,10 +59,12 @@ #define NXP_FEL_CUR_IDM_PMM_LEN 0x08U #define FELICA_STATUS 0x00U -#define FELICA_TIMEOUT NXP_FELICA_XCHG_TIMEOUT + +uint8_t nxp_nfc_felica_timeout = NXP_FELICA_XCHG_TIMEOUT; /* Presence check command for felica tag */ #define FELICA_REQ_MODE 0x04U + /* *************************** Structure and Enumeration *************************** */ @@ -417,10 +420,9 @@ phHciNfc_Felica_InfoUpdate( { if (NXP_FEL_SYS_CODE_LEN == reg_length) { - HCI_PRINT_BUFFER("\tFelica system code data", reg_value, reg_length); - /* Update current system code values */ - (void)memcpy(p_fel_tag_info->SystemCode, reg_value, - reg_length); + /* System code from registry is invalid in this case */ + p_fel_tag_info->SystemCode[0] = 0; + p_fel_tag_info->SystemCode[1] = 0; } else { @@ -500,6 +502,39 @@ phHciNfc_Recv_Felica_Packet( index = (index + 1); psHciContext->rx_index = (HCP_HEADER_LEN + 1); HCI_PRINT_BUFFER("Felica Bytes received", &pResponse[index], (length - index)); + /* If Poll response received then update IDm and PMm parameters, when presence check going on */ + if (pResponse[index + 1] == 0x01) + { + if (length >= 19) + { + /* IDm */ + (void) memcpy(psHciContext->p_target_info->RemoteDevInfo.Felica_Info.IDm, + &pResponse[index + 2], 8); + /* PMm */ + (void) memcpy(psHciContext->p_target_info->RemoteDevInfo.Felica_Info.PMm, + &pResponse[index + 2 + 8], 8); + index = index + 2 + 8 + 8; + + /* SC */ + if (length >= 21) + { + /* Copy SC if available */ + psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[0] = pResponse[index]; + psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[1] = pResponse[index + 1]; + } + else + { + /* If SC is not available in packet then set to zero */ + psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[0] = 0; + psHciContext->p_target_info->RemoteDevInfo.Felica_Info.SystemCode[1] = 0; + } + } + else + { + status = PHNFCSTVAL(CID_NFC_HCI, + NFCSTATUS_INVALID_HCI_RESPONSE); + } + } } else { @@ -827,7 +862,7 @@ phHciNfc_Felica_Request_Mode( pres_chk_data[1] = 0x00; // Felica poll pres_chk_data[2] = 0xFF; pres_chk_data[3] = 0xFF; - pres_chk_data[4] = 0x00; + pres_chk_data[4] = 0x01; pres_chk_data[5] = 0x00; ps_pipe_info->param_info = pres_chk_data; @@ -842,7 +877,6 @@ phHciNfc_Felica_Request_Mode( return status; } - NFCSTATUS phHciNfc_Send_Felica_Command( phHciNfc_sContext_t *psContext, @@ -908,7 +942,7 @@ phHciNfc_Send_Felica_Command( hcp_message = &(hcp_packet->msg.message); /* Time out */ - hcp_message->payload[i++] = FELICA_TIMEOUT ; + hcp_message->payload[i++] = nxp_nfc_felica_timeout ; /* Status */ hcp_message->payload[i++] = FELICA_STATUS; diff --git a/src/phHciNfc_Generic.c b/src/phHciNfc_Generic.c index 45aefdc..875e295 100644 --- a/src/phHciNfc_Generic.c +++ b/src/phHciNfc_Generic.c @@ -90,7 +90,7 @@ static phHciNfc_sContext_t *gpsHciContext= NULL; static void phHciNfc_Response_Timeout ( - uint32_t resp_timer_id + uint32_t resp_timer_id, void *pContext ); #endif /* (NXP_NFC_HCI_TIMER == 1) */ @@ -269,10 +269,10 @@ phHciNfc_Receive_HCP ( static void phHciNfc_Response_Timeout ( - uint32_t resp_timer_id + uint32_t resp_timer_id, void *pContext ) { - phNfc_sCompletionInfo_t comp_info = {0}; + phNfc_sCompletionInfo_t comp_info = {0,0,0}; if ( ( NULL != gpsHciContext) && (resp_timer_id == hci_resp_timer_id )) @@ -1147,11 +1147,11 @@ static #ifndef EVENT_NOTIFY ( NFCSTATUS_SUCCESS == status ) || ( NFCSTATUS_RF_TIMEOUT == status ) - || ( NFCSTATUS_MORE_INFORMATION == status ) + || (( NFCSTATUS_MORE_INFORMATION == status ) #else - (FALSE == psHciContext->event_pending ) + ((FALSE == psHciContext->event_pending ) #endif - && ( pipe_id <= PHHCINFC_MAX_PIPE ) + && ( pipe_id <= PHHCINFC_MAX_PIPE )) ) { /* phHciNfc_Reset_Pipe_MsgInfo(psHciContext->p_pipe_list[pipe_id]); */ @@ -1562,11 +1562,11 @@ phHciNfc_Send_Complete ( psHciContext->tx_total = HCP_ZERO_LEN ; psHciContext->tx_remain = HCP_ZERO_LEN ; psHciContext->tx_hcp_frgmnt_index = HCP_ZERO_LEN ; - HCI_DEBUG("HCI: In Function: %s \n", __FUNCTION__); - HCI_DEBUG("HCI: Response Pending status --> %s \n", - (psHciContext->response_pending)?"TRUE":"FALSE"); - HCI_DEBUG("HCI: Event Pending status --> %s \n", - (psHciContext->event_pending)?"TRUE":"FALSE"); + HCI_DEBUG("HCI: %s: response_pending=%s, event_pending=%s", + __FUNCTION__, + (psHciContext->response_pending)?"TRUE":"FALSE", + (psHciContext->event_pending)?"TRUE":"FALSE" + ); if ((TRUE == psHciContext->response_pending) || (TRUE == psHciContext->event_pending)) { @@ -2015,7 +2015,7 @@ phHciNfc_Notify_Event( if ( NXP_INVALID_TIMER_ID != hci_resp_timer_id ) { - HCI_DEBUG(" HCI : Response Timer Stop, Status:%02X : %X\n", + HCI_DEBUG(" HCI : Response Timer Stop, Status:%02X", psCompInfo->status); /* Stop and Un-Intialise the Response Timer */ phOsalNfc_Timer_Stop( hci_resp_timer_id ); @@ -2041,7 +2041,7 @@ phHciNfc_Notify_Event( if (( NFCSTATUS_BOARD_COMMUNICATION_ERROR == PHNFCSTATUS(psCompInfo->status)) && ( NXP_INVALID_TIMER_ID != hci_resp_timer_id )) { - HCI_DEBUG(" HCI : Response Timer Stop, Status:%02X : %X\n", + HCI_DEBUG(" HCI : Response Timer Stop, Status:%02X", psCompInfo->status); /* Stop the HCI Response Timer */ phOsalNfc_Timer_Stop( hci_resp_timer_id ); diff --git a/src/phHciNfc_Generic.h b/src/phHciNfc_Generic.h index 5410325..16ffa0e 100644 --- a/src/phHciNfc_Generic.h +++ b/src/phHciNfc_Generic.h @@ -55,21 +55,17 @@ ***************************** Header File Inclusion **************************** ################################################################################ */ - +#define LOG_TAG "NFC-HCI" +#include <cutils/log.h> #include <phNfcIoctlCode.h> #include<phNfcInterface.h> #include <phHciNfc.h> - /* ################################################################################ ****************************** Macro Definitions ******************************* ################################################################################ */ -#if defined(DEBUG) /*|| defined(_DEBUG) */ -#define HCI_TRACE -#endif - #define Trace_buffer phOsalNfc_DbgTraceBuffer /* HCI TRACE Macros */ @@ -80,14 +76,14 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define MAX_TRACE_BUFFER 150 /* #define HCI_PRINT( str ) phOsalNfc_DbgTrace(str) */ #define HCI_PRINT( str ) phOsalNfc_DbgString(str) -#define HCI_DEBUG(str, arg) \ - { \ - snprintf(Trace_buffer,MAX_TRACE_BUFFER,str,arg); \ - phOsalNfc_DbgString(Trace_buffer); \ - } +#define HCI_DEBUG(...) LOGD(__VA_ARGS__) + + + + #define HCI_PRINT_BUFFER(msg,buf,len) \ { \ - snprintf(Trace_buffer,MAX_TRACE_BUFFER,"\n\t %s:",msg); \ + snprintf(Trace_buffer,MAX_TRACE_BUFFER,"\t %s:",msg); \ phOsalNfc_DbgString(Trace_buffer); \ phOsalNfc_DbgTrace(buf,len); \ phOsalNfc_DbgString("\r"); \ @@ -101,7 +97,7 @@ extern char phOsalNfc_DbgTraceBuffer[]; #define HCI_PRINT_BUFFER(msg,buf,len) #else #define HCI_PRINT( str ) -#define HCI_DEBUG(str, arg) +#define HCI_DEBUG(...) #define HCI_PRINT_BUFFER(msg,buf,len) #endif /* #if defined(PHDBG_TRACES) */ /* #if defined(PHDBG_INFO) && defined (PHDBG_CRITICAL_ERROR) */ diff --git a/src/phHciNfc_RFReaderA.c b/src/phHciNfc_RFReaderA.c index ba71724..1b1280a 100644 --- a/src/phHciNfc_RFReaderA.c +++ b/src/phHciNfc_RFReaderA.c @@ -67,6 +67,7 @@ #define RDR_A_MIFARE_RAW_LENGTH 0x03U +uint8_t nxp_nfc_mifareraw_timeout = NXP_MIFARE_XCHG_TIMEOUT; /* *************************** Structure and Enumeration *************************** */ @@ -1037,7 +1038,7 @@ phHciNfc_Send_ReaderA_Command( hcp_message = &(hcp_packet->msg.message); #ifdef ENABLE_MIFARE_RAW /* Time out */ - hcp_message->payload[i++] = NXP_MIFARE_XCHG_TIMEOUT ; + hcp_message->payload[i++] = nxp_nfc_mifareraw_timeout; /* Status */ hcp_message->payload[i++] = RDR_A_MIFARE_STATUS; #else diff --git a/src/phHciNfc_Sequence.c b/src/phHciNfc_Sequence.c index 13b8ad5..73d7b79 100644 --- a/src/phHciNfc_Sequence.c +++ b/src/phHciNfc_Sequence.c @@ -527,16 +527,16 @@ phHciNfc_FSM_Rollback( ) { - HCI_DEBUG("HCI: In Function: %s \n", __FUNCTION__); + HCI_DEBUG("HCI: %s: transition=%02u, cur_state=%02u, next_state=%02u\n", + __func__, + psHciContext->hci_state.transition, + psHciContext->hci_state.cur_state, + psHciContext->hci_state.next_state); + + + - HCI_DEBUG(" HCI: Transition Before FSM Rollback --> %02u \n", - psHciContext->hci_state.transition ); - - HCI_DEBUG(" HCI: Current State Before FSM Rollback --> %02u \n", - psHciContext->hci_state.cur_state ); - HCI_DEBUG(" HCI: Next State Before FSM Rollback --> %02u \n", - psHciContext->hci_state.next_state ); if( (NFC_FSM_IN_PROGRESS == psHciContext->hci_state.transition) ) @@ -716,7 +716,7 @@ phHciNfc_Error_Sequence( case hciState_Select: { /* Notify the Configure failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info={FALSE}; + phNfc_sCompletionInfo_t comp_info={0,0,0}; /* Rollback the FSM as the Target Discovery Failed */ phHciNfc_FSM_Rollback(psHciContext); @@ -776,7 +776,7 @@ phHciNfc_Error_Sequence( case hciState_Reactivate: { /* Notify the General failure to the upper layer */ - phNfc_sCompletionInfo_t comp_info={FALSE}; + phNfc_sCompletionInfo_t comp_info={FALSE, 0, 0}; /* psHciContext->host_rf_type = phHal_eUnknown_DevType; status = phHciNfc_ReaderMgmt_Update_Sequence( @@ -893,14 +893,14 @@ phHciNfc_Resume_Sequence( ) { NFCSTATUS status = NFCSTATUS_SUCCESS; - - HCI_DEBUG("HCI: In Function: %s \n", - __FUNCTION__); - HCI_DEBUG(" HCI: Current HCI State --> %02u \n", - psHciContext->hci_state.cur_state ); - HCI_DEBUG(" HCI: Next HCI State --> %02u \n", - psHciContext->hci_state.next_state ); + HCI_DEBUG("HCI: %s: cur_state=%02u, next_state=%02u", + __FUNCTION__, + psHciContext->hci_state.cur_state, + psHciContext->hci_state.next_state); + + + switch(psHciContext->hci_state.next_state) { diff --git a/src/phLibNfc.c b/src/phLibNfc.c index fa28bf5..92bdc40 100644 --- a/src/phLibNfc.c +++ b/src/phLibNfc.c @@ -31,6 +31,8 @@ ************************* Header Files **************************************** */ +#define LOG_TAG "NFC" + #include <phLibNfc.h> #include <phDal4Nfc.h> #include <phHal4Nfc.h> @@ -134,12 +136,40 @@ NFCSTATUS phLibNfc_SetIsoXchgTimeout(uint8_t timeout) { return NFCSTATUS_SUCCESS; } +int phLibNfc_GetIsoXchgTimeout() { + return nxp_nfc_isoxchg_timeout; +} + extern uint32_t nxp_nfc_hci_response_timeout; NFCSTATUS phLibNfc_SetHciTimeout(uint32_t timeout_in_ms) { nxp_nfc_hci_response_timeout = timeout_in_ms; return NFCSTATUS_SUCCESS; } +int phLibNfc_GetHciTimeout() { + return nxp_nfc_hci_response_timeout; +} + +extern uint32_t nxp_nfc_felica_timeout; +NFCSTATUS phLibNfc_SetFelicaTimeout(uint8_t timeout_in_ms) { + nxp_nfc_felica_timeout = timeout_in_ms; + return NFCSTATUS_SUCCESS; +} + +int phLibNfc_GetFelicaTimeout() { + return nxp_nfc_felica_timeout; +} + +extern uint8_t nxp_nfc_mifareraw_timeout; +NFCSTATUS phLibNfc_SetMifareRawTimeout(uint8_t timeout) { + nxp_nfc_mifareraw_timeout = timeout; + return NFCSTATUS_SUCCESS; +} + +int phLibNfc_GetMifareRawTimeout() { + return nxp_nfc_mifareraw_timeout; +} + /** * Initialize the phLibNfc interface. */ @@ -840,6 +870,7 @@ NFCSTATUS phLibNfc_Mgt_GetstackCapabilities( /* Check the firmware version */ if (nxp_nfc_full_version == NULL) { // Couldn't load firmware, just pretend we're up to date. + LOGW("Firmware image not available: this device might be running old NFC firmware!"); phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = 0; } else { phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = memcmp(phLibNfc_StackCapabilities->psDevCapabilities.full_version, nxp_nfc_full_version, diff --git a/src/phLibNfc.h b/src/phLibNfc.h index 719cfc1..8621361 100644 --- a/src/phLibNfc.h +++ b/src/phLibNfc.h @@ -129,7 +129,10 @@ typedef enum This can be applied to UICC as well as SmartMX*/ phLibNfc_SE_ActModeVirtual=0x02, /**< Enables Virtual Mode communication. This can be applied to UICC as well as SmartMX*/ - phLibNfc_SE_ActModeOff =0x03 /**< Inactivate SE.This means,put SE in in-active state */ + phLibNfc_SE_ActModeOff =0x03, /**< Inactivate SE.This means,put SE in in-active state + This can be applied to UICC as well as SmartMX*/ + phLibNfc_SE_ActModeVirtualVolatile = 0x04 /**< Enabled virtual mode communication for SE through an event + This can be applied to UICC as well as SmartMX*/ }phLibNfc_eSE_ActivationMode; @@ -862,7 +865,27 @@ int phLibNfc_Load_Firmware_Image (); // bit [4] => timeout enable // bit [5..7] => unused NFCSTATUS phLibNfc_SetIsoXchgTimeout(uint8_t timeout); +int phLibNfc_GetIsoXchgTimeout(); + NFCSTATUS phLibNfc_SetHciTimeout(uint32_t timeout_in_ms); +int phLibNfc_GetHciTimeout(); + +// Felica timeout +// [0] -> timeout disabled +// [1..255] -> timeout in ms +NFCSTATUS phLibNfc_SetFelicaTimeout(uint8_t timeout_in_ms); +int phLibNfc_GetFelicaTimeout(); + +// MIFARE RAW timeout (ISO14443-3A / NfcA timeout) +// timeout is 8 bits +// bits [0..3] => timeout value, (256*16/13.56*10^6) * 2^value +// [0] -> 0.0003s +// .. +// [14] -> 4.9s +// [15] -> not allowed +// bits [4..7] => 0 +NFCSTATUS phLibNfc_SetMifareRawTimeout(uint8_t timeout); +int phLibNfc_GetMifareRawTimeout(); /** * \ingroup grp_lib_nfc diff --git a/src/phLibNfc_SE.c b/src/phLibNfc_SE.c index 4e839cf..968c239 100644 --- a/src/phLibNfc_SE.c +++ b/src/phLibNfc_SE.c @@ -135,7 +135,7 @@ STATIC void phLibNfc_SeNotification(void *context, { pphLibNfc_LibContext_t pLibContext=(pphLibNfc_LibContext_t)context; phHal_sEventInfo_t *pEvtInfo = NULL; - phLibNfc_uSeEvtInfo_t Se_Trans_Info={0}; + phLibNfc_uSeEvtInfo_t Se_Trans_Info={{{0,0},{0,0}}}; phLibNfc_SE_List_t *pSeInfo=NULL; if(pLibContext != gpphLibContext) @@ -473,7 +473,6 @@ NFCSTATUS phLibNfc_SE_SetMode ( phLibNfc_Handle hSE_Handle, switch(eActivation_mode) { case phLibNfc_SE_ActModeVirtual: - case phLibNfc_SE_ActModeDefault: { if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) { @@ -507,6 +506,69 @@ NFCSTATUS phLibNfc_SE_SetMode ( phLibNfc_Handle hSE_Handle, } } break; + case phLibNfc_SE_ActModeVirtualVolatile: + { + if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + eEmulationType = NFC_SMARTMX_EMULATION; + /*Enable the SMX -External reader can see it*/ + pLibContext->sCardEmulCfg.config.smartMxCfg.enableEmulation = TRUE; + pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeVirtualVolatile; + + Status = phHal4Nfc_Switch_SMX_Mode( + pLibContext->psHwReference, + eSmartMx_Virtual, + phLibNfc_SE_SetMode_cb, + pLibContext + ); + } + else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + eEmulationType = NFC_UICC_EMULATION; + /*Enable the UICC -External reader can see it*/ + pLibContext->sCardEmulCfg.config.uiccEmuCfg.enableUicc = TRUE; + pLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeVirtualVolatile; + + Status = phHal4Nfc_Switch_Swp_Mode( + pLibContext->psHwReference, + eSWP_Switch_On, + phLibNfc_SE_SetMode_cb, + pLibContext + ); + } + else + { + Status = NFCSTATUS_INVALID_HANDLE; + } + } + break; + case phLibNfc_SE_ActModeDefault: + { + if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) + { + Status = phHal4Nfc_Switch_SMX_Mode( + pLibContext->psHwReference, + eSmartMx_Default, + phLibNfc_SE_SetMode_cb, + pLibContext + ); + } + else if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement) + { + Status = phHal4Nfc_Switch_Swp_Mode( + pLibContext->psHwReference, + eSWP_Switch_Default, + phLibNfc_SE_SetMode_cb, + pLibContext + ); + } + else + { + Status = NFCSTATUS_INVALID_HANDLE; + } + } + break; + case phLibNfc_SE_ActModeWired: { if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_SMARTMX_INDEX].hSecureElement) diff --git a/src/phLibNfc_initiator.c b/src/phLibNfc_initiator.c index 2a03c05..0f71606 100644 --- a/src/phLibNfc_initiator.c +++ b/src/phLibNfc_initiator.c @@ -133,6 +133,10 @@ void phLibNfc_NotificationRegister_Resp_Cb ( { Status = NFCSTATUS_FAILED; } + else if (PHNFCSTATUS(status) == NFCSTATUS_DESELECTED) + { + return; + } else { DeviceIndx=0;DeviceIndx1=0; diff --git a/src/phLibNfc_ndef_raw.c b/src/phLibNfc_ndef_raw.c index 1e5b395..c39364e 100644 --- a/src/phLibNfc_ndef_raw.c +++ b/src/phLibNfc_ndef_raw.c @@ -1049,7 +1049,7 @@ STATIC void phLibNfc_Ndef_ChkNdef_Pchk_Cb(void *pContext, NFCSTATUS status ) { - phLibNfc_ChkNdef_Info_t Ndef_Info = {0,0}; + phLibNfc_ChkNdef_Info_t Ndef_Info = {0,0,0}; NFCSTATUS RetStatus = NFCSTATUS_SUCCESS; pphLibNfc_ChkNdefRspCb_t pClientCb=NULL; phLibNfc_LibContext_t *pLibNfc_Ctxt = diff --git a/src/phLlcNfc.c b/src/phLlcNfc.c index af0a3a1..36b442b 100644 --- a/src/phLlcNfc.c +++ b/src/phLlcNfc.c @@ -228,7 +228,7 @@ phLlcNfc_Init ( { NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext; - phLlcNfc_LlcPacket_t *ps_packet_info = NULL; + phLlcNfc_LlcPacket_t s_packet_info; PH_LLCNFC_PRINT("Llc Init called\n"); if ((NULL == ps_llc_ctxt) || (NULL == pLinkInfo)) @@ -239,8 +239,6 @@ phLlcNfc_Init ( else { /* Initialisation */ - ps_packet_info = &(ps_llc_ctxt->s_frameinfo.s_llcpacket); - ps_llc_ctxt->phwinfo = pLinkInfo; /* Call the internal frame initialise */ phLlcNfc_H_Frame_Init(ps_llc_ctxt); @@ -258,17 +256,17 @@ phLlcNfc_Init ( phLlcNfc_CreateTimers(); /* Create a U frame */ - result = phLlcNfc_H_CreateUFramePayload(ps_llc_ctxt, - ps_packet_info, - &(ps_packet_info->llcbuf_len), + result = phLlcNfc_H_CreateUFramePayload(ps_llc_ctxt, + &s_packet_info, + &(s_packet_info.llcbuf_len), phLlcNfc_e_rset); } if (NFCSTATUS_SUCCESS == result) { /* Call DAL write */ result = phLlcNfc_Interface_Write(ps_llc_ctxt, - (uint8_t*)&(ps_packet_info->s_llcbuf), - (uint32_t)ps_packet_info->llcbuf_len); + (uint8_t*)&(s_packet_info.s_llcbuf), + (uint32_t)s_packet_info.llcbuf_len); } if (NFCSTATUS_PENDING == result) { @@ -364,8 +362,7 @@ phLlcNfc_Send ( NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext; phLlcNfc_Frame_t *ps_frame_info = NULL; - phLlcNfc_LlcPacket_t *ps_packet_info = NULL, - s_packet_info; + phLlcNfc_LlcPacket_t s_packet_info; phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; #if 0 uint8_t count = 1; @@ -404,7 +401,6 @@ phLlcNfc_Send ( &s_packet_info, pLlcBuf, (uint8_t)llcBufLength); - ps_packet_info = &(ps_frame_info->s_llcpacket); /* Store the I frame in the send list */ (void)phLlcNfc_H_StoreIFrame (ps_store_frame, s_packet_info); @@ -423,13 +419,11 @@ phLlcNfc_Send ( #endif /* #ifdef CTRL_WIN_SIZE_COUNT */ { - (void)memcpy ((void *)ps_packet_info, (void *)&s_packet_info, - sizeof(phLlcNfc_LlcPacket_t)); /* Call write to the below layer, only if previous write is completed */ result = phLlcNfc_Interface_Write (ps_llc_ctxt, - (uint8_t *)&(ps_packet_info->s_llcbuf), - (uint32_t)ps_packet_info->llcbuf_len); + (uint8_t *)&(s_packet_info.s_llcbuf), + (uint32_t)s_packet_info.llcbuf_len); if ((NFCSTATUS_PENDING == result) || (NFCSTATUS_BUSY == PHNFCSTATUS (result))) diff --git a/src/phLlcNfc_DataTypes.h b/src/phLlcNfc_DataTypes.h index 2257513..9d5b588 100644 --- a/src/phLlcNfc_DataTypes.h +++ b/src/phLlcNfc_DataTypes.h @@ -105,79 +105,81 @@ #endif /* #if (!defined (LLC_TRACE) && !defined (LLC_DATA_BYTES)) */ -/* If the below MACRO (RECV_NR_CHECK_ENABLE) is -ENABLED : then check for the NR frame received from PN544 in the I frame is - added. This shall be greater than sent NS from the HOST. - This is used to stop the timer -DISABLED : dont check the N9R) frame received from the PN544 +/* If the below MACRO (RECV_NR_CHECK_ENABLE) is +DEFINED : then check for the NR frame received from PN544 in the I frame is + added. This shall be greater than sent NS from the HOST. + This is used to stop the timer +COMMENTED : dont check the N(R) frame received from the PN544 */ /* #define RECV_NR_CHECK_ENABLE */ -/* If the below MACRO (LLC_UPP_LAYER_NTFY_WRITE_RSP_CB) is -ENABLED : then if an I frame is received and the - upper layer response callback (before another READ is pended) is called - only after sending S frame and wait for the callback and then notify the +/* If the below MACRO (LLC_UPP_LAYER_NTFY_WRITE_RSP_CB) is +DEFINED : then if an I frame is received and the + upper layer response callback (before another READ is pended) is called + only after sending S frame and wait for the callback and then notify the upper layer -DISABLED : then if an I frame is received and the - upper layer response callback (before another READ is pended) is called - immediately after sending S frame (not waiting for the sent S frame +COMMENTED : then if an I frame is received and the + upper layer response callback (before another READ is pended) is called + immediately after sending S frame (not waiting for the sent S frame callback) */ -#define LLC_UPP_LAYER_NTFY_WRITE_RSP_CB +/* #define LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ -/* PN544 continuously sends an incorrect I frames to the HOST, +/* PN544 continuously sends an incorrect I frames to the HOST, even after the REJ frame from HOST to PN544 -If the below MACRO (LLC_RR_INSTEAD_OF_REJ) is -ENABLED : then if the received NS = (expected NR - 1) then instead of REJ +If the below MACRO (LLC_RR_INSTEAD_OF_REJ) is +DEFINED : then if the received NS = (expected NR - 1) then instead of REJ RR frame is sent -DISABLED : then REJ frame is sent +COMMENTED : then REJ frame is sent */ #define LLC_RR_INSTEAD_OF_REJ #define SEND_UFRAME -/* If the below MACRO (CTRL_WIN_SIZE_COUNT) is -ENABLED : then window size will be maximum -DISABLED : then window size is 1 +/* If the below MACRO (CTRL_WIN_SIZE_COUNT) is +DEFINED : then window size will be maximum +COMMENTED : then window size is 1 */ #define CTRL_WIN_SIZE_COUNT /* If the below MACRO (LLC_URSET_NO_DELAY) is -ENABLED : then after receiving the UA frame, then immediately this will be +DEFINED : then after receiving the UA frame, then immediately this will be notified or further operation will be carried on. -DISABLED : then after receiving the UA frame, then a timer is started, to +COMMENTED : then after receiving the UA frame, then a timer is started, to delay the notifiation or to carry on the next operation */ #define LLC_URSET_NO_DELAY -#ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB - - /* NO definition is required */ - -#else - /* - This macro is useful only if the LLC_UPP_LAYER_NTFY_WRITE_RSP_CB is DISABLED If the below MACRO (LLC_RELEASE_FLAG) is - ENABLED : then whenever LLC release is called the g_release_flag variable - will be made TRUE. Also, NO notification is allowed to the +DEFINED : then whenever LLC release is called the g_release_flag variable + will be made TRUE. Also, NO notification is allowed to the upper layer. - DISABLED : g_release_flag is not declared and not used +COMMENTED : g_release_flag is not declared and not used */ #define LLC_RELEASE_FLAG -#endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ /* - Actually, there is a send and receive error count, if either of them reaches + Actually, there is a send and receive error count, if either of them reaches limit, then exception is raised. If the below MACRO (LLC_RSET_INSTEAD_OF_EXCEPTION) is - ENABLED : then exception is not raised, instead a U RSET command is sent. - DISABLED : then exception is raised +DEFINED : then exception is not raised, instead a U RSET command is sent. +COMMENTED : then exception is raised */ /* #define LLC_RSET_INSTEAD_OF_EXCEPTION */ +#ifndef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB + /* + If the below MACRO (PIGGY_BACK) is + DEFINED : After receiving I frame, wait till the ACK timer to expire to send an ACK to PN544. + COMMENTED : immediately ACK the received I frame + */ + #define PIGGY_BACK + +#endif /* LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ + #define LLC_SEND_ERROR_COUNT #define RECV_ERROR_FRAME_COUNT (0x50U) @@ -191,7 +193,7 @@ DISABLED : then after receiving the UA frame, then a timer is started, to #define PH_LLCNFC_CRC_LENGTH (2) #define PH_LLCNFC_MAX_LLC_PAYLOAD ((PH_LLCNFC_MAX_IFRAME_BUFLEN) + (4)) /** Maximum timer used in the Llc */ -#define PH_LLCNFC_MAX_TIMER_USED (2) +#define PH_LLCNFC_MAX_TIMER_USED (3) /** Maximum timer used in the Llc */ #define PH_LLCNFC_MAX_ACK_GUARD_TIMER (4) /** Maximum I frame that can be stored */ @@ -496,7 +498,7 @@ typedef struct phLlcNfc_Timerinfo #ifdef PIGGY_BACK /** This will store the ack time out values */ - uint16_t ack_to_value[PH_LLCNFC_MAX_ACK_GUARD_TIMER]; + uint16_t ack_to_value; #endif /* #ifdef PIGGY_BACK */ /** This is a timer flag @@ -547,6 +549,9 @@ typedef struct phLlcNfc_Frame /** Store the I frames, that has been received, Storage will be till the window size */ phLlcNfc_StoreIFrame_t s_recv_store; + + /** Response received count to send the ACK once it reaches the window size */ + uint8_t resp_recvd_count; #endif /* #ifdef PIGGY_BACK */ /** To receive the packet sent by below layer */ diff --git a/src/phLlcNfc_Frame.c b/src/phLlcNfc_Frame.c index 81eb1ff..af61761 100644 --- a/src/phLlcNfc_Frame.c +++ b/src/phLlcNfc_Frame.c @@ -52,7 +52,6 @@ #ifdef LLC_RELEASE_FLAG extern uint8_t g_release_flag; #endif /* #ifdef LLC_RELEASE_FLAG */ - /************************ End of global variables *****************************/ /*********************** Local functions ****************************/ @@ -107,28 +106,6 @@ phLlcNfc_H_ProcessSFrame ( /** * \ingroup grp_hal_nfc_llc_helper * -* \brief LLC component <b>Create S frame</b> function -* -* \copydoc page_reg This is a helper function which, creates the S frame -* -* \param[in/out] psFrameInfo Generic frame information -* \param[in/out] cmdType Command type of S frame -* -* \retval NFCSTATUS_SUCCESS Operation successful. -* \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. -* -*/ -static -NFCSTATUS -phLlcNfc_H_CreateSFramePayload ( - phLlcNfc_Frame_t *psFrameInfo, - phLlcNfc_LlcCmd_t cmdType -); - - -/** -* \ingroup grp_hal_nfc_llc_helper -* * \brief LLC helper functions <b>Update I frame list</b> function * * \copydoc page_reg This function checks the nr value with the stored I frames @@ -433,10 +410,10 @@ phLlcNfc_H_CreateUFramePayload ( return result; } -static NFCSTATUS phLlcNfc_H_CreateSFramePayload ( phLlcNfc_Frame_t *psFrameInfo, + phLlcNfc_LlcPacket_t *psLlcPacket, phLlcNfc_LlcCmd_t cmdType ) { @@ -451,7 +428,7 @@ phLlcNfc_H_CreateSFramePayload ( phLlcNfc_Buffer_t *ps_llc_buf = NULL; uint8_t length = 0; - ps_llc_buf = &(psFrameInfo->s_llcpacket.s_llcbuf); + ps_llc_buf = &(psLlcPacket->s_llcbuf); /* Initial S frame header */ ps_llc_buf->sllcpayload.llcheader = PH_LLCNFC_S_HEADER_INIT; @@ -467,11 +444,10 @@ phLlcNfc_H_CreateSFramePayload ( (ps_llc_buf->sllcpayload.llcheader | (uint8_t)cmdType); /* Maximum S frame length */ - psFrameInfo->s_llcpacket.llcbuf_len = (uint8_t) - PH_LLCNFC_MAX_S_FRAME_LEN; + psLlcPacket->llcbuf_len = (uint8_t)PH_LLCNFC_MAX_S_FRAME_LEN; /* S frame length byte value */ ps_llc_buf->llc_length_byte = (uint8_t) - (psFrameInfo->s_llcpacket.llcbuf_len - 1); + (psLlcPacket->llcbuf_len - 1); /* psFrameInfo->s_llcpacket.s_llcbuf : @@ -493,7 +469,7 @@ phLlcNfc_H_CreateSFramePayload ( (psFrameInfo->s_llcpacket.llcbuf_len - 3) : is the array index of the second CRC byte to be calculated */ - length = psFrameInfo->s_llcpacket.llcbuf_len; + length = psLlcPacket->llcbuf_len; phLlcNfc_H_ComputeCrc( (uint8_t *)ps_llc_buf, (length - 2), &(ps_llc_buf->sllcpayload.llcpayload[(length - 4)]), @@ -760,7 +736,7 @@ phLlcNfc_H_SendUserIFrame ( { NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Frame_t *ps_frame_info = NULL; - phLlcNfc_LlcPacket_t *ps_create_packet = NULL; + phLlcNfc_LlcPacket_t s_create_packet; phLlcNfc_LlcPacket_t *ps_get_packet = NULL; phLlcNfc_Payload_t *ps_llc_payload = NULL; phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; @@ -778,7 +754,6 @@ phLlcNfc_H_SendUserIFrame ( else { ps_frame_info = &(psLlcCtxt->s_frameinfo); - ps_create_packet = &(ps_frame_info->s_llcpacket); ps_store_frame = &(ps_frame_info->s_send_store); if ( @@ -788,7 +763,7 @@ phLlcNfc_H_SendUserIFrame ( { /* Get the stored I frame, only if the new frame is sent from the upper layer */ - result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, + result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, ps_frame_info->n_s); } @@ -800,25 +775,25 @@ phLlcNfc_H_SendUserIFrame ( llc_header = (uint8_t)(llc_header | ps_frame_info->n_r); /* Create the packet */ - (void)memcpy ((void *)ps_create_packet, (void *)ps_get_packet, + (void)memcpy ((void *)&(s_create_packet), (void *)ps_get_packet, sizeof (phLlcNfc_LlcPacket_t)); - ps_create_packet->s_llcbuf.sllcpayload.llcheader = llc_header; - ps_llc_payload = &(ps_create_packet->s_llcbuf.sllcpayload); + s_create_packet.s_llcbuf.sllcpayload.llcheader = llc_header; + ps_llc_payload = &(s_create_packet.s_llcbuf.sllcpayload); /* Length of the complete llc buffer, sent to PN544 */ - length = ps_create_packet->llcbuf_len; + length = s_create_packet.llcbuf_len; /* Compute CRC for the created packet */ - phLlcNfc_H_ComputeCrc ((uint8_t *)&(ps_create_packet->s_llcbuf), + phLlcNfc_H_ComputeCrc ((uint8_t *)&(s_create_packet.s_llcbuf), (length - 2), (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)])); /* Send the i frame */ - result = phLlcNfc_Interface_Write (psLlcCtxt, - (uint8_t *)&(ps_create_packet->s_llcbuf), - (uint32_t)ps_create_packet->llcbuf_len); + result = phLlcNfc_Interface_Write (psLlcCtxt, + (uint8_t *)&(s_create_packet.s_llcbuf), + (uint32_t)s_create_packet.llcbuf_len); ps_frame_info->write_status = result; @@ -865,7 +840,7 @@ phLlcNfc_H_SendRejectedIFrame ( { NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Frame_t *ps_frame_info = NULL; - phLlcNfc_LlcPacket_t *ps_create_packet = NULL; + phLlcNfc_LlcPacket_t s_create_packet; phLlcNfc_LlcPacket_t *ps_get_packet = NULL; phLlcNfc_Payload_t *ps_llc_payload = NULL; phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; @@ -883,7 +858,6 @@ phLlcNfc_H_SendRejectedIFrame ( else { ps_frame_info = &(psLlcCtxt->s_frameinfo); - ps_create_packet = &(ps_frame_info->s_llcpacket); ps_store_frame = &(ps_frame_info->s_send_store); @@ -898,7 +872,7 @@ phLlcNfc_H_SendRejectedIFrame ( ps_store_frame->s_llcpacket[ns_rejected].frame_to_send) { /* Above check is added to know only if */ - result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, + result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, ns_rejected); } else @@ -918,25 +892,25 @@ phLlcNfc_H_SendRejectedIFrame ( llc_header = (uint8_t)(llc_header | ps_frame_info->n_r); /* Create the packet */ - (void)memcpy ((void *)ps_create_packet, (void *)ps_get_packet, + (void)memcpy ((void *)&(s_create_packet), (void *)ps_get_packet, sizeof (phLlcNfc_LlcPacket_t)); - ps_create_packet->s_llcbuf.sllcpayload.llcheader = llc_header; - ps_llc_payload = &(ps_create_packet->s_llcbuf.sllcpayload); + s_create_packet.s_llcbuf.sllcpayload.llcheader = llc_header; + ps_llc_payload = &(s_create_packet.s_llcbuf.sllcpayload); /* Length of the complete llc buffer, sent to PN544 */ - length = ps_create_packet->llcbuf_len; + length = s_create_packet.llcbuf_len; /* Compute CRC for the created packet */ - phLlcNfc_H_ComputeCrc ((uint8_t *)&(ps_create_packet->s_llcbuf), + phLlcNfc_H_ComputeCrc ((uint8_t *)&(s_create_packet.s_llcbuf), (length - 2), (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)])); /* Send the i frame */ result = phLlcNfc_Interface_Write (psLlcCtxt, - (uint8_t *)&(ps_create_packet->s_llcbuf), - (uint32_t)ps_create_packet->llcbuf_len); + (uint8_t *)&(s_create_packet.s_llcbuf), + (uint32_t)s_create_packet.llcbuf_len); ps_frame_info->write_status = result; @@ -946,7 +920,7 @@ phLlcNfc_H_SendRejectedIFrame ( so update the below variable */ ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t) (((ns_rejected != ps_store_frame->start_pos) && - (resend_i_frame != ps_frame_info->write_wait_call))? + (resend_i_frame != ps_frame_info->write_wait_call))? rejected_i_frame : ps_frame_info->write_wait_call); } else @@ -1009,7 +983,7 @@ phLlcNfc_H_SendTimedOutIFrame ( NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Frame_t *ps_frame_info = NULL; phLlcNfc_Timerinfo_t *ps_timer_info = NULL; - phLlcNfc_LlcPacket_t *ps_create_packet = NULL; + phLlcNfc_LlcPacket_t s_create_packet; phLlcNfc_LlcPacket_t *ps_get_packet = NULL; phLlcNfc_Payload_t *ps_llc_payload = NULL; phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; @@ -1033,7 +1007,6 @@ phLlcNfc_H_SendTimedOutIFrame ( ps_frame_info = &(psLlcCtxt->s_frameinfo); ps_timer_info = &(psLlcCtxt->s_timerinfo); - ps_create_packet = &(ps_frame_info->s_llcpacket); ps_store_frame = &(ps_frame_info->s_send_store); timer_index = ps_timer_info->index_to_send; @@ -1043,16 +1016,17 @@ phLlcNfc_H_SendTimedOutIFrame ( PH_LLCNFC_DEBUG("SEND TIMEOUT CALL WIN SIZE CNT : 0x%02X\n", ps_store_frame->winsize_cnt); PH_LLCNFC_DEBUG("SEND TIMEOUT CALL START POS : 0x%02X\n", ps_store_frame->start_pos); PH_LLCNFC_DEBUG("SEND TIMEOUT CALL N S value : 0x%02X\n", ps_frame_info->n_s); + PH_LLCNFC_DEBUG("SEND TIMEOUT TIMER INDEX : 0x%02X\n", timer_index); PH_LLCNFC_DEBUG("SEND TIMEOUT CALL frame type : 0x%02X\n", ps_timer_info->frame_type[timer_index]); if (resend_i_frame == ps_timer_info->frame_type[timer_index]) { /* Get the stored I frame */ - result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, + result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet, ns_index); } - PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Packet : 0x%02X\n", ps_get_packet); + PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Packet : 0x%p\n", ps_get_packet); if (NULL != ps_get_packet) { llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader; @@ -1061,25 +1035,25 @@ phLlcNfc_H_SendTimedOutIFrame ( llc_header = (uint8_t)(llc_header | ps_frame_info->n_r); /* create the packet */ - (void)memcpy ((void *)ps_create_packet, (void *)ps_get_packet, + (void)memcpy ((void *)&(s_create_packet), (void *)ps_get_packet, sizeof (phLlcNfc_LlcPacket_t)); - ps_create_packet->s_llcbuf.sllcpayload.llcheader = llc_header; - ps_llc_payload = &(ps_create_packet->s_llcbuf.sllcpayload); + s_create_packet.s_llcbuf.sllcpayload.llcheader = llc_header; + ps_llc_payload = &(s_create_packet.s_llcbuf.sllcpayload); /* Length of the complete llc buffer, sent to PN544 */ - length = ps_create_packet->llcbuf_len; + length = s_create_packet.llcbuf_len; /* Compute CRC */ - phLlcNfc_H_ComputeCrc((uint8_t *)&(ps_create_packet->s_llcbuf), + phLlcNfc_H_ComputeCrc((uint8_t *)&(s_create_packet.s_llcbuf), (length - 2), - (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), + (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]), (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)])); /* Send the i frame */ result = phLlcNfc_Interface_Write (psLlcCtxt, - (uint8_t *)&(ps_create_packet->s_llcbuf), - (uint32_t)ps_create_packet->llcbuf_len); + (uint8_t *)&(s_create_packet.s_llcbuf), + (uint32_t)s_create_packet.llcbuf_len); ps_frame_info->write_status = result; PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Write status : 0x%02X\n", result); @@ -1102,9 +1076,9 @@ phLlcNfc_H_SendTimedOutIFrame ( PH_LLCNFC_DEBUG("SEND TIMEOUT CALL timer index : 0x%02X\n", timer_index); - PH_LLCNFC_DEBUG("SEND TIMEOUT CALL GUARD TO VALUE : 0x%02X\n", ps_timer_info->guard_to_value[(timer_index - 1)]); if (timer_index > 0) { + PH_LLCNFC_DEBUG("SEND TIMEOUT CALL GUARD TO VALUE : 0x%02X\n", ps_timer_info->guard_to_value[(timer_index - 1)]); /* Copy the maximum time-out value. */ time_out_value = (uint16_t) ((ps_timer_info->guard_to_value[(timer_index - 1)] >= @@ -1206,18 +1180,12 @@ phLlcNfc_H_ProcessIFrame ( phLlcNfc_eSentFrameType_t eframe_type = invalid_frame; uint8_t dont_send_s_frame = FALSE; uint8_t no_of_del_frames = 0; - phNfc_sCompletionInfo_t notifyinfo = {0}; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; #ifdef RECV_NR_CHECK_ENABLE uint8_t recvd_nr = 0; #endif /* #ifdef RECV_NR_CHECK_ENABLE */ -#ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB - /* Nothing required in this define */ -#else - uint8_t prev_local_nr = 0; -#endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ - ps_frame_info = &(psLlcCtxt->s_frameinfo); ps_store_frame = &(ps_frame_info->s_send_store); ps_recv_pkt = &(ps_frame_info->s_recvpacket); @@ -1259,12 +1227,6 @@ phLlcNfc_H_ProcessIFrame ( phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames); } -#ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB - /* Nothing required in this define */ -#else - prev_local_nr = ps_frame_info->n_r; -#endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ - /* Received buffer, N(S) value = N(R) of host (our structure) then send RR type of s frame else send REJ type of s frame */ @@ -1290,7 +1252,6 @@ phLlcNfc_H_ProcessIFrame ( ps_recv_pkt->s_llcbuf.sllcpayload.llcpayload), psLlcCtxt->recvbuf_length); - #if defined (LLC_SEND_RR_ACK) if (((ns_index < ps_frame_info->n_r) && @@ -1309,6 +1270,11 @@ phLlcNfc_H_ProcessIFrame ( ps_frame_info->n_r = ((ps_frame_info->n_r + 1) % PH_LLCNFC_MOD_NS_NR); +#ifdef PIGGY_BACK + ps_frame_info->resp_recvd_count = (uint8_t) + (ps_frame_info->resp_recvd_count + 1); +#endif /* #ifdef PIGGY_BACK */ + } if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status)) @@ -1334,9 +1300,7 @@ phLlcNfc_H_ProcessIFrame ( { dont_send_s_frame = TRUE; #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB - phLlcNfc_H_SendInfo (psLlcCtxt); - #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ } else @@ -1349,15 +1313,10 @@ phLlcNfc_H_ProcessIFrame ( resend_s_frame : s_frame); } -#ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB - - /* Nothing required in this define */ - -#else /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ - +#ifdef PIGGY_BACK phLlcNfc_H_SendInfo (psLlcCtxt); +#endif /* #ifdef PIGGY_BACK */ -#endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */ } else { @@ -1374,8 +1333,8 @@ phLlcNfc_H_ProcessIFrame ( #ifdef LLC_RR_INSTEAD_OF_REJ if (((ps_frame_info->n_r > 0) && (ns_index == (ps_frame_info->n_r - 1))) - || (0 == ps_frame_info->n_r) && - (ns_index == (PH_LLCNFC_MOD_NS_NR - 1))) + || ((0 == ps_frame_info->n_r) && + (ns_index == (PH_LLCNFC_MOD_NS_NR - 1)))) { cmdtype = phLlcNfc_e_rr; eframe_type = rej_rr_s_frame; @@ -1425,23 +1384,61 @@ phLlcNfc_H_ProcessIFrame ( #endif /* #ifdef LLC_RELEASE_FLAG */ { - result = phLlcNfc_Interface_Read(psLlcCtxt, + (void)phLlcNfc_Interface_Read(psLlcCtxt, PH_LLCNFC_READWAIT_OFF, &(ps_recv_pkt->s_llcbuf.llc_length_byte), (uint8_t)PH_LLCNFC_BYTES_INIT_READ); +#ifdef PIGGY_BACK + /* Check if any write call is performed or not */ + if (NFCSTATUS_PENDING != result) + { + /* No write is performed, So, now check */ + if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status)) + { + /* Any how write cannot be done and some frame is ready to be sent + so this frame will act as the ACK */ + result = phLlcNfc_H_WriteWaitCall (psLlcCtxt); + } + } + + if (NFCSTATUS_PENDING != result) + { + if (ps_frame_info->window_size == ps_frame_info->resp_recvd_count) + { + phLlcNfc_LlcPacket_t s_packet_info; + /* Create S frame */ + (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), cmdtype); + result = phLlcNfc_Interface_Write(psLlcCtxt, + (uint8_t *)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); + + + if (0 == ps_frame_info->send_error_count) + { + ps_frame_info->write_wait_call = invalid_frame; + } + ps_frame_info->sent_frame_type = eframe_type; + } + else + { + result = phLlcNfc_StartTimers (PH_LLCNFC_ACKTIMER, 0); + } + } +#else /* #ifdef PIGGY_BACK */ if ((TRUE != ps_frame_info->write_pending) && (PH_LLCNFC_READPEND_REMAIN_BYTE != ps_frame_info->read_pending) && (FALSE == dont_send_s_frame)) { + phLlcNfc_LlcPacket_t s_packet_info = {0}; /* Create S frame */ - (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, cmdtype); + (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), cmdtype); result = phLlcNfc_Interface_Write(psLlcCtxt, - (uint8_t *)&(ps_frame_info->s_llcpacket.s_llcbuf), - (uint32_t)(ps_frame_info->s_llcpacket.llcbuf_len)); + (uint8_t *)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); if (0 == ps_frame_info->send_error_count) @@ -1450,6 +1447,7 @@ phLlcNfc_H_ProcessIFrame ( } ps_frame_info->sent_frame_type = eframe_type; } +#endif /* #ifdef PIGGY_BACK */ } return ; @@ -1465,7 +1463,7 @@ phLlcNfc_H_ProcessUFrame ( phLlcNfc_Frame_t *ps_frame_info = NULL; phLlcNfc_LlcPacket_t *ps_uframe_pkt = NULL; #ifdef LLC_URSET_NO_DELAY - phNfc_sCompletionInfo_t notifyinfo = {0}; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; #else /* #ifdef LLC_URSET_NO_DELAY */ uint32_t delay_timer_id = PH_OSALNFC_INVALID_TIMER_ID; @@ -1580,12 +1578,12 @@ phLlcNfc_H_ProcessSFrame ( #if 0 prev_win_count = 0; #endif /* #if 0 */ - phNfc_sTransactionInfo_t compinfo = {0}; + phNfc_sTransactionInfo_t compinfo = {0, 0, 0, 0, 0}; phLlcNfc_Frame_t *ps_frame_info = NULL; phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; uint8_t no_of_del_frames = 0; - phNfc_sCompletionInfo_t notifyinfo = {0}; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; ps_frame_info = &(psLlcCtxt->s_frameinfo); ps_recv_pkt = &(ps_frame_info->s_recvpacket); @@ -1962,13 +1960,16 @@ phLlcNfc_H_SendRejectFrame( ) { NFCSTATUS result = NFCSTATUS_SUCCESS; + phLlcNfc_LlcPacket_t s_packet_info = {0}; + result = phLlcNfc_H_CreateSFramePayload( - &(psLlcCtxt->s_frameinfo), + &(psLlcCtxt->s_frameinfo), + &(s_packet_info), phLlcNfc_e_rej); /* Send the "S" frame to the lower layer */ result = phLlcNfc_Interface_Write(psLlcCtxt, - (uint8_t *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf), - (uint32_t)(psLlcCtxt->s_frameinfo.s_llcpacket.llcbuf_len)); + (uint8_t *)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); if (NFCSTATUS_PENDING == result) { @@ -2160,23 +2161,22 @@ phLlcNfc_H_SendRSETFrame ( ) { NFCSTATUS result = NFCSTATUS_SUCCESS; - phLlcNfc_LlcPacket_t *ps_packet_info = NULL; + phLlcNfc_LlcPacket_t s_packet_info; phLlcNfc_Frame_t *ps_frame_info = NULL; ps_frame_info = &(psLlcCtxt->s_frameinfo); - ps_packet_info = &(psLlcCtxt->s_frameinfo.s_llcpacket); - result = phLlcNfc_H_CreateUFramePayload(psLlcCtxt, - ps_packet_info, - &(ps_packet_info->llcbuf_len), + result = phLlcNfc_H_CreateUFramePayload(psLlcCtxt, + &(s_packet_info), + &(s_packet_info.llcbuf_len), phLlcNfc_e_rset); if (NFCSTATUS_SUCCESS == result) { /* Call DAL write */ - result = phLlcNfc_Interface_Write(psLlcCtxt, - (uint8_t*)&(ps_packet_info->s_llcbuf), - (uint32_t)ps_packet_info->llcbuf_len); + result = phLlcNfc_Interface_Write(psLlcCtxt, + (uint8_t*)&(s_packet_info.s_llcbuf), + (uint32_t)s_packet_info.llcbuf_len); } ps_frame_info->write_status = result; diff --git a/src/phLlcNfc_Frame.h b/src/phLlcNfc_Frame.h index e1662df..e76e017 100644 --- a/src/phLlcNfc_Frame.h +++ b/src/phLlcNfc_Frame.h @@ -264,6 +264,7 @@ phLlcNfc_H_CreateUFramePayload ( * * \param[in/out] psFrameInfo Information related to LLC frames are stored * in this structure +* \param[in/out] psLlcPacket Llc packet sent by the upper layer * \param[in] pLlcBuf User given buffer or the buffer which needs LLC framing * \param[in] llcBufLength Length of the parameter "pLlcBuf" * @@ -427,6 +428,28 @@ phLlcNfc_H_SendRejectedIFrame ( /** * \ingroup grp_hal_nfc_llc_helper * +* \brief LLC component <b>Create S frame</b> function +* +* \copydoc page_reg This is a helper function which, creates the S frame +* +* \param[in/out] psFrameInfo Generic frame information +* \param[in/out] psLlcPacket Llc packet sent by the upper layer +* \param[in/out] cmdType Command type of S frame +* +* \retval NFCSTATUS_SUCCESS Operation successful. +* \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid. +* +*/ +NFCSTATUS +phLlcNfc_H_CreateSFramePayload ( + phLlcNfc_Frame_t *psFrameInfo, + phLlcNfc_LlcPacket_t *psLlcPacket, + phLlcNfc_LlcCmd_t cmdType +); + +/** +* \ingroup grp_hal_nfc_llc_helper +* * \brief LLC Send upper layer information function * * \copydoc page_reg Sends received information to the upper layer frame. diff --git a/src/phLlcNfc_Interface.c b/src/phLlcNfc_Interface.c index 92be48d..a1e9938 100644 --- a/src/phLlcNfc_Interface.c +++ b/src/phLlcNfc_Interface.c @@ -48,7 +48,6 @@ /***************************** Macros *******************************/ #define PH_LLCNFC_APPEND_LEN (4) #define LLC_NS_FRAME_HEADER_MASK (0x38U) - /************************ End of macros *****************************/ /*********************** Local functions ****************************/ @@ -81,8 +80,8 @@ phLlcNfc_Interface_Register( ) { NFCSTATUS result = NFCSTATUS_SUCCESS; - phNfcIF_sCallBack_t if_cb; - phNfcIF_sReference_t sreference; + phNfcIF_sCallBack_t if_cb = {0,0,0,0}; + phNfcIF_sReference_t sreference = {0,0,0}; if ((NULL == psLlcCtxt) || (NULL == psIFConfig)) { @@ -223,8 +222,8 @@ phLlcNfc_Interface_Write( (0 == llcBufferLength) || (NULL == psLlcCtxt->lower_if.send)) { - PH_LLCNFC_DEBUG ("psLlcCtxt : 0x%08X\n", psLlcCtxt); - PH_LLCNFC_DEBUG ("pLlcBuffer : 0x%08X\n", pLlcBuffer); + PH_LLCNFC_DEBUG ("psLlcCtxt : 0x%p\n", psLlcCtxt); + PH_LLCNFC_DEBUG ("pLlcBuffer : 0x%p\n", pLlcBuffer); PH_LLCNFC_DEBUG ("llcBufferLength : 0x%08X\n", llcBufferLength); result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER); } @@ -247,13 +246,24 @@ phLlcNfc_Interface_Write( PH_LLCNFC_STRING (";\n"); #endif /* LLC_DATA_BYTES */ + + psLlcCtxt->s_frameinfo.s_llcpacket.llcbuf_len = (uint8_t)llcBufferLength; + (void)memcpy ((void *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf), + (void *)pLlcBuffer, llcBufferLength); + result = psLlcCtxt->lower_if.send(psLlcCtxt->lower_if.pcontext, psLlcCtxt->phwinfo, - pLlcBuffer, + (uint8_t *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf), (uint16_t)llcBufferLength); if(NFCSTATUS_PENDING == result) { psLlcCtxt->s_frameinfo.write_pending = TRUE; +#ifdef PIGGY_BACK + /* Stop the ACK timer, as the ACK or I frame is sent */ + phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0); + /* ACK is sent, so reset the response received count */ + psLlcCtxt->s_frameinfo.resp_recvd_count = 0; +#endif /* #ifdef PIGGY_BACK */ } } } @@ -279,7 +289,7 @@ phLlcNfc_WrResp_Cb( phLlcNfc_Frame_t *ps_frame_info = NULL; phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; phLlcNfc_StoreIFrame_t *ps_store_frame = NULL; - phNfc_sCompletionInfo_t notifyinfo; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; uint8_t count = 0; PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB CALLED\n\n"); @@ -497,6 +507,7 @@ phLlcNfc_WrResp_Cb( } else { + /* ***** This notification needs to be disabled ***** */ if(NULL != ps_llc_ctxt->cb_for_if.send_complete) { pCompInfo->length = (pCompInfo->length - @@ -650,7 +661,7 @@ phLlcNfc_RdResp_Cb( phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; phLlcNfc_Payload_t *ps_llc_payload = NULL; pphNfcIF_Notification_CB_t notifyul = NULL; - phNfc_sCompletionInfo_t notifyinfo; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB CALLED\n\n"); @@ -932,7 +943,7 @@ phLlcNfc_H_SendInfo ( { phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL; phLlcNfc_Frame_t *ps_frame_info = NULL; - phNfc_sTransactionInfo_t comp_info; + phNfc_sTransactionInfo_t comp_info = {0,0,0,0,0}; ps_frame_info = &(psLlcCtxt->s_frameinfo); ps_recv_pkt = &(ps_frame_info->s_recvpacket); diff --git a/src/phLlcNfc_Timer.c b/src/phLlcNfc_Timer.c index 9a596b4..06ca7e4 100644 --- a/src/phLlcNfc_Timer.c +++ b/src/phLlcNfc_Timer.c @@ -44,8 +44,6 @@ /***************************** Macros *******************************/ /**< Timer for connection timer index */ #define PH_LLCNFC_CONNECTION_TO_INDEX (0x00) -/**< 0x0A Timer for ack time out value */ -#define PH_LLCNFC_ACK_TO_VALUE (1000) /**< Maximum guard timer can be present */ #define PH_LLCNFC_MAX_GUARD_TIMER (0x04) /** Connection time out bit to set */ @@ -60,6 +58,8 @@ #define PH_LLCNFC_CON_TO_BIT_VAL (0x01) /** Guard time out bit to set */ #define PH_LLCNFC_GUARD_TO_BIT_VAL (0x02) +/** ACK time out bit to set */ +#define PH_LLCNFC_ACK_TO_BIT_VAL (0x04) #define GUARD_TO_URSET @@ -84,7 +84,7 @@ void phLlcNfc_AckTimeoutCb ( uint32_t TimerId ); -#endif +#endif /* #ifdef PIGGY_BACK */ /* This callback is for connection time out */ static @@ -290,17 +290,22 @@ phLlcNfc_StartTimers ( /* Get the ack timer flag */ timerstarted = (uint8_t)GET_BITS8 ( ps_timer_info->timer_flag, - PH_LLCNFC_GUARD_TO_BIT, + PH_LLCNFC_ACK_TO_BIT, PH_LLCNFC_TO_NOOFBITS); - if (0 == timerstarted) + + if (FALSE == timerstarted) { /* Timer not started, so start the timer */ ps_timer_info->timer_flag = (uint8_t) SET_BITS8 (ps_timer_info->timer_flag, - PH_LLCNFC_GUARD_TO_BIT - PH_LLCNFC_TO_NOOFBITS - (PH_LLCNFC_GUARD_TO_BIT - 1)); + PH_LLCNFC_ACK_TO_BIT, + PH_LLCNFC_TO_NOOFBITS, + (PH_LLCNFC_ACK_TO_BIT - 1)); } + + + timer_resolution = ps_timer_info->ack_to_value = (uint16_t) + PH_LLCNFC_ACK_TO_VALUE; timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER]; Callback = (ppCallBck_t)&phLlcNfc_AckTimeoutCb; break; @@ -380,7 +385,7 @@ phLlcNfc_StopTimers ( { /* The number of guard timer count is more than the guard timer to delete */ - while (start_index < no_of_guard_to_del) + while (start_index < (timer_count - no_of_guard_to_del)) { /* Copy the previous stored timer values to the present */ ps_timer_info->guard_to_value[start_index] = (uint16_t) @@ -457,11 +462,14 @@ phLlcNfc_StopTimers ( #ifdef PIGGY_BACK case PH_LLCNFC_ACKTIMER: { + timerflag = (timerflag & PH_LLCNFC_ACK_TO_BIT_VAL); + ps_timer_info->timer_flag = (uint8_t) SET_BITS8 (ps_timer_info->timer_flag, - PH_LLCNFC_GUARD_TO_BIT, + PH_LLCNFC_ACK_TO_BIT, PH_LLCNFC_TO_NOOFBITS, 0); timerid = ps_timer_info->timer_id[PH_LLCNFC_ACKTIMER]; + ps_timer_info->ack_to_value = 0; break; } #endif /* #ifdef PIGGY_BACK */ @@ -486,7 +494,7 @@ phLlcNfc_StopTimers ( PHNFC_UNUSED_VARIABLE (result); PHNFC_UNUSED_VARIABLE (TimerType); - PHNFC_UNUSED_VARIABLE (no_of_gaurd_to_del); + PHNFC_UNUSED_VARIABLE (no_of_guard_to_del); #endif /* #ifdef LLC_TIMER_ENABLE */ } @@ -602,23 +610,25 @@ phLlcNfc_GuardTimeoutCb ( NFCSTATUS result = NFCSTATUS_SUCCESS; phLlcNfc_Timerinfo_t *ps_timer_info = NULL; phLlcNfc_Frame_t *ps_frame_info = NULL; - phLlcNfc_LlcPacket_t *ps_packet_info = NULL; + phLlcNfc_LlcPacket_t s_packet_info; uint8_t index = 0; + /* zero_to_index = Time out index has become 0 */ uint8_t zero_to_index = 0; + #if defined (GUARD_TO_ERROR) - phNfc_sCompletionInfo_t notifyinfo = {0}; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; #endif /* #if defined (GUARD_TO_ERROR) */ - PHNFC_UNUSED_VARIABLE(pContext); PH_LLCNFC_PRINT("\n\nLLC : GUARD TIMEOUT CB CALLED \n\n"); - if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == - gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_GUARDTIMER]) && - (PH_LLCNFC_GUARD_TO_BIT_VAL == - (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & + if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == + gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_GUARDTIMER]) && + (PH_LLCNFC_GUARD_TO_BIT_VAL == + (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & PH_LLCNFC_GUARD_TO_BIT_VAL))) { uint8_t timer_expired = FALSE; + ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); @@ -632,8 +642,15 @@ phLlcNfc_GuardTimeoutCb ( send called */ while (index < ps_timer_info->guard_to_count) { + /* This loop runs for all the timer present in the data structure. + This means if there are 2 I frame has been sent and + response is not received for the I frames sent then the + each time this timer expires, the time out value is decremented + by the PH_LLCNFC_RESOLUTION value */ if (0 != ps_timer_info->guard_to_value[index]) { + /* If timer value is not zero then enter, + this means that the value is not zero */ if (ps_timer_info->guard_to_value[index] > 0) { if (ps_timer_info->guard_to_value[index] >= @@ -651,10 +668,20 @@ phLlcNfc_GuardTimeoutCb ( if (0 == ps_timer_info->guard_to_value[index]) { + /* Timer value has expired, so resend has to be done + Timer value is 0 */ + ps_timer_info->frame_type[index] = (uint8_t)resend_i_frame; + if (FALSE == timer_expired) + { + /* As the statement is in the loop, so there are possibilities + of more than 1 timer value can be 0, so if previous timer + value has already been 0, then again dont change the + index */ zero_to_index = index; timer_expired = TRUE; } } + } index = (uint8_t)(index + 1); } @@ -686,7 +713,6 @@ phLlcNfc_GuardTimeoutCb ( timer_count = ps_timer_info->guard_to_count; - /* Check before changing the index to resend, if index already exist then dont set the index */ while ((FALSE == while_exit) && (start_index < timer_count)) @@ -702,13 +728,29 @@ phLlcNfc_GuardTimeoutCb ( } } - if (TRUE == while_exit) + if (FALSE == while_exit) { + /* This " ps_timer_info->index_to_send " member is + useful, when 2 time out values are 0, then + only first timed out value has to be resent and + other has to wait until the the first timed out + I frame is resent + This statement is executed only if, none of the timer + has expires previously, this is the first timer in the + list that has time out value has 0 + */ ps_timer_info->index_to_send = zero_to_index; } + else + { + /* This statement is executed only if, any one of the time + out value was 0 previously, so first resend has to be done + for the previous I frame, so the index is set to the previous + I frame + */ + ps_timer_info->index_to_send = start_index; + } - ps_timer_info->frame_type[zero_to_index] = (uint8_t) - resend_i_frame; /* Now resend the frame stored */ result = phLlcNfc_H_SendTimedOutIFrame (gpphLlcNfc_Ctxt, &(ps_frame_info->s_send_store), @@ -741,16 +783,15 @@ phLlcNfc_GuardTimeoutCb ( #if (!defined (GUARD_TO_ERROR) && defined (GUARD_TO_URSET)) PH_LLCNFC_PRINT("U-RSET IS SENT \n"); - ps_packet_info = &(gpphLlcNfc_Ctxt->s_frameinfo.s_llcpacket); - result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, - ps_packet_info, - &(ps_packet_info->llcbuf_len), + result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, + &(s_packet_info), + &(s_packet_info.llcbuf_len), phLlcNfc_e_rset); - result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, - (uint8_t*)&(ps_packet_info->s_llcbuf), - (uint32_t)ps_packet_info->llcbuf_len); + result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, + (uint8_t*)&(s_packet_info.s_llcbuf), + (uint32_t)s_packet_info.llcbuf_len); ps_frame_info->write_status = result; if (NFCSTATUS_PENDING == result) @@ -782,15 +823,71 @@ phLlcNfc_GuardTimeoutCb ( } #ifdef PIGGY_BACK + static void phLlcNfc_AckTimeoutCb ( uint32_t TimerId ) { + NFCSTATUS result = NFCSTATUS_SUCCESS; + phLlcNfc_Frame_t *ps_frame_info = NULL; + phLlcNfc_Timerinfo_t *ps_timer_info = NULL; + phLlcNfc_LlcPacket_t s_packet_info; + + PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB CALLED\n\n"); + if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == + gpphLlcNfc_Ctxt->s_timerinfo.timer_id[PH_LLCNFC_ACKTIMER]) + && (PH_LLCNFC_ACK_TO_BIT_VAL == + (gpphLlcNfc_Ctxt->s_timerinfo.timer_flag & + PH_LLCNFC_ACK_TO_BIT_VAL))) + { + ps_frame_info = &(gpphLlcNfc_Ctxt->s_frameinfo); + ps_timer_info = &(gpphLlcNfc_Ctxt->s_timerinfo); + + phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0); + + if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status)) + { + /* Any how write cannot be done and some frame is ready to be sent + so this frame will act as the ACK */ + result = phLlcNfc_H_WriteWaitCall (gpphLlcNfc_Ctxt); + } + else + { + /* Create S frame */ + (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), phLlcNfc_e_rr); + + result = phLlcNfc_Interface_Write(gpphLlcNfc_Ctxt, + (uint8_t *)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); + + if (NFCSTATUS_PENDING == result) + { + if (0 == ps_frame_info->send_error_count) + { + ps_frame_info->write_wait_call = invalid_frame; + } + ps_frame_info->sent_frame_type = s_frame; + } + else + { + if (invalid_frame == ps_frame_info->write_wait_call) + { + ps_frame_info->write_wait_call = s_frame; + } + } + } + } + + /* ACK is sent, so reset the response received count */ + gpphLlcNfc_Ctxt->s_frameinfo.resp_recvd_count = 0; + + PH_LLCNFC_PRINT("\n\nLLC : ACK TIMEOUT CB END\n\n"); } -#endif + +#endif /* #ifdef PIGGY_BACK */ static void @@ -800,12 +897,12 @@ phLlcNfc_ConnectionTimeoutCb ( ) { NFCSTATUS result = NFCSTATUS_SUCCESS; - phNfc_sCompletionInfo_t notifyinfo = {0}; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; pphNfcIF_Notification_CB_t notifyul = NULL; void *p_upperctxt = NULL; phLlcNfc_Frame_t *ps_frame_info = NULL; phLlcNfc_Timerinfo_t *ps_timer_info = NULL; - PHNFC_UNUSED_VARIABLE(pContext); + phLlcNfc_LlcPacket_t s_packet_info; PH_LLCNFC_PRINT("\n\nLLC : CONNECTION TIMEOUT CB CALLED\n\n"); if ((NULL != gpphLlcNfc_Ctxt) && (TimerId == @@ -834,16 +931,16 @@ phLlcNfc_ConnectionTimeoutCb ( { /* Create a U frame */ result = phLlcNfc_H_CreateUFramePayload(gpphLlcNfc_Ctxt, - &(ps_frame_info->s_llcpacket), - &(ps_frame_info->s_llcpacket.llcbuf_len), + &(s_packet_info), + &(s_packet_info.llcbuf_len), phLlcNfc_e_rset); if (NFCSTATUS_SUCCESS == result) { /* Call DAL write */ result = phLlcNfc_Interface_Write (gpphLlcNfc_Ctxt, - (uint8_t*)&(ps_frame_info->s_llcpacket.s_llcbuf), - (uint32_t)(ps_frame_info->s_llcpacket.llcbuf_len)); + (uint8_t*)&(s_packet_info.s_llcbuf), + (uint32_t)(s_packet_info.llcbuf_len)); } if (NFCSTATUS_PENDING == result) { @@ -927,7 +1024,7 @@ phLlcNfc_URSET_Delay_Notify ( void *pContext) { phLlcNfc_Frame_t *ps_frame_info = NULL; - phNfc_sCompletionInfo_t notifyinfo = {0}; + phNfc_sCompletionInfo_t notifyinfo = {0,0,0}; if (NULL != gpphLlcNfc_Ctxt) { diff --git a/src/phLlcNfc_Timer.h b/src/phLlcNfc_Timer.h index d8f702a..f212a32 100644 --- a/src/phLlcNfc_Timer.h +++ b/src/phLlcNfc_Timer.h @@ -56,6 +56,12 @@ /**< 0x05 Timer for guard time out value */ #define PH_LLCNFC_GUARD_TO_VALUE LINK_GUARD_TIMEOUT +#ifdef PIGGY_BACK + +#define PH_LLCNFC_ACK_TO_VALUE LINK_ACK_TIMEOUT + +#endif /* #ifdef PIGGY_BACK */ + #ifdef LLC_RESET_DELAY #define LLC_URSET_DELAY_TIME_OUT LLC_RESET_DELAY #else @@ -201,8 +207,10 @@ phLlcNfc_DeleteTimer (void); void phLlcNfc_URSET_Delay_Notify ( - uint32_t delay_id, - void *pContext); + + uint32_t delay_id); + + #endif /* #ifdef LLC_URSET_NO_DELAY */ |