Reconcile with gingerbread-release gingerbread-mr4-release

Change-Id: Ibcd6e2299e3f03df1a5320041404a42a20546a57
diff --git a/Android.mk b/Android.mk
index 8f64cba..2c2220b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,7 +6,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PRELINK_MODULE := false
 LOCAL_ARM_MODE := arm
 
 #phLibNfc
@@ -105,24 +104,23 @@
 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 -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -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 -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -fpic
-# Quiet:
-LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -DINCLUDE_DALINIT_DEINIT -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -Werror-implicit-function-declaration  -fno-strict-aliasing -mapcs -mno-sched-prolog -mabi=aapcs-linux -mno-thumb-interwork -msoft-float -Uarm -fno-common -fpic
+LOCAL_CFLAGS += -DNXP_MESSAGING -DANDROID -fno-strict-aliasing
 
-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
+# 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
@@ -141,8 +139,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_PRELINK_MODULE := false
-
 LOCAL_SRC_FILES += src/phFriNfc_NdefRecord.c
 
 LOCAL_CFLAGS += -I$(LOCAL_PATH)/inc
@@ -153,4 +149,3 @@
 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 6d3c9fb..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 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 @@
                                 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        result = NFCSTATUS_SUCCESS;
 
+    refresh_low_level_traces();
+
     if ((NULL != pContext) && (NULL != pHwRef))
     {
         pContext  = pgDalContext;
@@ -282,7 +312,7 @@
    return result;
 }
 
-NFCSTATUS phDal4Nfc_ConfigRelease( void *pHwRef)
+NFCSTATUS phDal4Nfc_ConfigRelease(void *pHwRef)
 {
 
    NFCSTATUS result = NFCSTATUS_SUCCESS;
@@ -292,19 +322,23 @@
 
    if (gDalContext.hw_valid == TRUE)
    {
-      DAL_PRINT("Release Read Semaphore");
-      sem_post(&nfc_read_sem);
+       /* Signal the read and write threads to exit.  NOTE: there
+          actually is no write thread!  :)  */
+       DAL_PRINT("Stop Reader Thread");
+       gReadWriteContext.nReadThreadAlive = 0;
+       gReadWriteContext.nWriteThreadAlive = 0;
 
-       /* Kill the read and write threads */
-      DAL_PRINT("Stop Reader Thread");
-      gReadWriteContext.nReadThreadAlive = 0;
-      gReadWriteContext.nWriteThreadAlive = 0;
+       /* Wake up the read thread so it can exit */
+       DAL_PRINT("Release Read Semaphore");
+       sem_post(&nfc_read_sem);
 
-      if (pthread_join(gReadWriteContext.nReadThread,  &pThreadReturn) != 0)
-      {
-         result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_FAILED);
-         DAL_PRINT("phDal4Nfc_ConfigRelease  KO");
-      }
+       DAL_DEBUG("phDal4Nfc_ConfigRelease - doing pthread_join(%d)",
+                 gReadWriteContext.nReadThread);
+       if (pthread_join(gReadWriteContext.nReadThread,  &pThreadReturn) != 0)
+       {
+           result = PHNFCSTVAL(CID_NFC_DAL, NFCSTATUS_FAILED);
+           DAL_PRINT("phDal4Nfc_ConfigRelease  KO");
+       }
 
       /* Close the message queue */
 #ifdef USE_MQ_MESSAGE_QUEUE
@@ -526,7 +560,6 @@
          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;
@@ -583,6 +616,7 @@
 
    gDalContext.hw_valid = TRUE;
 
+   phDal4Nfc_Reset(1);
    phDal4Nfc_Reset(0);
    phDal4Nfc_Reset(1);
 
@@ -600,7 +634,7 @@
 {
    NFCSTATUS	retstatus = NFCSTATUS_SUCCESS;
 
-   DAL_DEBUG("phDal4Nfc_Reset: VEN to %d",level);
+   DAL_DEBUG("phDal4Nfc_Reset: VEN to %ld",level);
 
    retstatus = gLinkFunc.reset(level);
 
@@ -677,12 +711,20 @@
 	DAL_PRINT("RX Thread Sem Lock\n");
         sem_wait(&nfc_read_sem);
         DAL_PRINT("RX Thread Sem UnLock\n");
+
+        if (!gReadWriteContext.nReadThreadAlive)
+        {
+            /* got the signal that we should exit.  NOTE: we don't
+               attempt to read below, since the read may block */
+            break;
+        }
+
         /* Issue read operation.*/
 
     i2c_error_count = 0;
 retry:
 	gReadWriteContext.nNbOfBytesRead=0;
-	DAL_DEBUG("\n*New *** *****Request Length = %d",gReadWriteContext.nNbOfBytesToRead);
+	DAL_DEBUG("RX Thread *New *** *****Request Length = %d",gReadWriteContext.nNbOfBytesToRead);
 	memsetRet=memset(gReadWriteContext.pReadBuffer,0,gReadWriteContext.nNbOfBytesToRead);
 
 	/* Wait for IRQ !!!  */
@@ -696,28 +738,30 @@
     if(gReadWriteContext.nNbOfBytesToRead == 1 && gReadWriteContext.pReadBuffer[0] == 0x57)
     {
         i2c_error_count++;
-        DAL_DEBUG("Read 0x57 %d times\n", i2c_error_count);
+        DAL_DEBUG("RX Thread Read 0x57 %d times\n", i2c_error_count);
         if (i2c_error_count < 5) {
             usleep(2000);
             goto retry;
         }
-        DAL_PRINT("NOTHING TO READ, RECOVER");
+        DAL_PRINT("RX Thread NOTHING TO READ, RECOVER");
         phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
     }
     else
     {
         i2c_error_count = 0;
-#ifdef LOW_LEVEL_TRACES
-        phOsalNfc_PrintData("Received buffer", (uint16_t)gReadWriteContext.nNbOfBytesRead, gReadWriteContext.pReadBuffer);
-#endif
-        DAL_DEBUG("Read ok. nbToRead=%d\n", gReadWriteContext.nNbOfBytesToRead);
-        DAL_DEBUG("NbReallyRead=%d\n", gReadWriteContext.nNbOfBytesRead);
-        DAL_PRINT("ReadBuff[]={ ");
+
+        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[]={ ");
         for (i = 0; i < gReadWriteContext.nNbOfBytesRead; i++)
         {
-          DAL_DEBUG("0x%x ", gReadWriteContext.pReadBuffer[i]);
+          DAL_DEBUG("RX Thread 0x%x ", gReadWriteContext.pReadBuffer[i]);
         }
-        DAL_PRINT("}\n");
+        DAL_PRINT("RX Thread }\n"); */
 
         /* read completed immediately */
         sMsg.eMsgType= PHDAL4NFC_READ_MESSAGE;
@@ -729,6 +773,9 @@
     }
 
     } /* End of thread Loop*/
+
+    DAL_PRINT("RX Thread  exiting");
+
     return TRUE;
 }
 
@@ -851,9 +898,10 @@
         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 */
@@ -878,12 +926,12 @@
                 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)
@@ -952,4 +1000,3 @@
 }
 
 #undef _DAL_4_NFC_C
-
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 @@
 
 int phDal4Nfc_i2c_read(uint8_t * pBuffer, int nNbBytesToRead)
 {
-   int ret;
-   DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "read called but not opened!");
+    int ret;
+    int numRead = 0;
+    struct timeval tv;
+    fd_set rfds;
 
-   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;
+    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 @@
 
 int phDal4Nfc_i2c_write(uint8_t * pBuffer, int nNbBytesToWrite)
 {
-   int ret;
-   DAL_ASSERT_STR(gI2cPortContext.nOpened == 1, "write called but not opened!");
+    int ret;
+    int numWrote = 0;
 
-   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;
+    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 @@
 -----------------------------------------------------------------------------*/
 int phDal4Nfc_i2c_reset(long level)
 {
-   int ret = NFCSTATUS_SUCCESS;   
+    DAL_DEBUG("phDal4Nfc_i2c_reset, VEN level = %ld", level);
 
-   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);
-   }
-
-   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 @@
    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 @@
           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;
+    int ret;
+    int numRead = 0;
+    struct timeval tv;
+    fd_set rfds;
 
-   DAL_ASSERT_STR(gComPortContext.nOpened == 1, "read called but not opened!");
+    DAL_ASSERT_STR(gComPortContext.nOpened == 1, "read called but not opened!");
+    DAL_DEBUG("_uart_read() called to read %d bytes", nNbBytesToRead);
 
-   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;
+    // 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 @@
 
 int phDal4Nfc_uart_write(uint8_t * pBuffer, int nNbBytesToWrite)
 {
-   fd_set wfds;
-   struct timeval tv;
-   int ret;
+    int ret;
+    int numWrote = 0;
 
-   DAL_ASSERT_STR(gComPortContext.nOpened == 1, "write called but not opened!");
+    DAL_ASSERT_STR(gComPortContext.nOpened == 1, "write called but not opened!");
+    DAL_DEBUG("_uart_write() called to write %d bytes\n", nNbBytesToWrite);
 
-   FD_ZERO(&wfds);
-   FD_SET(gComPortContext.nHandle, &wfds);
+    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;
+        }
+    }
 
-   /* 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;
+    return numWrote;
 }
 
 /*-----------------------------------------------------------------------------
@@ -332,24 +360,38 @@
 PURPOSE:  Reset the PN544, using the VEN pin
 
 -----------------------------------------------------------------------------*/
-int phDal4Nfc_uart_reset()
+int phDal4Nfc_uart_reset(long level)
 {
-   DAL_PRINT("phDal4Nfc_uart_reset");
+    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];
 
-   return NFCSTATUS_FEATURE_NOT_SUPPORTED;
+    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_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/phNfcHalTypes.h b/inc/phNfcHalTypes.h
index 748f01b..a242450 100644
--- a/inc/phNfcHalTypes.h
+++ b/inc/phNfcHalTypes.h
@@ -835,7 +835,12 @@
     /* NXP Specific System Information Events */
     NFC_INFO_TXLDO_OVERCUR       = 0x71U,
     NFC_INFO_MEM_VIOLATION       = 0x73U,
-    NFC_INFO_TEMP_OVERHEAT       = 0x74U
+    NFC_INFO_TEMP_OVERHEAT       = 0x74U,
+
+    /* NXP EVENTS */
+    NFC_EVT_MIFARE_ACCESS          = 0x35,
+    NFC_EVT_APDU_RECEIVED          = 0x36,
+    NFC_EVT_EMV_CARD_REMOVAL       = 0x37
 
 }phHal_Event_t;
 
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
old mode 100644
new mode 100755
index 76fd88b..796653e
--- 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 @@
 #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 @@
 
 #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 @@
 
 #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_eSeq
 {
     phDnld_Reset_Seq        = 0x00,
+    phDnld_Activate_Patch,
+    phDnld_Deactivate_Patch,
     phDnld_Update_Patch,
     phDnld_Update_Patchtable,
     phDnld_Lock_System,
@@ -274,7 +285,7 @@
     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 @@
     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 @@
 ******************** 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 @@
 STATIC
 void
 phDnldNfc_Abort (
-                    uint32_t abort_id   ,
-                    void * pcontext
+                    uint32_t abort_id,
+                    void *pContext
                 );
 
 
@@ -796,7 +820,6 @@
                                 phDnldNfc_sContext_t    **ppsDnldContext
                             )
 {
-
     if(NULL != (*ppsDnldContext)->p_resp_buffer)
     {
         phOsalNfc_FreeMemory((*ppsDnldContext)->p_resp_buffer);
@@ -894,7 +917,7 @@
     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,6 +934,32 @@
                                 psDnldContext->cur_dnld_seq;
             break;
         }
+        case DNLD_SEQ_UNLOCK:
+        {
+            psDnldContext->cur_dnld_state =
+                                (uint8_t) phDnld_Reset_State;
+
+#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_LOCK:
         {
             psDnldContext->cur_dnld_state =
@@ -923,18 +972,6 @@
                                 psDnldContext->cur_dnld_seq;
             break;
         }
-        case DNLD_SEQ_UNLOCK:
-        {
-            psDnldContext->cur_dnld_state =
-                                (uint8_t) phDnld_Reset_State;
-            psDnldContext->next_dnld_state =
-                                (uint8_t) phDnld_Unlock_State;
-            psDnldContext->cur_dnld_seq =
-                                (uint8_t) phDnld_Update_Patch;
-            psDnldContext->next_dnld_seq =
-                                psDnldContext->cur_dnld_seq;
-            break;
-        }
         case DNLD_SEQ_UPDATE:
         {
             prev_temp_state = (uint8_t) psDnldContext->cur_dnld_state;
@@ -1107,18 +1144,25 @@
     }
     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 @@
     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 @@
     {
         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 @@
                                &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 @@
         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 @@
         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
             {
+                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 @@
 
             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 @@
             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 @@
 
             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 @@
             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 @@
     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 @@
                                     (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 @@
                 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 @@
                 {
                     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 @@
     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 @@
             {
                 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 @@
         }
         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 @@
             {
                 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 @@
             }
 #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 @@
         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 @@
     return status;
 }
 
+
 static
 NFCSTATUS
 phDnldNfc_Process_FW(
@@ -2648,12 +2807,12 @@
 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_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 @@
                      */
                     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 @@
 
     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 @@
                                               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 @@
 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 @@
 {
     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);
-
 }
 
 
-
 /*!
  * \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 @@
 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 @@
                 (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 @@
             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);
-
-            /* 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);
-
-            switch (ps_iso15693_info->max_data_size)
+            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))
             {
-                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;
-                }
+                result = PHNFCSTVAL (CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_FORMAT);
             }
-            
-            send_index = (uint8_t)(send_index + 1);
+            else
+            {
+                /* prepare data for writing CC bytes */
 
-            send_length = sizeof (a_send_byte);
-            
+                command_type = ISO15693_WR_SINGLE_BLK_CMD;
+                e_format_seq = ISO15693_WRITE_CC_FMT;
+
+                /* CC magic number */
+                *a_send_byte = (uint8_t)ISO15693_CC_MAGIC_NUM;
+                send_index = (uint8_t)(send_index + 1);
+
+                /* CC Version and read/write access */
+                *(a_send_byte + send_index) = (uint8_t) ISO15693_CC_VER_RW;
+                send_index = (uint8_t)(send_index + 1);
+
+                /* 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);
+
+                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;
+                    }
+
+                    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);
+            }
+
             break;
         }
 
@@ -568,16 +562,8 @@
     }
     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_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 @@
                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_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 @@
       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 @@
          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 @@
       /* 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 @@
  /*@{*/
 #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 @@
    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 @@
          case phFriNfc_LlcpTransportSocket_eSocketRejected:
             phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
             break;
+         default: break;
          }
       }
       else
@@ -234,7 +273,6 @@
          phFriNfc_LlcpTransport_Close(&pLlcpTransport->pSocketTable[i]);
       }
    }
-
    return status;
 }
 
@@ -644,6 +682,20 @@
    {
       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 @@
    }
    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 @@
    }
    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_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 @@
          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 @@
                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 @@
             /* 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 @@
             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 @@
             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 @@
             /* 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 @@
             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 @@
             /* 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 @@
             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 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 @@
       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 @@
       /* 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 @@
       /* 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 @@
          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 @@
                   /* 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 @@
                  /* 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 @@
                /* 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 @@
             /* 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 @@
       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 @@
       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 @@
    }
    else
    {
-      /* Send Pending */
-      pLlcpSocket->psTransport->bSendPending = TRUE;
-
       /* Update Send Buffer length value */
       pLlcpSocket->sSocketSendBuffer.length = offset;
 
@@ -2335,8 +2224,7 @@
 
       /* 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 @@
    }
    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 @@
    }
    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 @@
          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 @@
                 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 @@
 #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 ebd447f..341f183 100644
--- a/src/phHal4Nfc.c
+++ b/src/phHal4Nfc.c
@@ -302,15 +302,17 @@
 #include <utils/Log.h>
 #include <dlfcn.h>
 
-const unsigned char *nxp_nfc_full_version;
-const unsigned char *nxp_nfc_fw;
+#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;
     }
 
@@ -1240,7 +1242,10 @@
         case NFC_EVT_START_OF_TRANSACTION:
         case NFC_EVT_END_OF_TRANSACTION:
         case NFC_EVT_CONNECTIVITY:   
-        case NFC_EVT_OPERATION_ENDED:        
+        case NFC_EVT_OPERATION_ENDED:
+        case NFC_EVT_MIFARE_ACCESS:
+        case NFC_EVT_APDU_RECEIVED:
+        case NFC_EVT_EMV_CARD_REMOVAL:
             sNotificationInfo.info = psEventInfo;
             sNotificationInfo.status = NFCSTATUS_SUCCESS;
             sNotificationInfo.type = NFC_EVENT_NOTIFICATION;
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 @@
                         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 @@
     /*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 @@
         /*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 @@
     {
         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 @@
     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 @@
                                 = 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 @@
     }
     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_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 @@
     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 @@
                                                     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 @@
                     }
                     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 @@
             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 @@
         {
             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 @@
             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 @@
             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 @@
     return status;
 }
 
-
 NFCSTATUS
 phHciNfc_Send_Felica_Command(
                               phHciNfc_sContext_t   *psContext,
@@ -908,7 +942,7 @@
                     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
 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 @@
 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 @@
 #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 @@
                 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 @@
 
                 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 @@
                 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 @@
 #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 @@
 #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 @@
                         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 @@
                     )
 {
 
-    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 @@
             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 @@
             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 @@
                           )
 {
     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/phHciNfc_WI.c b/src/phHciNfc_WI.c
index 4da2078..e1310a4 100644
--- a/src/phHciNfc_WI.c
+++ b/src/phHciNfc_WI.c
@@ -63,6 +63,9 @@
 
 /****************** Static Function Declaration **************************/
 
+static uint8_t paypass_removal[2]          = {0x50, 0x00};
+static uint8_t mifare_access               = 0x60;
+
 static 
 NFCSTATUS 
 phHciNfc_Recv_WI_Response(  
@@ -700,12 +703,33 @@
                 EventInfo.eventType = NFC_EVT_TRANSACTION;
                 EventInfo.eventInfo.aid.buffer = (uint8_t *)p_wi_info->aid;
                 /* check for AID data is at least 1 byte is their */
-                if(length > HCP_HEADER_LEN)
+                if (length > HCP_HEADER_LEN)
                 {
                     EventInfo.eventInfo.aid.length = length - HCP_HEADER_LEN;
-                    (void) memcpy((void *)p_wi_info->aid,message->payload,
-                                    EventInfo.eventInfo.aid.length );
+                    memcpy((void *)p_wi_info->aid, message->payload,
+                           EventInfo.eventInfo.aid.length );
                 }
+
+                /* Filter Transaction event */
+                if (EventInfo.eventInfo.aid.length == 4)
+                {
+                    EventInfo.eventType = NFC_EVT_APDU_RECEIVED;
+                }
+                else if (EventInfo.eventInfo.aid.length == 2)
+                {
+                    if (!memcmp(paypass_removal, EventInfo.eventInfo.aid.buffer, EventInfo.eventInfo.aid.length))
+                    {
+                        EventInfo.eventType = NFC_EVT_EMV_CARD_REMOVAL;
+                    }
+                    else if(mifare_access == EventInfo.eventInfo.aid.buffer[0])
+                    {
+                        EventInfo.eventType = NFC_EVT_MIFARE_ACCESS;
+                    }
+                }
+
+                EventInfo.eventInfo.aid.buffer = (uint8_t *)p_wi_info->aid;
+                (void) memcpy((void *)p_wi_info->aid,message->payload,
+                                EventInfo.eventInfo.aid.length );
                 break;
             }
             default:
diff --git a/src/phLibNfc.c b/src/phLibNfc.c
index 9c7db4f..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>
@@ -45,6 +47,8 @@
 *************************** Macro's  ******************************************
 */
 
+extern int dlopen_firmware();
+
 #ifndef STATIC_DISABLE
 #define STATIC static
 #else
@@ -106,6 +110,7 @@
 {
     NFCSTATUS Status = NFCSTATUS_SUCCESS;
 
+    Status = phDal4Nfc_Reset(1);
     Status = phDal4Nfc_Reset(0);
     Status = phDal4Nfc_Reset(1);
 
@@ -117,6 +122,13 @@
    return phDal4Nfc_Download();
 }
 
+int phLibNfc_Load_Firmware_Image ()
+{
+    int status;
+    status = dlopen_firmware();
+    return status;
+}
+
 
 extern uint8_t nxp_nfc_isoxchg_timeout;
 NFCSTATUS phLibNfc_SetIsoXchgTimeout(uint8_t timeout) {
@@ -124,12 +136,40 @@
     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.
 */
@@ -580,6 +620,7 @@
         }
         /* No device is connected */
         gpphLibContext->Connected_handle = 0x00;       
+        gpphLibContext->Prev_Connected_handle = 0x00;
         gpphLibContext->ReleaseType = NFC_INVALID_RELEASE_TYPE;        
         gpphLibContext->eLibNfcCfgMode = NFC_DISCOVERY_STOP;
         /*Lib Nfc Stack is initilized and in idle state*/
@@ -826,10 +867,15 @@
             gpphLibContext->psHwReference->device_info.model_id;        
         (void)memcpy(phLibNfc_StackCapabilities->psDevCapabilities.full_version,
             gpphLibContext->psHwReference->device_info.full_version,NXP_FULL_VERSION_LEN);
-        
         /* Check the firmware version */
-        phLibNfc_StackCapabilities->psDevCapabilities.firmware_update_info = memcmp(phLibNfc_StackCapabilities->psDevCapabilities.full_version, nxp_nfc_full_version,
-                   NXP_FULL_VERSION_LEN);
+        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,
+                       NXP_FULL_VERSION_LEN);
+        }
 
         if(NFCSTATUS_SUCCESS != RetVal)
         {       
diff --git a/src/phLibNfc.h b/src/phLibNfc.h
index 216196f..8621361 100644
--- a/src/phLibNfc.h
+++ b/src/phLibNfc.h
@@ -129,7 +129,10 @@
                                         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;
 
@@ -173,6 +176,12 @@
                                            ETSI TS 102 622 V7.4.0 */
     phLibNfc_eSE_EvtFieldOn,  // consider using phLibNfc_eSE_EvtConnectivity
     phLibNfc_eSE_EvtFieldOff,
+
+    phLibNfc_eSE_EvtApduReceived, /* PAYPASS MagStripe or MCHIP_4 transaction */
+
+    phLibNfc_eSE_EvtCardRemoval, /* Indicates the beginning of an EMV Card Removal sequence */
+
+    phLibNfc_eSE_EvtMifareAccess /* Indicates when the SMX Emulation MIFARE is accessed */
 } phLibNfc_eSE_EvtType_t;
 
 /**
@@ -845,6 +854,8 @@
 
 NFCSTATUS phLibNfc_Download_Mode ();
 
+int phLibNfc_Load_Firmware_Image ();
+
 // timeout is 8 bits
 // bits [0..3] => timeout value, (256*16/13.56*10^6) * 2^value
 //                  [0] -> 0.0003s
@@ -854,7 +865,27 @@
 // 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_Internal.h b/src/phLibNfc_Internal.h
index 10018ec..304ac22 100644
--- a/src/phLibNfc_Internal.h
+++ b/src/phLibNfc_Internal.h
@@ -221,6 +221,9 @@
     uint32_t                     Connected_handle,
                                  Discov_handle[MAX_REMOTE_DEVICES];
 
+    /* To store the previous connected handle in case of Multiple protocol tags */
+    uint32_t Prev_Connected_handle;
+
     /*Call back function pointers */
 
     phLibNfc_eDiscoveryConfigMode_t        eLibNfcCfgMode;
diff --git a/src/phLibNfc_SE.c b/src/phLibNfc_SE.c
index 5fa4e08..968c239 100644
--- a/src/phLibNfc_SE.c
+++ b/src/phLibNfc_SE.c
@@ -135,7 +135,7 @@
 {
     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)
@@ -204,6 +204,51 @@
                             status);
                         break;
                     }
+
+                    case NFC_EVT_APDU_RECEIVED:
+                    {
+                        if ((pEvtInfo->eventInfo.aid.length != 0) && ((pEvtInfo->eventInfo.aid.length <= 16)))
+                        {
+                            /* Copy received APDU to aid buffer. */
+                            Se_Trans_Info.UiccEvtInfo.aid.buffer = pEvtInfo->eventInfo.aid.buffer;
+                            Se_Trans_Info.UiccEvtInfo.aid.length = pEvtInfo->eventInfo.aid.length;
+                        }
+
+                        (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
+                            pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
+                            phLibNfc_eSE_EvtApduReceived,
+                            pSeInfo->hSecureElement,
+                            &Se_Trans_Info,
+                            status);
+                        break;
+                    }
+
+                    case NFC_EVT_MIFARE_ACCESS:
+                    {
+                        /* copy the Block MIFARE accessed */
+                        Se_Trans_Info.UiccEvtInfo.aid.buffer = pEvtInfo->eventInfo.aid.buffer;
+                        Se_Trans_Info.UiccEvtInfo.aid.length = pEvtInfo->eventInfo.aid.length;
+
+                        (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
+                            pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
+                            phLibNfc_eSE_EvtMifareAccess,
+                            pSeInfo->hSecureElement,
+                            &Se_Trans_Info,
+                            status);
+                        break;
+                    }
+
+                    case NFC_EVT_EMV_CARD_REMOVAL:
+                    {
+                        (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
+                            pLibContext->sSeContext.sSeCallabackInfo.pSeListenerCtxt,
+                            phLibNfc_eSE_EvtCardRemoval,
+                            pSeInfo->hSecureElement,
+                            &Se_Trans_Info,
+                            status);
+                        break;
+                    }
+
                     case NFC_EVT_END_OF_TRANSACTION:
                     {
                         (*pLibContext->sSeContext.sSeCallabackInfo.pSeListenerNtfCb)(
@@ -428,7 +473,6 @@
         switch(eActivation_mode)
         {
             case phLibNfc_SE_ActModeVirtual: 
-            case phLibNfc_SE_ActModeDefault:
             {
                 if(hSE_Handle == sSecuredElementInfo[LIBNFC_SE_UICC_INDEX].hSecureElement)
                 {
@@ -462,6 +506,69 @@
                 }
             }
             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 340af78..0f71606 100644
--- a/src/phLibNfc_initiator.c
+++ b/src/phLibNfc_initiator.c
@@ -133,6 +133,10 @@
     {
         Status = NFCSTATUS_FAILED;
     }
+    else if (PHNFCSTATUS(status) == NFCSTATUS_DESELECTED)
+    {
+        return;
+    }
 	else
 	{
 		DeviceIndx=0;DeviceIndx1=0;
@@ -548,6 +552,9 @@
             gpphLibContext->CBInfo.pClientConCntx = pContext;
             gpphLibContext->status.GenCb_pending_status = TRUE;
 			gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;            
+
+            gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
+
 			gpphLibContext->Connected_handle = hRemoteDevice;
          }
          else if (NFCSTATUS_INVALID_REMOTE_DEVICE == PHNFCSTATUS(ret_val))
@@ -633,6 +640,7 @@
             gpphLibContext->CBInfo.pClientConCntx = pContext;
             gpphLibContext->status.GenCb_pending_status=TRUE;
 			gpphLibContext->LibNfcState.next_state = eLibNfcHalStateConnect;            
+            gpphLibContext->Prev_Connected_handle = gpphLibContext->Connected_handle;
 			gpphLibContext->Connected_handle = hRemoteDevice;
          }
          else if(PHNFCSTATUS(RetVal) == NFCSTATUS_INVALID_REMOTE_DEVICE)
@@ -757,6 +765,7 @@
             /* If remote device is invalid return as TARGET LOST to upper layer*/
             /* If error code is other than SUCCESS return NFCSTATUS_TARGET_LOST */
             Connect_status = NFCSTATUS_TARGET_LOST;
+            gpphLibContext->Connected_handle = gpphLibContext->Prev_Connected_handle ;
         }
         gpphLibContext->ndef_cntx.is_ndef = CHK_NDEF_NOT_DONE;
         /* Update the Current Sate*/
@@ -896,6 +905,9 @@
         gpphLibContext->LastTrancvSuccess = FALSE;
         /*Reset Connected handle */
         gpphLibContext->Connected_handle=0x0000;
+        /*Reset previous Connected handle */
+        gpphLibContext->Prev_Connected_handle = 0x0000;
+
         if(gpphLibContext->sSeContext.eActivatedMode == phLibNfc_SE_ActModeWired)
         {
           gpphLibContext->sSeContext.eActivatedMode = phLibNfc_SE_ActModeDefault;
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 @@
                                 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 @@
 {
     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 @@
     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_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 @@
     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 @@
                                 &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 @@
 
 #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 @@
 #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 @@
 
 #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 @@
     /** 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 @@
 /**
 * \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 @@
     return result;
 }
 
-static 
 NFCSTATUS
 phLlcNfc_H_CreateSFramePayload (
     phLlcNfc_Frame_t    *psFrameInfo, 
+    phLlcNfc_LlcPacket_t    *psLlcPacket,
     phLlcNfc_LlcCmd_t   cmdType
 )
 {
@@ -451,7 +428,7 @@
     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 @@
                 (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 @@
         (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 @@
 {
     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 @@
     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 @@
         {
             /* 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 @@
             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 @@
 {
     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 @@
     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 @@
                 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 @@
             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 @@
                     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 @@
     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 @@
 
         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 @@
         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 @@
             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 @@
 
                 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_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_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 @@
                         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 @@
             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 @@
         {
             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 @@
                             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 @@
 #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 @@
 
 #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 @@
             }
             ps_frame_info->sent_frame_type = eframe_type;
         }
+#endif /* #ifdef PIGGY_BACK */
     }
 
     return ;
@@ -1465,7 +1463,7 @@
     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 @@
 #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 @@
                       )
 {
     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 @@
                       )
 {
     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 @@
 *
 * \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 @@
 /**
 * \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 @@
 )
 {
     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 @@
         (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 @@
             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_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 @@
                     }
                     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_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_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 @@
 phLlcNfc_AckTimeoutCb (
     uint32_t TimerId                    
 );
-#endif
+#endif /* #ifdef PIGGY_BACK */
 
 /* This callback is for connection time out */
 static 
@@ -290,17 +290,22 @@
             /* 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 @@
             {
                 /* 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 @@
 #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 @@
 
     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 @@
     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 @@
            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 @@
 
                 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 @@
 
                     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 @@
                         }
                     }
 
-                    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 @@
 #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 @@
 }
 
 #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 @@
 )
 {
     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 @@
                 {
                     /* 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 @@
     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 @@
 
 void 
 phLlcNfc_URSET_Delay_Notify (
-    uint32_t            delay_id,
-    void                *pContext);
+
+    uint32_t            delay_id);
+
+
 
 #endif /* #ifdef LLC_URSET_NO_DELAY */