update NXP se hal for SNxxx am: b20ea5e67f am: 9b6a5a73df am: 28011caa98

Original change: https://android-review.googlesource.com/c/platform/hardware/nxp/secure_element/+/1924041

Change-Id: Iad61ee4bf4abd2eca07f7772ae4cdfbd3d564692
diff --git a/snxxx/1.0/NxpEseService.cpp b/snxxx/1.0/NxpEseService.cpp
index c27b781..52b47a7 100644
--- a/snxxx/1.0/NxpEseService.cpp
+++ b/snxxx/1.0/NxpEseService.cpp
@@ -19,13 +19,13 @@
 #include <android-base/stringprintf.h>
 #include <android/hardware/secure_element/1.0/ISecureElement.h>
 #include <base/logging.h>
-#include <vendor/nxp/nxpese/1.0/INxpEse.h>
-#include "VirtualISO.h"
-
 #include <hidl/LegacySupport.h>
 #include <string.h>
+#include <vendor/nxp/nxpese/1.0/INxpEse.h>
+
 #include "NxpEse.h"
 #include "SecureElement.h"
+#include "VirtualISO.h"
 #include "eSEClient.h"
 
 // Generated HIDL files
@@ -84,15 +84,15 @@
     nxp_se_service = new NxpEse();
     if (nxp_se_service == nullptr) {
       LOG(ERROR) << StringPrintf(
-          "Can not create an instance of NXP Secure Element Extn "
-          "Iface,exiting.");
+          "Can not create an instance of NXP Secure "
+          "Element Extn Iface,exiting.");
       goto shutdown;
     }
     status = nxp_se_service->registerAsService();
     if (status != OK) {
       LOG(ERROR) << StringPrintf(
-          "Could not register service for Power Secure Element Extn Iface "
-          "(%d).",
+          "Could not register service for Power Secure "
+          "Element Extn Iface (%d).",
           status);
       goto shutdown;
     }
diff --git a/snxxx/1.0/SecureElement.cpp b/snxxx/1.0/SecureElement.cpp
index 61f1e7f..18c5176 100755
--- a/snxxx/1.0/SecureElement.cpp
+++ b/snxxx/1.0/SecureElement.cpp
@@ -16,8 +16,10 @@
  *
  ******************************************************************************/
 #include "SecureElement.h"
+
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
+
 #include "NxpEse.h"
 #include "eSEClient.h"
 #include "hal_nxpese.h"
@@ -502,8 +504,7 @@
   LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
   LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
                             mMaxChannelCount, channelNumber);
-  if (channelNumber < DEFAULT_BASIC_CHANNEL ||
-      channelNumber >= mMaxChannelCount) {
+  if (channelNumber >= mMaxChannelCount) {
     LOG(ERROR) << StringPrintf("invalid channel!!! %d for %d", channelNumber,
                                mOpenedChannels[channelNumber]);
     sestatus = SecureElementStatus::FAILED;
@@ -511,6 +512,11 @@
     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
     cpdu.cla = channelNumber; /* Class of instruction */
+    // For Suplementary Channel update CLA byte according to GP
+    if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
+      /* update CLA byte accoridng to GP spec Table 11-12*/
+      cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
+    }
     cpdu.ins = 0x70;          /* Instruction code */
     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
diff --git a/snxxx/1.0/SecureElement.h b/snxxx/1.0/SecureElement.h
index f46b666..44d7e7b 100644
--- a/snxxx/1.0/SecureElement.h
+++ b/snxxx/1.0/SecureElement.h
@@ -24,6 +24,7 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 #include <pthread.h>
+
 #include "phNxpEse_Api.h"
 
 class ThreadMutex {
diff --git a/snxxx/1.0/VirtualISO.cpp b/snxxx/1.0/VirtualISO.cpp
index e92bce8..0b3a383 100644
--- a/snxxx/1.0/VirtualISO.cpp
+++ b/snxxx/1.0/VirtualISO.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  Copyright 2018-2020 NXP
+ *  Copyright 2018-2021 NXP
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
  *
  ******************************************************************************/
 #include "VirtualISO.h"
+
 #include <android-base/logging.h>
+
 #include "NxpEse.h"
 #include "SecureElement.h"
 #include "eSEClient.h"
@@ -446,6 +448,11 @@
     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
     cpdu.cla = channelNumber; /* Class of instruction */
+    // For Suplementary Channel update CLA byte according to GP
+    if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
+      /* update CLA byte accoridng to GP spec Table 11-12*/
+      cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
+    }
     cpdu.ins = 0x70;          /* Instruction code */
     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
diff --git a/snxxx/1.0/VirtualISO.h b/snxxx/1.0/VirtualISO.h
index 9d7438f..322dc6b 100644
--- a/snxxx/1.0/VirtualISO.h
+++ b/snxxx/1.0/VirtualISO.h
@@ -23,6 +23,7 @@
 #include <hardware/hardware.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+
 #include "phNxpEse_Api.h"
 
 namespace vendor {
@@ -72,7 +73,6 @@
     // T=1 stack
     // close(0);
   }
-
  private:
   uint8_t mMaxChannelCount;
   uint8_t mOpenedchannelCount = 0;
diff --git a/snxxx/1.1/NxpEseService.cpp b/snxxx/1.1/NxpEseService.cpp
index dcb1541..3d23bb4 100755
--- a/snxxx/1.1/NxpEseService.cpp
+++ b/snxxx/1.1/NxpEseService.cpp
@@ -17,15 +17,16 @@
  ******************************************************************************/
 #define LOG_TAG "nxpese@1.1-service"
 #include <android/hardware/secure_element/1.1/ISecureElement.h>
-#include <log/log.h>
-#include <vendor/nxp/nxpese/1.0/INxpEse.h>
-#include "VirtualISO.h"
-
 #include <hidl/LegacySupport.h>
+#include <log/log.h>
 #include <string.h>
+#include <vendor/nxp/nxpese/1.0/INxpEse.h>
+
 #include <regex>
+
 #include "NxpEse.h"
 #include "SecureElement.h"
+#include "VirtualISO.h"
 #include "eSEClient.h"
 
 // Generated HIDL files
diff --git a/snxxx/1.1/SecureElement.cpp b/snxxx/1.1/SecureElement.cpp
index 409811f..3a2834c 100755
--- a/snxxx/1.1/SecureElement.cpp
+++ b/snxxx/1.1/SecureElement.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  Copyright 2018-2020 NXP
+ *  Copyright 2018-2021 NXP
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,8 +16,10 @@
  *
  ******************************************************************************/
 #include "SecureElement.h"
+
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
+
 #include "NxpEse.h"
 #include "eSEClient.h"
 #include "hal_nxpese.h"
@@ -565,13 +567,17 @@
   LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
   LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
                             mMaxChannelCount, channelNumber);
-  if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
-      channelNumber >= mMaxChannelCount) {
+  if (channelNumber >= mMaxChannelCount) {
     LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
     cpdu.cla = channelNumber; /* Class of instruction */
+    // For Suplementary Channel update CLA byte according to GP
+    if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
+      /* update CLA byte accoridng to GP spec Table 11-12*/
+      cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
+    }
     cpdu.ins = 0x70;          /* Instruction code */
     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
diff --git a/snxxx/1.1/SecureElement.h b/snxxx/1.1/SecureElement.h
index 5c15da1..4ed0b8f 100755
--- a/snxxx/1.1/SecureElement.h
+++ b/snxxx/1.1/SecureElement.h
@@ -26,6 +26,7 @@
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
 #include <pthread.h>
+
 #include "phNxpEse_Api.h"
 
 class ThreadMutex {
diff --git a/snxxx/1.1/VirtualISO.cpp b/snxxx/1.1/VirtualISO.cpp
index aa0355e..432de16 100755
--- a/snxxx/1.1/VirtualISO.cpp
+++ b/snxxx/1.1/VirtualISO.cpp
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  Copyright 2018-2020 NXP
+ *  Copyright 2018-2021 NXP
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
  *
  ******************************************************************************/
 #include "VirtualISO.h"
+
 #include <android-base/logging.h>
+
 #include "NxpEse.h"
 #include "SecureElement.h"
 #include "eSEClient.h"
@@ -506,6 +508,11 @@
     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
     cpdu.cla = channelNumber; /* Class of instruction */
+    // For Suplementary Channel update CLA byte according to GP
+    if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
+      /* update CLA byte accoridng to GP spec Table 11-12*/
+      cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
+    }
     cpdu.ins = 0x70;          /* Instruction code */
     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
diff --git a/snxxx/1.1/VirtualISO.h b/snxxx/1.1/VirtualISO.h
index 504a535..fa38783 100755
--- a/snxxx/1.1/VirtualISO.h
+++ b/snxxx/1.1/VirtualISO.h
@@ -24,6 +24,7 @@
 #include <hardware/hardware.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+
 #include "phNxpEse_Api.h"
 
 namespace vendor {
@@ -79,7 +80,6 @@
     // T=1 stack
     // close(0);
   }
-
  private:
   uint8_t mMaxChannelCount;
   uint8_t mOpenedchannelCount = 0;
diff --git a/snxxx/1.2/NxpEseService.cpp b/snxxx/1.2/NxpEseService.cpp
index 7e9559a..eba57e0 100755
--- a/snxxx/1.2/NxpEseService.cpp
+++ b/snxxx/1.2/NxpEseService.cpp
@@ -16,20 +16,25 @@
  *
  ******************************************************************************/
 #define LOG_TAG "nxpese@1.2-service"
+#include <android/hardware/nfc/1.2/INfc.h>
 #include <android/hardware/secure_element/1.2/ISecureElement.h>
-#include <log/log.h>
-#include <vendor/nxp/nxpese/1.0/INxpEse.h>
-#include "VirtualISO.h"
-
 #include <hidl/LegacySupport.h>
+#include <log/log.h>
 #include <string.h>
+#include <vendor/nxp/nxpese/1.0/INxpEse.h>
+
 #include <regex>
+
 #include "NxpEse.h"
 #include "SecureElement.h"
+#include "VirtualISO.h"
 #ifdef NXP_BOOTTIME_UPDATE
 #include "eSEClient.h"
 #endif
 
+#define MAX_NFC_GET_RETRY 30
+#define NFC_GET_SERVICE_DELAY_MS 100
+
 // Generated HIDL files
 using android::OK;
 using android::base::StringPrintf;
@@ -37,6 +42,7 @@
 using android::hardware::defaultPassthroughServiceImplementation;
 using android::hardware::joinRpcThreadpool;
 using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::nfc::V1_2::INfc;
 using android::hardware::secure_element::V1_2::ISecureElement;
 using android::hardware::secure_element::V1_2::implementation::SecureElement;
 using vendor::nxp::nxpese::V1_0::INxpEse;
@@ -47,6 +53,25 @@
 using android::sp;
 using android::status_t;
 
+static inline void waitForNFCHAL() {
+  int retry = 0;
+  android::sp<INfc> nfc_service = nullptr;
+
+  ALOGI("Waiting for NFC HAL .. ");
+  do {
+    nfc_service = INfc::tryGetService();
+    if (nfc_service != nullptr) {
+      ALOGI("NFC HAL service is registered");
+      break;
+    }
+    /* Wait for 100 MS for HAL RETRY*/
+    usleep(NFC_GET_SERVICE_DELAY_MS * 1000);
+  } while (retry++ < MAX_NFC_GET_RETRY);
+  if (nfc_service == nullptr) {
+    ALOGE("Failed to get NFC HAL Service");
+  }
+}
+
 int main() {
   status_t status;
 
@@ -58,8 +83,9 @@
   android::sp<INxpEse> nxp_se_service = nullptr;
   android::sp<ISecureElement> virtual_iso_service = nullptr;
 
-  ALOGI("Secure Element HAL Service 1.2 is starting.");
   try {
+    waitForNFCHAL();
+    ALOGI("Secure Element HAL Service 1.2 is starting.");
     se_service = new SecureElement();
     if (se_service == nullptr) {
       ALOGE("Can not create an instance of Secure Element HAL Iface, exiting.");
@@ -104,6 +130,7 @@
       ALOGI("Secure Element Service is ready");
     }
 
+#ifdef NXP_VISO_ENABLE
     ALOGI("Virtual ISO HAL Service 1.0 is starting.");
     virtual_iso_service = new VirtualISO();
     if (virtual_iso_service == nullptr) {
@@ -121,11 +148,12 @@
       if (status != OK) {
         ALOGE("Could not register service for Virtual ISO HAL Iface (%d).",
               status);
-      } else {
-        ALOGI("Virtual ISO: Secure Element Service is ready");
+        goto shutdown;
       }
     }
 
+    ALOGI("Virtual ISO: Secure Element Service is ready");
+#endif
 #ifdef NXP_BOOTTIME_UPDATE
     perform_eSEClientUpdate();
 #endif
diff --git a/snxxx/1.2/OsuHal/inc/OsuHalExtn.h b/snxxx/1.2/OsuHal/inc/OsuHalExtn.h
index 6630d7a..3fb8a72 100644
--- a/snxxx/1.2/OsuHal/inc/OsuHalExtn.h
+++ b/snxxx/1.2/OsuHal/inc/OsuHalExtn.h
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- *  Copyright 2020 NXP
+ *  Copyright 2020-2021 NXP
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -56,9 +56,9 @@
     INIT,
     OPENBASIC,
     OPENLOGICAL,
+    GETATR,
     TRANSMIT,
     CLOSE,
-    RESET,
   } SecureElementAPI;
 
   static OsuHalExtn& getInstance();
@@ -75,6 +75,7 @@
   bool isAppOSUMode;
   bool isJcopOSUMode;
   static const hidl_vec<uint8_t> osu_aid[10];
-  OsuApduMode checkTransmit(uint8_t* input, size_t length, uint32_t* outLength);
+  OsuApduMode checkTransmit(uint8_t* input, uint32_t* outLength,
+                            const hidl_vec<uint8_t>& data);
   bool isOsuMode();
 };
diff --git a/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp b/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp
index 8fcffb7..0411c16 100644
--- a/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp
+++ b/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp
@@ -60,16 +60,21 @@
       }
       break;
     case TRANSMIT:
-      memcpy(pCmdData->p_data, evt.data(), evt.size());
-      if (isOsuMode()) {
-        /*
-         * Process transmit request(unwrap APDU, proprietary actions) in OSU
-         * mode
-         */
-        osuSubState =
-            checkTransmit(pCmdData->p_data, evt.size(), &pCmdData->len);
+      // Validate input data before processing
+      if (pCmdData != NULL && pCmdData->p_data != NULL) {
+        memcpy(pCmdData->p_data, evt.data(), evt.size());
+        if (isOsuMode()) {
+          /*
+           * Process transmit request(unwrap APDU, proprietary actions) in OSU
+           * mode
+           */
+          osuSubState = checkTransmit(pCmdData->p_data, &pCmdData->len, evt);
+        } else {
+          pCmdData->len = evt.size();
+          osuSubState = NON_OSU_MODE;
+        }
       } else {
-        pCmdData->len = evt.size();
+        if (pCmdData != NULL) pCmdData->len = evt.size();
         osuSubState = NON_OSU_MODE;
       }
       break;
@@ -95,6 +100,9 @@
     case OPENLOGICAL:
       // No action, only return current mode
       break;
+    case GETATR:
+      // No action, only return current mode
+      break;
     case CLOSE:
       /*
        * If in OSU mode close basic channel is called
@@ -188,10 +196,15 @@
 ** Returns:     OsuApduMode
 **
 *******************************************************************************/
-OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit(uint8_t* input, size_t length,
-                                                  uint32_t* outLength) {
+OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit(
+    uint8_t* input, uint32_t* outLength, const hidl_vec<uint8_t>& data) {
   OsuHalExtn::OsuApduMode halMode = NON_OSU_MODE;
+  size_t length = data.size();
 
+  // Validate input buffer processing
+  if (input == NULL) {
+    return halMode;
+  }
   /*
    * 1) Transmit request on logical channels(ISO7816_CLA_CHN_MASK)shall be
    *    blocked in OSU mode
@@ -215,8 +228,7 @@
     if (*(input + ISO7816_LC_OFFSET) != 0) {
       if (length > ISO7816_SHORT_APDU_HEADER) {
         *outLength = length - ISO7816_SHORT_APDU_HEADER;
-        memcpy(input, input + ISO7816_SHORT_APDU_HEADER,
-               length - ISO7816_SHORT_APDU_HEADER);
+        std::copy(data.begin() + ISO7816_SHORT_APDU_HEADER, data.end(), input);
       } else {
         *outLength = 0;
         ALOGE("checkTransmit input data length is incorrect");
@@ -224,8 +236,8 @@
     } else {
       if (length > ISO7816_EXTENDED_APDU_HEADER) {
         *outLength = length - ISO7816_EXTENDED_APDU_HEADER;
-        memcpy(input, input + ISO7816_EXTENDED_APDU_HEADER,
-               length - ISO7816_EXTENDED_APDU_HEADER);
+        std::copy(data.begin() + ISO7816_EXTENDED_APDU_HEADER, data.end(),
+                  input);
       } else {
         *outLength = 0;
         ALOGE("checkTransmit input data length is incorrect");
diff --git a/snxxx/1.2/SecureElement.cpp b/snxxx/1.2/SecureElement.cpp
index 4c6756d..520d545 100755
--- a/snxxx/1.2/SecureElement.cpp
+++ b/snxxx/1.2/SecureElement.cpp
@@ -16,15 +16,17 @@
  *
  ******************************************************************************/
 #include "SecureElement.h"
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
+
 #include "NxpEse.h"
-#include "hal_nxpese.h"
-#include "phNxpEse_Apdu_Api.h"
-#include "phNxpEse_Api.h"
 #ifdef NXP_BOOTTIME_UPDATE
 #include "eSEClient.h"
 #endif
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include "hal_nxpese.h"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Api.h"
 /* Mutex to synchronize multiple transceive */
 
 namespace android {
@@ -37,6 +39,7 @@
 #define DEFAULT_BASIC_CHANNEL 0x00
 #define INVALID_LEN_SW1 0x64
 #define INVALID_LEN_SW2 0xFF
+#define SW1_BYTES_REMAINING 0x61
 
 typedef struct gsTransceiveBuffer {
   phNxpEse_data cmdData;
@@ -44,6 +47,9 @@
   hidl_vec<uint8_t>* pRspDataBuff;
 } sTransceiveBuffer_t;
 
+static Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+getResponseInternal(uint8_t cla, phNxpEse_7816_rpdu_t& rpdu,
+                    hidl_vec<uint8_t>& result);
 static sTransceiveBuffer_t gsTxRxBuffer;
 static hidl_vec<uint8_t> gsRspDataBuff(256);
 sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
@@ -198,8 +204,8 @@
   ESESTATUS status = ESESTATUS_FAILED;
   bool mIsSeHalInitDone = false;
 
-  if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >=
-      OsuHalExtn::getInstance().OSU_PROP_MODE) {
+  // In dedicated mode getATR not allowed
+  if (IS_OSU_MODE(OsuHalExtn::getInstance().GETATR)) {
     LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
     _hidl_cb(response);
     return Void();
@@ -336,8 +342,8 @@
 
   LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
 
-  if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >=
-      OsuHalExtn::getInstance().OSU_PROP_MODE) {
+  // In dedicated mode openLogical not allowed
+  if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL)) {
     LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
     _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
     return Void();
@@ -467,6 +473,14 @@
     resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
     resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
 
+    if (rpdu.sw1 == SW1_BYTES_REMAINING) {
+      sestatus =
+          getResponseInternal(cpdu.cla, rpdu, resApduBuff.selectResponse);
+      if (sestatus != SecureElementStatus::SUCCESS) {
+        LOG(ERROR) << "%s: getResponseInternal Failed" << __func__;
+      }
+    }
+
     /*Status is success*/
     if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
         (rpdu.sw1 == 0x63)) {
@@ -609,6 +623,12 @@
     memcpy(&result[0], rpdu.pdata, rpdu.len);
     result[responseLen - 1] = rpdu.sw2;
     result[responseLen - 2] = rpdu.sw1;
+    if (rpdu.sw1 == SW1_BYTES_REMAINING) {
+      sestatus = getResponseInternal(cpdu.cla, rpdu, result);
+      if (sestatus != SecureElementStatus::SUCCESS) {
+        LOG(ERROR) << "%s: getResponseInternal Failed " << __func__;
+      }
+    }
 
     /*Status is success*/
     if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
@@ -660,13 +680,17 @@
   LOG(ERROR) << "Acquired the lock in SPI internalCloseChannel";
   LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
                             mMaxChannelCount, channelNumber);
-  if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
-      channelNumber >= mMaxChannelCount) {
+  if (channelNumber >= mMaxChannelCount) {
     LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
   } else if (channelNumber > DEFAULT_BASIC_CHANNEL) {
     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
     cpdu.cla = channelNumber; /* Class of instruction */
+    // For Suplementary Channel update CLA byte according to GP
+    if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
+      /* update CLA byte accoridng to GP spec Table 11-12*/
+      cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
+    }
     cpdu.ins = 0x70;          /* Instruction code */
     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
@@ -704,8 +728,8 @@
 
 Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
   AutoMutex guard(seHalLock);
-  if (IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber) ==
-      OsuHalExtn::getInstance().NON_OSU_MODE) {
+  // Close internal allowed when not in dedicated Mode
+  if (!IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber)) {
     return internalCloseChannel(channelNumber);
   } else {
     /*Decrement channel count opened to
@@ -825,6 +849,67 @@
   return sestatus;
 }
 
+static Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+getResponseInternal(uint8_t cla, phNxpEse_7816_rpdu_t& rpdu,
+                    hidl_vec<uint8_t>& result) {
+  SecureElementStatus sestatus = SecureElementStatus::SUCCESS;
+  ESESTATUS status = ESESTATUS_SUCCESS;
+  phNxpEse_data cmdApdu;
+  phNxpEse_data rspApdu;
+  uint16_t responseLen = rpdu.len;  // Response already copied
+  uint8_t getRespLe = rpdu.sw2;     // Response pending to receive
+  uint8_t getResponse[5] = {0x00, 0xC0, 0x00, 0x00, 0x00};
+
+  getResponse[0] = cla;
+
+  phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+
+  cmdApdu.len = (uint32_t)sizeof(getResponse);
+  cmdApdu.p_data = getResponse;
+
+  do {
+    // update GET response 61 xx(Le)
+    getResponse[4] = getRespLe;
+
+    phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+    status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+    if (status != ESESTATUS_SUCCESS) {
+      /*Transceive failed*/
+      if (rspApdu.len > 0 && (rspApdu.p_data[rspApdu.len - 2] == 0x64 &&
+                              rspApdu.p_data[rspApdu.len - 1] == 0xFF)) {
+        sestatus = SecureElementStatus::IOERROR;
+      } else {
+        sestatus = SecureElementStatus::FAILED;
+      }
+      break;
+    } else {
+      uint32_t respLen = rspApdu.len;
+
+      // skip 2 bytes in case of 61xx SW again
+      if (rspApdu.p_data[respLen - 2] == SW1_BYTES_REMAINING) {
+        respLen -= 2;
+        getRespLe = rspApdu.p_data[respLen - 1];
+      }
+      // copy response chunk received
+      result.resize(responseLen + respLen);
+      memcpy(&result[responseLen], rspApdu.p_data, respLen);
+      responseLen += respLen;
+    }
+  } while (rspApdu.p_data[rspApdu.len - 2] == SW1_BYTES_REMAINING);
+
+  // Propagate SW as it is received from card
+  if (sestatus == SecureElementStatus::SUCCESS) {
+    rpdu.sw1 = rspApdu.p_data[rspApdu.len - 2];
+    rpdu.sw2 = rspApdu.p_data[rspApdu.len - 1];
+  } else {  // Other Failure cases update failure SW:64FF
+    rpdu.sw1 = INVALID_LEN_SW1;
+    rpdu.sw2 = INVALID_LEN_SW2;
+  }
+
+  return sestatus;
+}
+
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace secure_element
diff --git a/snxxx/1.2/VirtualISO.cpp b/snxxx/1.2/VirtualISO.cpp
index 4550605..44ece57 100755
--- a/snxxx/1.2/VirtualISO.cpp
+++ b/snxxx/1.2/VirtualISO.cpp
@@ -16,15 +16,17 @@
  *
  ******************************************************************************/
 #include "VirtualISO.h"
-#include <android-base/logging.h>
+
+#include "NxpEse.h"
 #include "SecureElement.h"
-#include "phNxpEse_Apdu_Api.h"
-#include "phNxpEse_Api.h"
 #ifdef NXP_BOOTTIME_UPDATE
 #include "eSEClient.h"
 #endif
-#include "NxpEse.h"
+#include <android-base/logging.h>
+
 #include "hal_nxpese.h"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Api.h"
 
 namespace vendor {
 namespace nxp {
@@ -522,6 +524,11 @@
     phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
     phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
     cpdu.cla = channelNumber; /* Class of instruction */
+    // For Suplementary Channel update CLA byte according to GP
+    if ((channelNumber > 0x03) && (channelNumber < 0x14)) {
+      /* update CLA byte accoridng to GP spec Table 11-12*/
+      cpdu.cla = 0x40 + (channelNumber - 4); /* Class of instruction */
+    }
     cpdu.ins = 0x70;          /* Instruction code */
     cpdu.p1 = 0x80;           /* Instruction parameter 1 */
     cpdu.p2 = channelNumber;  /* Instruction parameter 2 */
diff --git a/snxxx/1.2/VirtualISO.h b/snxxx/1.2/VirtualISO.h
index b664fa0..af8b641 100755
--- a/snxxx/1.2/VirtualISO.h
+++ b/snxxx/1.2/VirtualISO.h
@@ -24,6 +24,7 @@
 #include <hardware/hardware.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+
 #include "phNxpEse_Api.h"
 
 namespace vendor {
@@ -77,7 +78,6 @@
     // T=1 stack
     // close(0);
   }
-
  private:
   uint8_t mMaxChannelCount;
   uint8_t mOpenedchannelCount = 0;
diff --git a/snxxx/Android.bp b/snxxx/Android.bp
index 6e7cbd6..1713d67 100755
--- a/snxxx/Android.bp
+++ b/snxxx/Android.bp
@@ -39,6 +39,7 @@
         "vendor.nxp.nxpnfc@2.0",
         "android.hardware.nfc@1.0",
         "android.hardware.nfc@1.1",
+        "android.hardware.nfc@1.2",
     ],
 
     local_include_dirs: [
@@ -52,9 +53,11 @@
         "libese-spi/p73/spm",
         "libese-spi/src/include",
         "1.2/OsuHal/inc",
-        "extns/impl",
     ],
 
+    include_dirs: [
+        "hardware/nxp/secure_element/snxxx/extns/impl",
+    ],
     cflags: [
         "-DANDROID",
         "-DJCOP_VER_3_1=1",
diff --git a/snxxx/ese-clients/inc/eSEClient.h b/snxxx/ese-clients/inc/eSEClient.h
index 425cada..f8752f3 100644
--- a/snxxx/ese-clients/inc/eSEClient.h
+++ b/snxxx/ese-clients/inc/eSEClient.h
@@ -17,6 +17,7 @@
  ******************************************************************************/
 
 #include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h>
+
 #include "../../../secure_element_extns/inc/eSEClientIntf.h"
 #include "phNxpEse_Api.h"
 
diff --git a/snxxx/ese-clients/src/eSEClient.cpp b/snxxx/ese-clients/src/eSEClient.cpp
index f87e80c..1ee1e8c 100644
--- a/snxxx/ese-clients/src/eSEClient.cpp
+++ b/snxxx/ese-clients/src/eSEClient.cpp
@@ -17,6 +17,7 @@
  ******************************************************************************/
 
 #include "eSEClient.h"
+
 #include <IChannel.h>
 #include <JcDnld.h>
 #include <LsClient.h>
@@ -29,6 +30,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <vendor/nxp/nxpnfc/2.0/INxpNfc.h>
+
 #include "NfcAdaptation.h"
 #include "NxpEse.h"
 #include "hal_nxpese.h"
diff --git a/snxxx/extns/impl/NxpEse.cpp b/snxxx/extns/impl/NxpEse.cpp
index c72d162..370ce51 100755
--- a/snxxx/extns/impl/NxpEse.cpp
+++ b/snxxx/extns/impl/NxpEse.cpp
@@ -16,12 +16,13 @@
  *
  ******************************************************************************/
 #include "NxpEse.h"
-#include <android-base/logging.h>
-#include <android-base/stringprintf.h>
-#include "phNxpEse_Api.h"
 #ifdef NXP_BOOTTIME_UPDATE
 #include "eSEClient.h"
 #endif
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include "phNxpEse_Api.h"
 
 namespace vendor {
 namespace nxp {
diff --git a/snxxx/libese-spi/Android.bp b/snxxx/libese-spi/Android.bp
index 1fb7ebf..4563037 100755
--- a/snxxx/libese-spi/Android.bp
+++ b/snxxx/libese-spi/Android.bp
@@ -31,13 +31,15 @@
     ],
 
     local_include_dirs: [
+        "p73/lib",
+        "p73/pal/spi",
+        "p73/utils",
+    ],
+    export_include_dirs: [
         "common/include",
         "p73/common",
         "p73/inc",
-        "p73/lib",
         "p73/pal",
-        "p73/pal/spi",
-        "p73/utils",
         "src/include",
     ],
     include_dirs: [
diff --git a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
index bf1aad2..d6df6da 100755
--- a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
+++ b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
@@ -189,7 +189,7 @@
  * \ingroup ISO7816-3_protocol_lib
  * \brief      This internal function is used to
  *                  1. Send propreitary S-Frame command for resynch
- *T=1 sequence at client
+ *T=1 sequence at worker
  *
  */
 static ESESTATUS phNxpEseProto7816_RSync(void);
@@ -1226,8 +1226,9 @@
     phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = SFRAME;
     if (frameType != WTX_REQ) {
       phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
+      phNxpEseProto7816_ResetRecovery();
     }
-    phNxpEseProto7816_ResetRecovery();
+
     switch (frameType) {
       case RESYNCH_REQ:
         phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
diff --git a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h
index 8a22daa..70f4617 100755
--- a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h
+++ b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h
@@ -193,14 +193,14 @@
   uint8_t numChannels;     /*!< ATR: Number of logical connections supported */
   uint8_t maxIFSC[2];      /*!< ATR: Maximum size of IFS supported */
   uint8_t capabilities[2]; /*!< ATR: Bitmap to indicate various features
-                         supported by SE Bit-1: SE Data Available Line
-                         supported. Bit-2: SE Data available polarity. 1 - Data
-                         available GPIO will be pulled HIGH when SE response is
-                         ready Bit 3: SE chip reset S-blk command supported
-                         Bit-4: Extended frame length feature supported Bit-5:
-                         Support for more than one logical channel Bit 6 to 16:
-                         Reserved for future use
-                         */
+                        supported by SE Bit-1: SE Data Available Line supported.
+                        Bit-2: SE Data available polarity. 1 - Data available
+                        GPIO will be pulled HIGH when SE response is ready Bit
+                        3: SE chip reset S-blk command supported Bit-4: Extended
+                        frame length feature supported Bit-5: Support for more
+                        than one logical channel Bit 6 to 16: Reserved for
+                        future use
+                        */
 } phNxpEseProto7816_ATR_Info_t;
 
 typedef struct phNxpEseProto7816_ATR_Info2 {
diff --git a/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp b/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp
index a5b63d7..da6a0e1 100755
--- a/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp
+++ b/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp
@@ -133,10 +133,10 @@
  *
  * Description      This function is called by Jni/phNxpEse_open during the
  *                  initialization of the ESE. It initializes protocol stack
- *instance variable
+ *                  instance variable
  *
  * Returns          This function return ESESTATUS_SUCCESS (0) in case of
- *success In case of failure returns other failure value.
+ *                  success In case of failure returns other failure value.
  *
  ******************************************************************************/
 ESESTATUS phNxpEse_init(phNxpEse_initParams initParams) {
@@ -278,6 +278,7 @@
  *                  thread for operation.
  * Returns          This function return ESESTATUS_SUCCESS (0) in case of
  *                  success. In case of failure returns other failure values.
+ *
  ******************************************************************************/
 ESESTATUS phNxpEse_open(phNxpEse_initParams initParams) {
   phPalEse_Config_t tPalConfig;
@@ -1381,7 +1382,7 @@
         /*For I-Frame Only*/
         if (0 == pcb_bits.msb) {
           if (pBuffer[2] != EXTENDED_FRAME_MARKER) {
-            nNbBytesToRead = pBuffer[2];
+            nNbBytesToRead = (pBuffer[2] & 0x000000FF);
             headerIndex = 3;
           } else {
             ret = phPalEse_read(pDevHandle, &pBuffer[3], 2);
@@ -1406,7 +1407,7 @@
           }
         } else {
           /*For Non-IFrame*/
-          nNbBytesToRead = (int)pBuffer[2];
+          nNbBytesToRead = (pBuffer[2] & 0x000000FF);
           headerIndex = 3;
         }
         if (!flushData) {
@@ -1535,7 +1536,7 @@
                poll_sof_chained_delay);
     }
     total_count = 3;
-    nNbBytesToRead = (int)pBuffer[2];
+    nNbBytesToRead = (pBuffer[2] & 0x000000FF);
     /* Read the Complete data + one byte CRC*/
     ret = phPalEse_read(pDevHandle, &pBuffer[3], (nNbBytesToRead + 1));
     if (ret < 0) {
diff --git a/snxxx/libese-spi/src/include/NfcAdaptation.h b/snxxx/libese-spi/src/include/NfcAdaptation.h
index 18720f6..10c0545 100644
--- a/snxxx/libese-spi/src/include/NfcAdaptation.h
+++ b/snxxx/libese-spi/src/include/NfcAdaptation.h
@@ -16,13 +16,13 @@
  *
  ******************************************************************************/
 #pragma once
-#include <pthread.h>
-
 #include <android/hardware/nfc/1.0/types.h>
 #include <phEseStatus.h>
 #include <phNxpEseFeatures.h>
+#include <pthread.h>
 #include <utils/RefBase.h>
 #include <vendor/nxp/nxpnfc/2.0/INxpNfc.h>
+
 #include "hal_nxpese.h"
 using vendor::nxp::nxpnfc::V2_0::INxpNfc;