summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranil.hiranniah <anil.hiranniah@nxp.com>2021-03-27 10:45:31 +0530
committerGeorge Chang <georgekgchang@google.com>2021-05-18 02:44:45 +0000
commit167e0ff873df1f7218524ddc8b6a8dd39e38f323 (patch)
treef493f0a60513b2c6ed5cbc46f03e469955f03fdd
parent8803e33ec06cd8eaa99d1c78dbaf3079ad826191 (diff)
downloadsecure_element-167e0ff873df1f7218524ddc8b6a8dd39e38f323.tar.gz
Add SE hal support for SNXXX
Move existing se hal to pn8x/ Add se hal for snxxx in snxxx/ Move existing extns/intf to intf/ Update Android.bp files to build hals for pn8x and snxxx Bug: 188034640 Test: CTS, VTS, NFC On/OFf, Data exchange to SE using OMAPI APIs Merged-In: I8df25d1b743f7bd012ccb021d92880f774581eef Change-Id: I8df25d1b743f7bd012ccb021d92880f774581eef
-rw-r--r--[-rwxr-xr-x]Android.bp191
-rw-r--r--extns/intf/nxpese/1.0/Android.bp24
-rw-r--r--extns/intf/nxpese/Android.bp12
-rw-r--r--intf/nxpese/1.0/Android.bp15
-rw-r--r--intf/nxpese/1.0/INxpEse.hal (renamed from extns/intf/nxpese/1.0/INxpEse.hal)0
-rw-r--r--intf/nxpese/1.0/manifest.xml (renamed from extns/intf/nxpese/1.0/manifest.xml)0
-rw-r--r--intf/nxpese/Android.bp3
-rw-r--r--intf/nxpese/current.txt (renamed from extns/intf/nxpese/current.txt)0
-rwxr-xr-xpn8x/1.0/NxpEseService.cpp (renamed from 1.0/NxpEseService.cpp)8
-rw-r--r--pn8x/1.0/SecureElement.cpp (renamed from 1.0/SecureElement.cpp)3
-rwxr-xr-xpn8x/1.0/SecureElement.h (renamed from 1.0/SecureElement.h)6
-rw-r--r--pn8x/1.0/android.hardware.secure_element@1.0-service-disabled.rc (renamed from 1.0/android.hardware.secure_element@1.0-service-disabled.rc)0
-rw-r--r--pn8x/1.0/android.hardware.secure_element@1.0-service.rc (renamed from 1.0/android.hardware.secure_element@1.0-service.rc)0
-rwxr-xr-xpn8x/1.1/NxpEseService.cpp (renamed from 1.1/NxpEseService.cpp)0
-rw-r--r--pn8x/1.1/SecureElement.cpp (renamed from 1.1/SecureElement.cpp)0
-rwxr-xr-xpn8x/1.1/SecureElement.h (renamed from 1.1/SecureElement.h)0
-rw-r--r--pn8x/1.1/android.hardware.secure_element@1.1-service-disabled.rc (renamed from 1.1/android.hardware.secure_element@1.1-service-disabled.rc)0
-rw-r--r--pn8x/1.1/android.hardware.secure_element@1.1-service.rc (renamed from 1.1/android.hardware.secure_element@1.1-service.rc)0
-rwxr-xr-xpn8x/Android.bp155
-rw-r--r--pn8x/extns/impl/NxpEse.cpp (renamed from extns/impl/NxpEse.cpp)0
-rw-r--r--pn8x/extns/impl/NxpEse.h (renamed from extns/impl/NxpEse.h)8
-rw-r--r--pn8x/extns/impl/hal_nxpese.h (renamed from extns/impl/hal_nxpese.h)4
-rwxr-xr-xpn8x/libese-spi/common/include/phNxpEseFeatures.h (renamed from libese-spi/common/include/phNxpEseFeatures.h)0
-rwxr-xr-xpn8x/libese-spi/p73/common/phEseStatus.h (renamed from libese-spi/p73/common/phEseStatus.h)0
-rwxr-xr-xpn8x/libese-spi/p73/inc/phNxpEse_Api.h (renamed from libese-spi/p73/inc/phNxpEse_Api.h)0
-rwxr-xr-xpn8x/libese-spi/p73/lib/phNxpEseDataMgr.cpp (renamed from libese-spi/p73/lib/phNxpEseDataMgr.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/lib/phNxpEseDataMgr.h (renamed from libese-spi/p73/lib/phNxpEseDataMgr.h)0
-rwxr-xr-xpn8x/libese-spi/p73/lib/phNxpEseProto7816_3.cpp (renamed from libese-spi/p73/lib/phNxpEseProto7816_3.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/lib/phNxpEseProto7816_3.h (renamed from libese-spi/p73/lib/phNxpEseProto7816_3.h)0
-rw-r--r--pn8x/libese-spi/p73/lib/phNxpEse_Api.cpp (renamed from libese-spi/p73/lib/phNxpEse_Api.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/lib/phNxpEse_Internal.h (renamed from libese-spi/p73/lib/phNxpEse_Internal.h)0
-rwxr-xr-xpn8x/libese-spi/p73/libese-nxp-P73.conf (renamed from libese-spi/p73/libese-nxp-P73.conf)0
-rwxr-xr-xpn8x/libese-spi/p73/pal/phNxpEsePal.cpp (renamed from libese-spi/p73/pal/phNxpEsePal.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/pal/phNxpEsePal.h (renamed from libese-spi/p73/pal/phNxpEsePal.h)0
-rwxr-xr-xpn8x/libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp (renamed from libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp)2
-rwxr-xr-xpn8x/libese-spi/p73/pal/spi/phNxpEsePal_spi.h (renamed from libese-spi/p73/pal/spi/phNxpEsePal_spi.h)0
-rwxr-xr-xpn8x/libese-spi/p73/spm/phNxpEse_Spm.cpp (renamed from libese-spi/p73/spm/phNxpEse_Spm.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/spm/phNxpEse_Spm.h (renamed from libese-spi/p73/spm/phNxpEse_Spm.h)0
-rw-r--r--pn8x/libese-spi/p73/utils/config.cpp (renamed from libese-spi/p73/utils/config.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/utils/config.h (renamed from libese-spi/p73/utils/config.h)0
-rwxr-xr-xpn8x/libese-spi/p73/utils/ese_config.cpp (renamed from libese-spi/p73/utils/ese_config.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/utils/ese_config.h (renamed from libese-spi/p73/utils/ese_config.h)0
-rwxr-xr-xpn8x/libese-spi/p73/utils/ringbuffer.cpp (renamed from libese-spi/p73/utils/ringbuffer.cpp)0
-rwxr-xr-xpn8x/libese-spi/p73/utils/ringbuffer.h (renamed from libese-spi/p73/utils/ringbuffer.h)0
-rwxr-xr-xpn8x/libese-spi/src/adaptation/NfcAdaptation.cpp (renamed from libese-spi/src/adaptation/NfcAdaptation.cpp)2
-rwxr-xr-xpn8x/libese-spi/src/include/NfcAdaptation.h (renamed from libese-spi/src/include/NfcAdaptation.h)0
-rwxr-xr-xpn8x/ls_client/inc/LsClient.h (renamed from ls_client/inc/LsClient.h)0
-rwxr-xr-xpn8x/ls_client/inc/LsLib.h (renamed from ls_client/inc/LsLib.h)0
-rwxr-xr-xpn8x/ls_client/src/LsClient.cpp (renamed from ls_client/src/LsClient.cpp)3
-rwxr-xr-xpn8x/ls_client/src/LsLib.cpp (renamed from ls_client/src/LsLib.cpp)0
-rw-r--r--snxxx/1.0/NxpEseService.cpp127
-rwxr-xr-xsnxxx/1.0/SecureElement.cpp688
-rw-r--r--snxxx/1.0/SecureElement.h113
-rw-r--r--snxxx/1.0/VirtualISO.cpp612
-rw-r--r--snxxx/1.0/VirtualISO.h94
-rw-r--r--snxxx/1.0/android.hardware.secure_element_snxxx@1.0-service.rc4
-rwxr-xr-xsnxxx/1.1/NxpEseService.cpp132
-rwxr-xr-xsnxxx/1.1/SecureElement.cpp691
-rwxr-xr-xsnxxx/1.1/SecureElement.h124
-rwxr-xr-xsnxxx/1.1/VirtualISO.cpp655
-rwxr-xr-xsnxxx/1.1/VirtualISO.h105
-rwxr-xr-xsnxxx/1.1/android.hardware.secure_element_snxxx@1.1-service.rc4
-rwxr-xr-xsnxxx/1.2/NxpEseService.cpp145
-rw-r--r--snxxx/1.2/OsuHal/inc/OsuHalExtn.h80
-rw-r--r--snxxx/1.2/OsuHal/src/OsuHalExtn.cpp273
-rwxr-xr-xsnxxx/1.2/SecureElement.cpp832
-rwxr-xr-xsnxxx/1.2/SecureElement.h127
-rwxr-xr-xsnxxx/1.2/VirtualISO.cpp704
-rwxr-xr-xsnxxx/1.2/VirtualISO.h103
-rwxr-xr-xsnxxx/1.2/android.hardware.secure_element_snxxx@1.2-service.rc4
-rwxr-xr-xsnxxx/Android.bp64
-rw-r--r--snxxx/ese-clients/inc/eSEClient.h41
-rw-r--r--snxxx/ese-clients/src/eSEClient.cpp484
-rwxr-xr-xsnxxx/extns/impl/NxpEse.cpp224
-rwxr-xr-xsnxxx/extns/impl/NxpEse.h75
-rwxr-xr-xsnxxx/extns/impl/hal_nxpese.h169
-rwxr-xr-xsnxxx/libese-spi/Android.bp76
-rw-r--r--snxxx/libese-spi/common/include/phNxpEseFeatures.h48
-rw-r--r--snxxx/libese-spi/p73/common/phEseStatus.h222
-rw-r--r--snxxx/libese-spi/p73/inc/phNxpEse_Apdu_Api.h105
-rwxr-xr-xsnxxx/libese-spi/p73/inc/phNxpEse_Api.h459
-rwxr-xr-xsnxxx/libese-spi/p73/lib/phNxpEseDataMgr.cpp165
-rw-r--r--snxxx/libese-spi/p73/lib/phNxpEseDataMgr.h48
-rwxr-xr-xsnxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp2231
-rwxr-xr-xsnxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h623
-rwxr-xr-xsnxxx/libese-spi/p73/lib/phNxpEse_Apdu_Api.cpp270
-rwxr-xr-xsnxxx/libese-spi/p73/lib/phNxpEse_Api.cpp1950
-rw-r--r--snxxx/libese-spi/p73/lib/phNxpEse_Internal.h142
-rw-r--r--snxxx/libese-spi/p73/pal/EseTransport.h139
-rw-r--r--snxxx/libese-spi/p73/pal/EseTransportFactory.cpp41
-rw-r--r--snxxx/libese-spi/p73/pal/EseTransportFactory.h67
-rwxr-xr-xsnxxx/libese-spi/p73/pal/phNxpEsePal.cpp314
-rw-r--r--snxxx/libese-spi/p73/pal/phNxpEsePal.h247
-rw-r--r--snxxx/libese-spi/p73/pal/spi/EseSpiTransport.cpp503
-rw-r--r--snxxx/libese-spi/p73/pal/spi/EseSpiTransport.h34
-rwxr-xr-xsnxxx/libese-spi/p73/spm/phNxpEse_Spm.cpp476
-rw-r--r--snxxx/libese-spi/p73/spm/phNxpEse_Spm.h195
-rw-r--r--snxxx/libese-spi/p73/utils/config.cpp164
-rw-r--r--snxxx/libese-spi/p73/utils/config.h76
-rw-r--r--snxxx/libese-spi/p73/utils/ese_config.cpp87
-rwxr-xr-xsnxxx/libese-spi/p73/utils/ese_config.h69
-rw-r--r--snxxx/libese-spi/p73/utils/ringbuffer.cpp116
-rw-r--r--snxxx/libese-spi/p73/utils/ringbuffer.h62
-rwxr-xr-xsnxxx/libese-spi/src/adaptation/CondVar.cpp135
-rwxr-xr-xsnxxx/libese-spi/src/adaptation/Mutex.cpp122
-rw-r--r--snxxx/libese-spi/src/adaptation/NfcAdaptation.cpp258
-rw-r--r--snxxx/libese-spi/src/include/CondVar.h85
-rw-r--r--snxxx/libese-spi/src/include/Mutex.h106
-rw-r--r--snxxx/libese-spi/src/include/NfcAdaptation.h84
-rw-r--r--snxxx/libese-spi/src/include/SyncEvent.h142
110 files changed, 16746 insertions, 225 deletions
diff --git a/Android.bp b/Android.bp
index d33252c..435a352 100755..100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,170 +1,21 @@
-package {
- default_applicable_licenses: ["hardware_nxp_secure_element_license"],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
- name: "hardware_nxp_secure_element_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-Apache-2.0",
- ],
- // large-scale-change unable to identify any license_text files
-}
-
-cc_library_shared {
-
- name: "ese_spi_nxp",
- defaults: ["hidl_defaults"],
- proprietary: true,
-
- srcs: [
- "libese-spi/p73/lib/phNxpEseDataMgr.cpp",
- "libese-spi/p73/lib/phNxpEseProto7816_3.cpp",
- "libese-spi/p73/lib/phNxpEse_Api.cpp",
- "libese-spi/p73/pal/phNxpEsePal.cpp",
- "libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp",
- "libese-spi/p73/spm/phNxpEse_Spm.cpp",
- "libese-spi/p73/utils/ese_config.cpp",
- "libese-spi/p73/utils/config.cpp",
- "libese-spi/p73/utils/ringbuffer.cpp",
- "libese-spi/src/adaptation/NfcAdaptation.cpp",
- ],
-
- local_include_dirs: [
- "libese-spi/p73/lib",
- "libese-spi/p73/pal/spi",
- "libese-spi/p73/utils",
- "libese-spi/src/include",
- ],
- export_include_dirs: [
- "extns/impl",
- "libese-spi/common/include",
- "libese-spi/p73/common",
- "libese-spi/p73/inc",
- "libese-spi/p73/pal",
- ],
-
- cflags: [
- "-DANDROID",
- "-DBUILDCFG=1",
- "-DNXP_EXTNS=TRUE",
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "android.hardware.nfc@1.0",
- "android.hardware.nfc@1.1",
- "libcutils",
- "libhardware",
- "libhidlbase",
- "libutils",
- "liblog",
- "libbase",
- "vendor.nxp.nxpese@1.0",
- "vendor.nxp.nxpnfc@1.0",
- ],
-}
-
-cc_library_shared {
-
- name: "ls_client",
- defaults: ["hidl_defaults"],
- proprietary: true,
-
- srcs: [
- "ls_client/src/LsLib.cpp",
- "ls_client/src/LsClient.cpp",
- ],
-
- export_include_dirs: ["ls_client/inc"],
-
- shared_libs: [
- "ese_spi_nxp",
- "libcutils",
- "liblog",
- "libhidlbase",
- "liblog",
- "libutils",
- "libcrypto"
- ],
-}
-
-cc_defaults {
- name: "android.hardware.secure_element@1.1_defaults",
- relative_install_path: "hw",
- proprietary: true,
- defaults: ["hidl_defaults"],
- srcs: [
- "1.1/NxpEseService.cpp",
- "1.1/SecureElement.cpp",
- "extns/impl/NxpEse.cpp",
- ],
-
- shared_libs: [
- "android.hardware.secure_element@1.0",
- "android.hardware.secure_element@1.1",
- "ese_spi_nxp",
- "libbase",
- "ls_client",
- "libcutils",
- "libhardware",
- "libhidlbase",
- "liblog",
- "libutils",
- "vendor.nxp.nxpese@1.0",
- "vendor.nxp.nxpnfc@1.0",
- ],
-}
-
-cc_defaults {
- name: "android.hardware.secure_element@1.0_defaults",
- relative_install_path: "hw",
- proprietary: true,
- defaults: ["hidl_defaults"],
- srcs: [
- "1.0/NxpEseService.cpp",
- "1.0/SecureElement.cpp",
- "extns/impl/NxpEse.cpp",
- ],
-
- shared_libs: [
- "android.hardware.secure_element@1.0",
- "ese_spi_nxp",
- "libbase",
- "ls_client",
- "libcutils",
- "libhardware",
- "libhidlbase",
- "liblog",
- "libutils",
- "vendor.nxp.nxpese@1.0",
- "vendor.nxp.nxpnfc@1.0",
- ],
-}
-
-cc_binary {
- name: "android.hardware.secure_element@1.0-service",
- init_rc: ["1.0/android.hardware.secure_element@1.0-service.rc"],
- defaults: ["android.hardware.secure_element@1.0_defaults"],
-}
-
-cc_binary {
- name: "android.hardware.secure_element@1.0-service-disabled",
- init_rc: ["1.0/android.hardware.secure_element@1.0-service-disabled.rc"],
- defaults: ["android.hardware.secure_element@1.0_defaults"],
-}
-
-cc_binary {
- name: "android.hardware.secure_element@1.1-service",
- init_rc: ["1.1/android.hardware.secure_element@1.1-service.rc"],
- defaults: ["android.hardware.secure_element@1.1_defaults"],
-}
-
-cc_binary {
- name: "android.hardware.secure_element@1.1-service-disabled",
- init_rc: ["1.1/android.hardware.secure_element@1.1-service-disabled.rc"],
- defaults: ["android.hardware.secure_element@1.1_defaults"],
-}
+/******************************************************************************
+ *
+ * Copyright 2021 NXP
+ *
+ * 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.
+ *
+*******************************************************************************/
+
+subdirs = [
+ "snxxx","intf","pn8x",
+]
diff --git a/extns/intf/nxpese/1.0/Android.bp b/extns/intf/nxpese/1.0/Android.bp
deleted file mode 100644
index 013be4f..0000000
--- a/extns/intf/nxpese/1.0/Android.bp
+++ /dev/null
@@ -1,24 +0,0 @@
-// This file is autogenerated by hidl-gen -Landroidbp.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_nxp_secure_element_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_nxp_secure_element_license"],
-}
-
-hidl_interface {
- name: "vendor.nxp.nxpese@1.0",
- root: "vendor.nxp.nxpese",
- srcs: [
- "INxpEse.hal",
- ],
- interfaces: [
- "android.hidl.base@1.0",
- ],
- types: [
- ],
- gen_java: true,
-}
diff --git a/extns/intf/nxpese/Android.bp b/extns/intf/nxpese/Android.bp
deleted file mode 100644
index f8abae8..0000000
--- a/extns/intf/nxpese/Android.bp
+++ /dev/null
@@ -1,12 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_nxp_secure_element_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_nxp_secure_element_license"],
-}
-
-hidl_package_root {
- name: "vendor.nxp.nxpese",
-}
diff --git a/intf/nxpese/1.0/Android.bp b/intf/nxpese/1.0/Android.bp
new file mode 100644
index 0000000..8e22179
--- /dev/null
+++ b/intf/nxpese/1.0/Android.bp
@@ -0,0 +1,15 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "vendor.nxp.nxpese@1.0",
+ root: "vendor.nxp.nxpese",
+ srcs: [
+ "INxpEse.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ types: [
+ ],
+ gen_java: true,
+}
diff --git a/extns/intf/nxpese/1.0/INxpEse.hal b/intf/nxpese/1.0/INxpEse.hal
index 594fdf2..594fdf2 100644
--- a/extns/intf/nxpese/1.0/INxpEse.hal
+++ b/intf/nxpese/1.0/INxpEse.hal
diff --git a/extns/intf/nxpese/1.0/manifest.xml b/intf/nxpese/1.0/manifest.xml
index 79a5c4d..79a5c4d 100644
--- a/extns/intf/nxpese/1.0/manifest.xml
+++ b/intf/nxpese/1.0/manifest.xml
diff --git a/intf/nxpese/Android.bp b/intf/nxpese/Android.bp
new file mode 100644
index 0000000..cdee88e
--- /dev/null
+++ b/intf/nxpese/Android.bp
@@ -0,0 +1,3 @@
+hidl_package_root {
+ name: "vendor.nxp.nxpese",
+}
diff --git a/extns/intf/nxpese/current.txt b/intf/nxpese/current.txt
index 57fe96e..57fe96e 100644
--- a/extns/intf/nxpese/current.txt
+++ b/intf/nxpese/current.txt
diff --git a/1.0/NxpEseService.cpp b/pn8x/1.0/NxpEseService.cpp
index c305338..2569a07 100755
--- a/1.0/NxpEseService.cpp
+++ b/pn8x/1.0/NxpEseService.cpp
@@ -25,13 +25,13 @@
#include "SecureElement.h"
// Generated HIDL files
-using android::hardware::secure_element::V1_0::ISecureElement;
-using android::hardware::secure_element::V1_0::implementation::SecureElement;
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
using android::OK;
using android::sp;
using android::status_t;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::secure_element::V1_0::ISecureElement;
+using android::hardware::secure_element::V1_0::implementation::SecureElement;
using vendor::nxp::nxpese::V1_0::INxpEse;
using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
diff --git a/1.0/SecureElement.cpp b/pn8x/1.0/SecureElement.cpp
index d4cde23..039d872 100644
--- a/1.0/SecureElement.cpp
+++ b/pn8x/1.0/SecureElement.cpp
@@ -37,8 +37,7 @@ static void onLSCompleted(bool result, std::string reason, void* arg) {
}
SecureElement::SecureElement()
- : mOpenedchannelCount(0),
- mOpenedChannels{false, false, false, false} {}
+ : mOpenedchannelCount(0), mOpenedChannels{false, false, false, false} {}
Return<void> SecureElement::init(
const sp<
diff --git a/1.0/SecureElement.h b/pn8x/1.0/SecureElement.h
index a15028a..6c314e4 100755
--- a/1.0/SecureElement.h
+++ b/pn8x/1.0/SecureElement.h
@@ -31,12 +31,12 @@ namespace secure_element {
namespace V1_0 {
namespace implementation {
-using ::android::hidl::base::V1_0::IBase;
+using ::android::sp;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
-using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback;
using ::android::hardware::Void;
-using ::android::sp;
+using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback;
+using ::android::hidl::base::V1_0::IBase;
#ifndef MAX_LOGICAL_CHANNELS
#define MAX_LOGICAL_CHANNELS 0x04
diff --git a/1.0/android.hardware.secure_element@1.0-service-disabled.rc b/pn8x/1.0/android.hardware.secure_element@1.0-service-disabled.rc
index bb6ea2f..bb6ea2f 100644
--- a/1.0/android.hardware.secure_element@1.0-service-disabled.rc
+++ b/pn8x/1.0/android.hardware.secure_element@1.0-service-disabled.rc
diff --git a/1.0/android.hardware.secure_element@1.0-service.rc b/pn8x/1.0/android.hardware.secure_element@1.0-service.rc
index f1e0966..f1e0966 100644
--- a/1.0/android.hardware.secure_element@1.0-service.rc
+++ b/pn8x/1.0/android.hardware.secure_element@1.0-service.rc
diff --git a/1.1/NxpEseService.cpp b/pn8x/1.1/NxpEseService.cpp
index 595f11e..595f11e 100755
--- a/1.1/NxpEseService.cpp
+++ b/pn8x/1.1/NxpEseService.cpp
diff --git a/1.1/SecureElement.cpp b/pn8x/1.1/SecureElement.cpp
index e4a05df..e4a05df 100644
--- a/1.1/SecureElement.cpp
+++ b/pn8x/1.1/SecureElement.cpp
diff --git a/1.1/SecureElement.h b/pn8x/1.1/SecureElement.h
index d36b03f..d36b03f 100755
--- a/1.1/SecureElement.h
+++ b/pn8x/1.1/SecureElement.h
diff --git a/1.1/android.hardware.secure_element@1.1-service-disabled.rc b/pn8x/1.1/android.hardware.secure_element@1.1-service-disabled.rc
index 6ff981f..6ff981f 100644
--- a/1.1/android.hardware.secure_element@1.1-service-disabled.rc
+++ b/pn8x/1.1/android.hardware.secure_element@1.1-service-disabled.rc
diff --git a/1.1/android.hardware.secure_element@1.1-service.rc b/pn8x/1.1/android.hardware.secure_element@1.1-service.rc
index 8d5ddbe..8d5ddbe 100644
--- a/1.1/android.hardware.secure_element@1.1-service.rc
+++ b/pn8x/1.1/android.hardware.secure_element@1.1-service.rc
diff --git a/pn8x/Android.bp b/pn8x/Android.bp
new file mode 100755
index 0000000..0e83bab
--- /dev/null
+++ b/pn8x/Android.bp
@@ -0,0 +1,155 @@
+cc_library_shared {
+
+ name: "ese_spi_nxp",
+ defaults: ["hidl_defaults"],
+ proprietary: true,
+
+ srcs: [
+ "libese-spi/p73/lib/phNxpEseDataMgr.cpp",
+ "libese-spi/p73/lib/phNxpEseProto7816_3.cpp",
+ "libese-spi/p73/lib/phNxpEse_Api.cpp",
+ "libese-spi/p73/pal/phNxpEsePal.cpp",
+ "libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp",
+ "libese-spi/p73/spm/phNxpEse_Spm.cpp",
+ "libese-spi/p73/utils/ese_config.cpp",
+ "libese-spi/p73/utils/config.cpp",
+ "libese-spi/p73/utils/ringbuffer.cpp",
+ "libese-spi/src/adaptation/NfcAdaptation.cpp",
+ ],
+
+ local_include_dirs: [
+ "libese-spi/p73/lib",
+ "libese-spi/p73/pal/spi",
+ "libese-spi/p73/utils",
+ "libese-spi/src/include",
+ ],
+ export_include_dirs: [
+ "extns/impl",
+ "libese-spi/common/include",
+ "libese-spi/p73/common",
+ "libese-spi/p73/inc",
+ "libese-spi/p73/pal",
+ ],
+
+ cflags: [
+ "-DANDROID",
+ "-DBUILDCFG=1",
+ "-DNXP_EXTNS=TRUE",
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "android.hardware.nfc@1.0",
+ "android.hardware.nfc@1.1",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ "libbase",
+ "vendor.nxp.nxpese@1.0",
+ "vendor.nxp.nxpnfc@1.0",
+ ],
+}
+
+cc_library_shared {
+
+ name: "ls_client",
+ defaults: ["hidl_defaults"],
+ proprietary: true,
+
+ srcs: [
+ "ls_client/src/LsLib.cpp",
+ "ls_client/src/LsClient.cpp",
+ ],
+
+ export_include_dirs: ["ls_client/inc"],
+
+ shared_libs: [
+ "ese_spi_nxp",
+ "libcutils",
+ "liblog",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "libcrypto"
+ ],
+}
+
+cc_defaults {
+ name: "android.hardware.secure_element@1.1_defaults",
+ relative_install_path: "hw",
+ proprietary: true,
+ defaults: ["hidl_defaults"],
+ srcs: [
+ "1.1/NxpEseService.cpp",
+ "1.1/SecureElement.cpp",
+ "extns/impl/NxpEse.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.secure_element@1.0",
+ "android.hardware.secure_element@1.1",
+ "ese_spi_nxp",
+ "libbase",
+ "ls_client",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "vendor.nxp.nxpese@1.0",
+ "vendor.nxp.nxpnfc@1.0",
+ ],
+}
+
+cc_defaults {
+ name: "android.hardware.secure_element@1.0_defaults",
+ relative_install_path: "hw",
+ proprietary: true,
+ defaults: ["hidl_defaults"],
+ srcs: [
+ "1.0/NxpEseService.cpp",
+ "1.0/SecureElement.cpp",
+ "extns/impl/NxpEse.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.secure_element@1.0",
+ "ese_spi_nxp",
+ "libbase",
+ "ls_client",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "vendor.nxp.nxpese@1.0",
+ "vendor.nxp.nxpnfc@1.0",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.secure_element@1.0-service",
+ init_rc: ["1.0/android.hardware.secure_element@1.0-service.rc"],
+ defaults: ["android.hardware.secure_element@1.0_defaults"],
+}
+
+cc_binary {
+ name: "android.hardware.secure_element@1.0-service-disabled",
+ init_rc: ["1.0/android.hardware.secure_element@1.0-service-disabled.rc"],
+ defaults: ["android.hardware.secure_element@1.0_defaults"],
+}
+
+cc_binary {
+ name: "android.hardware.secure_element@1.1-service",
+ init_rc: ["1.1/android.hardware.secure_element@1.1-service.rc"],
+ defaults: ["android.hardware.secure_element@1.1_defaults"],
+}
+
+cc_binary {
+ name: "android.hardware.secure_element@1.1-service-disabled",
+ init_rc: ["1.1/android.hardware.secure_element@1.1-service-disabled.rc"],
+ defaults: ["android.hardware.secure_element@1.1_defaults"],
+}
diff --git a/extns/impl/NxpEse.cpp b/pn8x/extns/impl/NxpEse.cpp
index ce5b40a..ce5b40a 100644
--- a/extns/impl/NxpEse.cpp
+++ b/pn8x/extns/impl/NxpEse.cpp
diff --git a/extns/impl/NxpEse.h b/pn8x/extns/impl/NxpEse.h
index b6af6e3..5da9b07 100644
--- a/extns/impl/NxpEse.h
+++ b/pn8x/extns/impl/NxpEse.h
@@ -31,16 +31,16 @@ namespace nxpese {
namespace V1_0 {
namespace implementation {
-using ::android::hidl::base::V1_0::DebugInfo;
-using ::android::hidl::base::V1_0::IBase;
-using ::vendor::nxp::nxpese::V1_0::INxpEse;
+using ::android::sp;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
-using ::android::sp;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::vendor::nxp::nxpese::V1_0::INxpEse;
struct NxpEse : public INxpEse {
Return<void> ioctl(uint64_t ioctlType, const hidl_vec<uint8_t>& inOutData,
diff --git a/extns/impl/hal_nxpese.h b/pn8x/extns/impl/hal_nxpese.h
index 50ae9f5..813fff8 100644
--- a/extns/impl/hal_nxpese.h
+++ b/pn8x/extns/impl/hal_nxpese.h
@@ -118,7 +118,7 @@ typedef union {
*/
typedef struct {
/*context to be used/updated only by users of proxy & stub of Ese.hal
- * i.e, EseAdaptation & hardware/interface/Ese.
+ * i.e., EseAdaptation & hardware/interface/Ese.
*/
void* context;
eseInputData_t data;
@@ -152,7 +152,7 @@ typedef union {
typedef struct {
/*ioctlType, result & context to be used/updated only by users of
* proxy & stub of Ese.hal.
- * i.e, EseAdaptation & hardware/interface/Ese
+ * i.e., EseAdaptation & hardware/interface/Ese
* These fields shall not be used by libese or halimplementation*/
uint64_t ioctlType;
uint32_t result;
diff --git a/libese-spi/common/include/phNxpEseFeatures.h b/pn8x/libese-spi/common/include/phNxpEseFeatures.h
index f957ba6..f957ba6 100755
--- a/libese-spi/common/include/phNxpEseFeatures.h
+++ b/pn8x/libese-spi/common/include/phNxpEseFeatures.h
diff --git a/libese-spi/p73/common/phEseStatus.h b/pn8x/libese-spi/p73/common/phEseStatus.h
index d4c893d..d4c893d 100755
--- a/libese-spi/p73/common/phEseStatus.h
+++ b/pn8x/libese-spi/p73/common/phEseStatus.h
diff --git a/libese-spi/p73/inc/phNxpEse_Api.h b/pn8x/libese-spi/p73/inc/phNxpEse_Api.h
index fb31af1..fb31af1 100755
--- a/libese-spi/p73/inc/phNxpEse_Api.h
+++ b/pn8x/libese-spi/p73/inc/phNxpEse_Api.h
diff --git a/libese-spi/p73/lib/phNxpEseDataMgr.cpp b/pn8x/libese-spi/p73/lib/phNxpEseDataMgr.cpp
index 0213e18..0213e18 100755
--- a/libese-spi/p73/lib/phNxpEseDataMgr.cpp
+++ b/pn8x/libese-spi/p73/lib/phNxpEseDataMgr.cpp
diff --git a/libese-spi/p73/lib/phNxpEseDataMgr.h b/pn8x/libese-spi/p73/lib/phNxpEseDataMgr.h
index 8a9e203..8a9e203 100755
--- a/libese-spi/p73/lib/phNxpEseDataMgr.h
+++ b/pn8x/libese-spi/p73/lib/phNxpEseDataMgr.h
diff --git a/libese-spi/p73/lib/phNxpEseProto7816_3.cpp b/pn8x/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
index f7a1679..f7a1679 100755
--- a/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
+++ b/pn8x/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
diff --git a/libese-spi/p73/lib/phNxpEseProto7816_3.h b/pn8x/libese-spi/p73/lib/phNxpEseProto7816_3.h
index ee502f3..ee502f3 100755
--- a/libese-spi/p73/lib/phNxpEseProto7816_3.h
+++ b/pn8x/libese-spi/p73/lib/phNxpEseProto7816_3.h
diff --git a/libese-spi/p73/lib/phNxpEse_Api.cpp b/pn8x/libese-spi/p73/lib/phNxpEse_Api.cpp
index 9db2d3b..9db2d3b 100644
--- a/libese-spi/p73/lib/phNxpEse_Api.cpp
+++ b/pn8x/libese-spi/p73/lib/phNxpEse_Api.cpp
diff --git a/libese-spi/p73/lib/phNxpEse_Internal.h b/pn8x/libese-spi/p73/lib/phNxpEse_Internal.h
index ead441d..ead441d 100755
--- a/libese-spi/p73/lib/phNxpEse_Internal.h
+++ b/pn8x/libese-spi/p73/lib/phNxpEse_Internal.h
diff --git a/libese-spi/p73/libese-nxp-P73.conf b/pn8x/libese-spi/p73/libese-nxp-P73.conf
index 84790d3..84790d3 100755
--- a/libese-spi/p73/libese-nxp-P73.conf
+++ b/pn8x/libese-spi/p73/libese-nxp-P73.conf
diff --git a/libese-spi/p73/pal/phNxpEsePal.cpp b/pn8x/libese-spi/p73/pal/phNxpEsePal.cpp
index c15ab51..c15ab51 100755
--- a/libese-spi/p73/pal/phNxpEsePal.cpp
+++ b/pn8x/libese-spi/p73/pal/phNxpEsePal.cpp
diff --git a/libese-spi/p73/pal/phNxpEsePal.h b/pn8x/libese-spi/p73/pal/phNxpEsePal.h
index 59bcbfe..59bcbfe 100755
--- a/libese-spi/p73/pal/phNxpEsePal.h
+++ b/pn8x/libese-spi/p73/pal/phNxpEsePal.h
diff --git a/libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp b/pn8x/libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp
index cb2d4c5..a89a5fd 100755
--- a/libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp
+++ b/pn8x/libese-spi/p73/pal/spi/phNxpEsePal_spi.cpp
@@ -161,7 +161,7 @@ retry_nfc_access:
}
ALOGD_IF(ese_debug_enabled, "Opening port=%s\n", pConfig->pDevName);
-/* open port */
+ /* open port */
retry:
nHandle = open((char const*)pConfig->pDevName, O_RDWR);
diff --git a/libese-spi/p73/pal/spi/phNxpEsePal_spi.h b/pn8x/libese-spi/p73/pal/spi/phNxpEsePal_spi.h
index 1033694..1033694 100755
--- a/libese-spi/p73/pal/spi/phNxpEsePal_spi.h
+++ b/pn8x/libese-spi/p73/pal/spi/phNxpEsePal_spi.h
diff --git a/libese-spi/p73/spm/phNxpEse_Spm.cpp b/pn8x/libese-spi/p73/spm/phNxpEse_Spm.cpp
index f35a891..f35a891 100755
--- a/libese-spi/p73/spm/phNxpEse_Spm.cpp
+++ b/pn8x/libese-spi/p73/spm/phNxpEse_Spm.cpp
diff --git a/libese-spi/p73/spm/phNxpEse_Spm.h b/pn8x/libese-spi/p73/spm/phNxpEse_Spm.h
index 7595cf8..7595cf8 100755
--- a/libese-spi/p73/spm/phNxpEse_Spm.h
+++ b/pn8x/libese-spi/p73/spm/phNxpEse_Spm.h
diff --git a/libese-spi/p73/utils/config.cpp b/pn8x/libese-spi/p73/utils/config.cpp
index 5983d59..5983d59 100644
--- a/libese-spi/p73/utils/config.cpp
+++ b/pn8x/libese-spi/p73/utils/config.cpp
diff --git a/libese-spi/p73/utils/config.h b/pn8x/libese-spi/p73/utils/config.h
index 6a5ccb1..6a5ccb1 100755
--- a/libese-spi/p73/utils/config.h
+++ b/pn8x/libese-spi/p73/utils/config.h
diff --git a/libese-spi/p73/utils/ese_config.cpp b/pn8x/libese-spi/p73/utils/ese_config.cpp
index 4a6b2cc..4a6b2cc 100755
--- a/libese-spi/p73/utils/ese_config.cpp
+++ b/pn8x/libese-spi/p73/utils/ese_config.cpp
diff --git a/libese-spi/p73/utils/ese_config.h b/pn8x/libese-spi/p73/utils/ese_config.h
index fc7cf98..fc7cf98 100755
--- a/libese-spi/p73/utils/ese_config.h
+++ b/pn8x/libese-spi/p73/utils/ese_config.h
diff --git a/libese-spi/p73/utils/ringbuffer.cpp b/pn8x/libese-spi/p73/utils/ringbuffer.cpp
index d7798fd..d7798fd 100755
--- a/libese-spi/p73/utils/ringbuffer.cpp
+++ b/pn8x/libese-spi/p73/utils/ringbuffer.cpp
diff --git a/libese-spi/p73/utils/ringbuffer.h b/pn8x/libese-spi/p73/utils/ringbuffer.h
index d2c310a..d2c310a 100755
--- a/libese-spi/p73/utils/ringbuffer.h
+++ b/pn8x/libese-spi/p73/utils/ringbuffer.h
diff --git a/libese-spi/src/adaptation/NfcAdaptation.cpp b/pn8x/libese-spi/src/adaptation/NfcAdaptation.cpp
index 55745f5..5f45e44 100755
--- a/libese-spi/src/adaptation/NfcAdaptation.cpp
+++ b/pn8x/libese-spi/src/adaptation/NfcAdaptation.cpp
@@ -24,9 +24,9 @@
#include <pthread.h>
using android::sp;
+using android::hardware::hidl_vec;
using android::hardware::Return;
using android::hardware::Void;
-using android::hardware::hidl_vec;
using vendor::nxp::nxpnfc::V1_0::INxpNfc;
sp<INxpNfc> NfcAdaptation::mHalNxpNfc = nullptr;
diff --git a/libese-spi/src/include/NfcAdaptation.h b/pn8x/libese-spi/src/include/NfcAdaptation.h
index db942fa..db942fa 100755
--- a/libese-spi/src/include/NfcAdaptation.h
+++ b/pn8x/libese-spi/src/include/NfcAdaptation.h
diff --git a/ls_client/inc/LsClient.h b/pn8x/ls_client/inc/LsClient.h
index b4fa43e..b4fa43e 100755
--- a/ls_client/inc/LsClient.h
+++ b/pn8x/ls_client/inc/LsClient.h
diff --git a/ls_client/inc/LsLib.h b/pn8x/ls_client/inc/LsLib.h
index b5002cc..b5002cc 100755
--- a/ls_client/inc/LsLib.h
+++ b/pn8x/ls_client/inc/LsLib.h
diff --git a/ls_client/src/LsClient.cpp b/pn8x/ls_client/src/LsClient.cpp
index 4c874a9..8fb4fcd 100755
--- a/ls_client/src/LsClient.cpp
+++ b/pn8x/ls_client/src/LsClient.cpp
@@ -106,8 +106,7 @@ static std::string dumpLsInfo(LSInfo* info) {
<< (int)(info->m_status);
buff << std::setw(2) << std::setfill('0') << std::hex
<< (int)(info->m_version);
- buff << std::setw(2) << std::setfill('0') << std::hex
- << (int)(info->m_mode);
+ buff << std::setw(2) << std::setfill('0') << std::hex << (int)(info->m_mode);
buff << std::setw(2) << std::setfill('0') << std::hex
<< (int)(info->m_slot1_status);
buff << std::setw(2) << std::setfill('0') << std::hex
diff --git a/ls_client/src/LsLib.cpp b/pn8x/ls_client/src/LsLib.cpp
index c670408..c670408 100755
--- a/ls_client/src/LsLib.cpp
+++ b/pn8x/ls_client/src/LsLib.cpp
diff --git a/snxxx/1.0/NxpEseService.cpp b/snxxx/1.0/NxpEseService.cpp
new file mode 100644
index 0000000..c27b781
--- /dev/null
+++ b/snxxx/1.0/NxpEseService.cpp
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * Copyright 2018 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "nxpese@1.0-service"
+#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 "NxpEse.h"
+#include "SecureElement.h"
+#include "eSEClient.h"
+
+// Generated HIDL files
+using android::OK;
+using android::base::StringPrintf;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::secure_element::V1_0::ISecureElement;
+using android::hardware::secure_element::V1_0::implementation::SecureElement;
+using vendor::nxp::nxpese::V1_0::INxpEse;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+using vendor::nxp::virtual_iso::V1_0::implementation::VirtualISO;
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+int main() {
+ status_t status;
+
+ char terminalID[5];
+ const char* SEterminal = "eSEx";
+ bool ret = false;
+
+ android::sp<ISecureElement> se_service = nullptr;
+ android::sp<INxpEse> nxp_se_service = nullptr;
+ android::sp<ISecureElement> virtual_iso_service = nullptr;
+
+ ALOGI("Secure Element HAL Service 1.0 is starting.");
+ se_service = new SecureElement();
+ if (se_service == nullptr) {
+ LOG(ERROR) << StringPrintf(
+ "Can not create an instance of Secure Element HAL Iface, exiting.");
+ goto shutdown;
+ }
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ checkEseClientUpdate();
+ ret = geteSETerminalId(terminalID);
+ ALOGI("Terminal val = %s", terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ ALOGI("Terminal ID found");
+ status = se_service->registerAsService(terminalID);
+
+ if (status != OK) {
+ LOG(ERROR) << StringPrintf(
+ "Could not register service for Secure Element HAL Iface (%d).",
+ status);
+ goto shutdown;
+ }
+ ALOGI("Secure Element Service is ready");
+
+ ALOGI("NXP Secure Element Extn Service 1.0 is starting.");
+ 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.");
+ goto shutdown;
+ }
+ status = nxp_se_service->registerAsService();
+ if (status != OK) {
+ LOG(ERROR) << StringPrintf(
+ "Could not register service for Power Secure Element Extn Iface "
+ "(%d).",
+ status);
+ goto shutdown;
+ }
+ ALOGI("Secure Element Service is ready");
+ }
+
+ ALOGI("Virtual ISO HAL Service 1.0 is starting.");
+ virtual_iso_service = new VirtualISO();
+ if (virtual_iso_service == nullptr) {
+ LOG(ERROR) << StringPrintf(
+ "Can not create an instance of Virtual ISO HAL Iface, exiting.");
+ goto shutdown;
+ }
+ ret = geteUICCTerminalId(terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ status = virtual_iso_service->registerAsService(terminalID);
+ if (status != OK) {
+ LOG(ERROR) << StringPrintf(
+ "Could not register service for Virtual ISO HAL Iface (%d).", status);
+ goto shutdown;
+ }
+ }
+
+ ALOGI("Virtual ISO: Secure Element Service is ready");
+ perform_eSEClientUpdate();
+ joinRpcThreadpool();
+// Should not pass this line
+shutdown:
+ // In normal operation, we don't expect the thread pool to exit
+ LOG(ERROR) << StringPrintf("Secure Element Service is shutting down");
+ return 1;
+}
diff --git a/snxxx/1.0/SecureElement.cpp b/snxxx/1.0/SecureElement.cpp
new file mode 100755
index 0000000..61f1e7f
--- /dev/null
+++ b/snxxx/1.0/SecureElement.cpp
@@ -0,0 +1,688 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#include "SecureElement.h"
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include "NxpEse.h"
+#include "eSEClient.h"
+#include "hal_nxpese.h"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Api.h"
+/* Mutex to synchronize multiple transceive */
+
+namespace android {
+namespace hardware {
+namespace secure_element {
+namespace V1_0 {
+namespace implementation {
+
+#define LOG_TAG "nxpese@1.0-service"
+#define DEFAULT_BASIC_CHANNEL 0x00
+#define INVALID_LEN_SW1 0x64
+#define INVALID_LEN_SW2 0xFF
+
+typedef struct gsTransceiveBuffer {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+ hidl_vec<uint8_t>* pRspDataBuff;
+} sTransceiveBuffer_t;
+
+static sTransceiveBuffer_t gsTxRxBuffer;
+static hidl_vec<uint8_t> gsRspDataBuff(256);
+static android::sp<ISecureElementHalCallback> cCallback;
+std::vector<bool> SecureElement::mOpenedChannels;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+SecureElement::SecureElement()
+ : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
+
+Return<void> SecureElement::init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ LOG(INFO) << "SecureElement::init called here";
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ cCallback = clientCallback;
+ clientCallback->onStateChange(false);
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setSeCallBack(clientCallback);
+ return Void();
+ // Register
+ }
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange(true);
+ return Void();
+ }
+
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ LOG(INFO) << "ESE SPI init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange(true);
+ cCallback = clientCallback;
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ clientCallback->onStateChange(false);
+ }
+ return Void();
+}
+
+Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
+ LOG(ERROR) << "Processing ATR.....";
+ phNxpEse_data atrData;
+ hidl_vec<uint8_t> response;
+ ESESTATUS status = ESESTATUS_FAILED;
+ bool mIsSeHalInitDone = false;
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(response); /*Return with empty Vector*/
+ return Void();
+ } else {
+ mIsSeHalInitDone = true;
+ }
+ }
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "Endpoint set failed";
+ }
+ status = phNxpEse_getAtr(&atrData);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_getAtr failed";
+ _hidl_cb(response); /*Return with empty Vector*/
+ return Void();
+ } else {
+ response.resize(atrData.len);
+ memcpy(&response[0], atrData.p_data, atrData.len);
+ }
+
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "Endpoint set failed";
+ }
+
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(INFO) << StringPrintf("ATR Data[BytebyByte]=Look below for %d bytes",
+ atrData.len);
+ for (auto i = response.begin(); i != response.end(); ++i)
+ LOG(INFO) << StringPrintf("0x%x\t", *i);
+ }
+
+ _hidl_cb(response);
+ if (atrData.p_data != NULL) {
+ phNxpEse_free(atrData.p_data);
+ }
+ if (mIsSeHalInitDone) {
+ if (SecureElementStatus::SUCCESS != seHalDeInit())
+ LOG(ERROR) << "phNxpEse_getAtr seHalDeInit failed";
+ mIsEseInitialized = false;
+ mIsSeHalInitDone = false;
+ }
+ return Void();
+}
+
+Return<bool> SecureElement::isCardPresent() { return true; }
+
+Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ hidl_vec<uint8_t> result;
+ phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
+ gsTxRxBuffer.cmdData.len = data.size();
+ gsTxRxBuffer.cmdData.p_data =
+ (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
+ if (NULL == gsTxRxBuffer.cmdData.p_data) {
+ LOG(ERROR) << "transmit failed to allocate the Memory!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ }
+ memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
+ LOG(INFO) << "Acquired lock for SPI";
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
+
+ if (status == ESESTATUS_SUCCESS) {
+ result.resize(gsTxRxBuffer.rspData.len);
+ memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
+ } else if (status == ESESTATUS_INVALID_RECEIVE_LENGTH) {
+ uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
+ result.resize(sizeof(respBuf));
+ memcpy(&result[0], respBuf, sizeof(respBuf));
+ } else {
+ LOG(ERROR) << "transmit failed!!!";
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+
+ _hidl_cb(result);
+ if (NULL != gsTxRxBuffer.cmdData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
+ gsTxRxBuffer.cmdData.p_data = NULL;
+ }
+ if (NULL != gsTxRxBuffer.rspData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.rspData.p_data);
+ gsTxRxBuffer.rspData.p_data = NULL;
+ }
+
+ return Void();
+}
+
+Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) {
+ hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
+
+ LogicalChannelResponse resApduBuff;
+ resApduBuff.channelNumber = 0xff;
+ memset(&resApduBuff, 0x00, sizeof(resApduBuff));
+
+ LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ SecureElementStatus sestatus = SecureElementStatus::IOERROR;
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEse_data cmdApdu;
+ phNxpEse_data rspApdu;
+
+ phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+
+ phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+ cmdApdu.len = manageChannelCommand.size();
+ cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
+ sizeof(uint8_t));
+ memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+ if (status != ESESTATUS_SUCCESS) {
+ resApduBuff.channelNumber = 0xff;
+ if (NULL != rspApdu.p_data && rspApdu.len > 0) {
+ if (rspApdu.p_data[0] == 0x64 && rspApdu.p_data[1] == 0xFF) {
+ sestatus = SecureElementStatus::IOERROR;
+ }
+ }
+ if (SecureElementStatus::IOERROR != sestatus) {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x81) {
+ resApduBuff.channelNumber = 0xff;
+ sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ resApduBuff.channelNumber = rspApdu.p_data[0];
+ mOpenedchannelCount++;
+ mOpenedChannels[resApduBuff.channelNumber] = true;
+ sestatus = SecureElementStatus::SUCCESS;
+ } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
+ (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ }
+ /*Free the allocations*/
+ phNxpEse_free(cmdApdu.p_data);
+ phNxpEse_free(rspApdu.p_data);
+
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ if (mOpenedchannelCount == 0) {
+ SecureElementStatus deInitStatus = seHalDeInit();
+ if (deInitStatus != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ }
+ }
+ /*If manageChanle is failed in any of above cases
+ send the callback and return*/
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ return Void();
+ }
+ LOG(INFO) << "openLogicalChannel Sending selectApdu";
+ sestatus = SecureElementStatus::IOERROR;
+ status = ESESTATUS_FAILED;
+
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ if ((resApduBuff.channelNumber > 0x03) &&
+ (resApduBuff.channelNumber < 0x14)) {
+ /* update CLA byte accoridng to GP spec Table 11-12*/
+ cpdu.cla =
+ 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
+ } else if ((resApduBuff.channelNumber > 0x00) &&
+ (resApduBuff.channelNumber < 0x04)) {
+ /* update CLA byte accoridng to GP spec Table 11-11*/
+ cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
+ } else {
+ LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
+ resApduBuff.channelNumber);
+ resApduBuff.channelNumber = 0xff;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status != ESESTATUS_SUCCESS) {
+ /*Transceive failed*/
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ resApduBuff.selectResponse.resize(responseLen);
+ memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
+ resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
+ resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
+ (rpdu.sw1 == 0x63)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
+ (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(resApduBuff.channelNumber);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ } else {
+ resApduBuff.channelNumber = 0xff;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+
+ return Void();
+}
+
+Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openBasicChannel_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ hidl_vec<uint8_t> result;
+ hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
+ 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
+
+ LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ cpdu.cla = 0x00; /* Class of instruction */
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ SecureElementStatus sestatus;
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ if (status != ESESTATUS_SUCCESS) {
+ /* Transceive failed */
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ result.resize(responseLen);
+ memcpy(&result[0], rpdu.pdata, rpdu.len);
+ result[responseLen - 1] = rpdu.sw2;
+ result[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
+ (rpdu.sw1 == 0x63)) {
+ /*Set basic channel reference if it is not set */
+ if (!mOpenedChannels[0]) {
+ mOpenedChannels[0] = true;
+ mOpenedchannelCount++;
+ }
+
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
+ (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(DEFAULT_BASIC_CHANNEL);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ }
+ }
+ _hidl_cb(result, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+ return Void();
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+SecureElement::internalCloseChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ 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) {
+ LOG(ERROR) << StringPrintf("invalid channel!!! %d for %d", channelNumber,
+ mOpenedChannels[channelNumber]);
+ sestatus = SecureElementStatus::FAILED;
+ } 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status != ESESTATUS_SUCCESS) {
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::FAILED;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+SecureElement::closeChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(ERROR) << "Acquired the lock in SPI closeChannel";
+ if (channelNumber < DEFAULT_BASIC_CHANNEL ||
+ channelNumber >= mMaxChannelCount) {
+ LOG(ERROR) << StringPrintf("invalid channel!!! %d for %d", channelNumber,
+ mOpenedChannels[channelNumber]);
+ sestatus = SecureElementStatus::FAILED;
+ } 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status != ESESTATUS_SUCCESS) {
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::FAILED;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+ LOG(ERROR) << " SecureElement serviceDied!!!";
+ mIsEseInitialized = false;
+ if (seHalDeInit() != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "SE Deinit not successful";
+ }
+}
+ESESTATUS SecureElement::seHalInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ status = phNxpEse_open(initParams);
+ if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ mIsEseInitialized = true;
+ LOG(INFO) << "ESE SPI init complete!!!";
+ return ESESTATUS_SUCCESS;
+ }
+ deInitStatus = phNxpEse_deInit();
+ } else {
+ LOG(INFO) << "ESE SPI init NOT successful";
+ status = ESESTATUS_FAILED;
+ }
+ if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
+ LOG(INFO) << "ESE close not successful";
+ status = ESESTATUS_FAILED;
+ }
+ mIsEseInitialized = false;
+ }
+ return status;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+SecureElement::seHalDeInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsDeInitDone = true;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
+ sestatus = SecureElementStatus::SUCCESS;
+ ;
+ } else {
+ LOG(ERROR) << "seHalDeInit: Failed";
+ }
+ mIsEseInitialized = false;
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+
+ return sestatus;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace secure_element
+} // namespace hardware
+} // namespace android
diff --git a/snxxx/1.0/SecureElement.h b/snxxx/1.0/SecureElement.h
new file mode 100644
index 0000000..f46b666
--- /dev/null
+++ b/snxxx/1.0/SecureElement.h
@@ -0,0 +1,113 @@
+/******************************************************************************
+ *
+ * Copyright 2018 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef ANDROID_HARDWARE_SECURE_ELEMENT_V1_0_SECUREELEMENT_H
+#define ANDROID_HARDWARE_SECURE_ELEMENT_V1_0_SECUREELEMENT_H
+
+#include <android-base/stringprintf.h>
+#include <android/hardware/secure_element/1.0/ISecureElement.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <pthread.h>
+#include "phNxpEse_Api.h"
+
+class ThreadMutex {
+ public:
+ ThreadMutex();
+ virtual ~ThreadMutex();
+ void lock();
+ void unlock();
+ operator pthread_mutex_t*() { return &mMutex; }
+
+ private:
+ pthread_mutex_t mMutex;
+};
+
+class AutoThreadMutex {
+ public:
+ AutoThreadMutex(ThreadMutex& m);
+ virtual ~AutoThreadMutex();
+ operator ThreadMutex&() { return mm; }
+ operator pthread_mutex_t*() { return (pthread_mutex_t*)mm; }
+
+ private:
+ ThreadMutex& mm;
+};
+
+namespace android {
+namespace hardware {
+namespace secure_element {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using android::base::StringPrintf;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifndef MIN_APDU_LENGTH
+#define MIN_APDU_LENGTH 0x04
+#endif
+#ifndef DEFAULT_BASIC_CHANNEL
+#define DEFAULT_BASIC_CHANNEL 0x00
+#endif
+
+struct SecureElement : public ISecureElement, public hidl_death_recipient {
+ SecureElement();
+ Return<void> init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> getAtr(getAtr_cb _hidl_cb) override;
+ Return<bool> isCardPresent() override;
+ Return<void> transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) override;
+ Return<void> openLogicalChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) override;
+ Return<void> openBasicChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openBasicChannel_cb _hidl_cb) override;
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ closeChannel(uint8_t channelNumber) override;
+
+ void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/);
+
+ private:
+ uint8_t mMaxChannelCount;
+ uint8_t mOpenedchannelCount = 0;
+ bool mIsEseInitialized = false;
+ static std::vector<bool> mOpenedChannels;
+ static sp<V1_0::ISecureElementHalCallback> mCallbackV1_0;
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ seHalDeInit();
+ ESESTATUS seHalInit();
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ internalCloseChannel(uint8_t channelNumber);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace secure_element
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_SECURE_ELEMENT_V1_0_SECUREELEMENT_H
diff --git a/snxxx/1.0/VirtualISO.cpp b/snxxx/1.0/VirtualISO.cpp
new file mode 100644
index 0000000..e92bce8
--- /dev/null
+++ b/snxxx/1.0/VirtualISO.cpp
@@ -0,0 +1,612 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#include "VirtualISO.h"
+#include <android-base/logging.h>
+#include "NxpEse.h"
+#include "SecureElement.h"
+#include "eSEClient.h"
+#include "hal_nxpese.h"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Api.h"
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+namespace vendor {
+namespace nxp {
+namespace virtual_iso {
+namespace V1_0 {
+namespace implementation {
+
+#define LOG_TAG "nxpVIsoese@1.0-service"
+
+#define DEFAULT_BASIC_CHANNEL 0x00
+
+typedef struct gsTransceiveBuffer {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+ hidl_vec<uint8_t>* pRspDataBuff;
+} sTransceiveBuffer_t;
+
+static sTransceiveBuffer_t gsTxRxBuffer;
+static hidl_vec<uint8_t> gsRspDataBuff(256);
+static android::sp<ISecureElementHalCallback> cCallback;
+std::vector<bool> VirtualISO::mOpenedChannels;
+
+VirtualISO::VirtualISO()
+ : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
+
+Return<void> VirtualISO::init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ LOG(INFO) << "Virtual ISO::init Enter";
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ cCallback = clientCallback;
+ clientCallback->onStateChange(false);
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setVirtualISOCallBack(clientCallback);
+ return Void();
+ // Register
+ }
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange(true);
+ return Void();
+ }
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ LOG(INFO) << "VISO init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange(true);
+ } else {
+ LOG(ERROR) << "VISO-Hal Init failed";
+ clientCallback->onStateChange(false);
+ }
+ return Void();
+}
+
+Return<void> VirtualISO::getAtr(getAtr_cb _hidl_cb) {
+ hidl_vec<uint8_t> response;
+ _hidl_cb(response);
+ return Void();
+}
+
+Return<bool> VirtualISO::isCardPresent() { return true; }
+
+Return<void> VirtualISO::transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ hidl_vec<uint8_t> result;
+ phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
+ gsTxRxBuffer.cmdData.len = data.size();
+ gsTxRxBuffer.cmdData.p_data =
+ (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
+ if (NULL == gsTxRxBuffer.cmdData.p_data) {
+ LOG(ERROR) << "transmit failed to allocate the Memory!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ }
+ memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
+ LOG(ERROR) << "Acquired the lock in VISO ";
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
+
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "transmit failed!!!";
+ } else {
+ result.resize(gsTxRxBuffer.rspData.len);
+ memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+
+ _hidl_cb(result);
+ if (NULL != gsTxRxBuffer.cmdData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
+ gsTxRxBuffer.cmdData.p_data = NULL;
+ }
+ if (NULL != gsTxRxBuffer.rspData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.rspData.p_data);
+ gsTxRxBuffer.rspData.p_data = NULL;
+ }
+
+ return Void();
+}
+
+Return<void> VirtualISO::openLogicalChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) {
+ hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
+
+ LogicalChannelResponse resApduBuff;
+
+ LOG(INFO) << "Acquired the lock in VISO openLogicalChannel";
+
+ resApduBuff.channelNumber = 0xff;
+ memset(&resApduBuff, 0x00, sizeof(resApduBuff));
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ SecureElementStatus sestatus = SecureElementStatus::IOERROR;
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEse_data cmdApdu;
+ phNxpEse_data rspApdu;
+
+ phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+ cmdApdu.len = manageChannelCommand.size();
+ cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
+ sizeof(uint8_t));
+ memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
+
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+ if (status != ESESTATUS_SUCCESS) {
+ resApduBuff.channelNumber = 0xff;
+ if (NULL != rspApdu.p_data && rspApdu.len > 0) {
+ if ((rspApdu.p_data[0] == 0x64 && rspApdu.p_data[1] == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ }
+ }
+ if (SecureElementStatus::IOERROR != sestatus) {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x81) {
+ resApduBuff.channelNumber = 0xff;
+ sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ resApduBuff.channelNumber = rspApdu.p_data[0];
+ mOpenedchannelCount++;
+ mOpenedChannels[resApduBuff.channelNumber] = true;
+ sestatus = SecureElementStatus::SUCCESS;
+ } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
+ (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ }
+
+ /*Free the allocations*/
+ phNxpEse_free(cmdApdu.p_data);
+ phNxpEse_free(rspApdu.p_data);
+
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ }
+ }
+ /*If manageChanle is failed in any of above cases
+ send the callback and return*/
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ return Void();
+ }
+ LOG(INFO) << "openLogicalChannel Sending selectApdu";
+ sestatus = SecureElementStatus::IOERROR;
+ status = ESESTATUS_FAILED;
+
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ if ((resApduBuff.channelNumber > 0x03) &&
+ (resApduBuff.channelNumber < 0x14)) {
+ /* update CLA byte accoridng to GP spec Table 11-12*/
+ cpdu.cla =
+ 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
+ } else if ((resApduBuff.channelNumber > 0x00) &&
+ (resApduBuff.channelNumber < 0x04)) {
+ /* update CLA byte accoridng to GP spec Table 11-11*/
+ cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
+ } else {
+ LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
+ resApduBuff.channelNumber);
+ resApduBuff.channelNumber = 0xff;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status != ESESTATUS_SUCCESS) {
+ /*Transceive failed*/
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ resApduBuff.selectResponse.resize(responseLen);
+ memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
+ resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
+ resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if (rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(resApduBuff.channelNumber);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ } else {
+ resApduBuff.channelNumber = 0xff;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+
+ return Void();
+}
+
+Return<void> VirtualISO::openBasicChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openBasicChannel_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ hidl_vec<uint8_t> result;
+
+ LOG(INFO) << "Acquired the lock in VISO openBasicChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ cpdu.cla = 0x00; /* Class of instruction */
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ SecureElementStatus sestatus;
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ if (status != ESESTATUS_SUCCESS) {
+ /* Transceive failed */
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ result.resize(responseLen);
+ memcpy(&result[0], rpdu.pdata, rpdu.len);
+ result[responseLen - 1] = rpdu.sw2;
+ result[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ /*Set basic channel reference if it is not set */
+ if (!mOpenedChannels[0]) {
+ mOpenedChannels[0] = true;
+ mOpenedchannelCount++;
+ }
+
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(DEFAULT_BASIC_CHANNEL);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ }
+ }
+ _hidl_cb(result, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+ return Void();
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::internalCloseChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(ERROR) << "internalCloseChannel Enter";
+ LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
+ mMaxChannelCount, channelNumber);
+ if (channelNumber < DEFAULT_BASIC_CHANNEL ||
+ channelNumber >= mMaxChannelCount) {
+ LOG(ERROR) << StringPrintf("invalid channel!!! %d", channelNumber);
+ sestatus = SecureElementStatus::FAILED;
+ } 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status != ESESTATUS_SUCCESS) {
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::FAILED;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::closeChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(INFO) << "Acquired the lock in VISO closeChannel";
+ if (channelNumber < DEFAULT_BASIC_CHANNEL ||
+ channelNumber >= mMaxChannelCount) {
+ LOG(ERROR) << StringPrintf("invalid channel!!! %d for %d", channelNumber,
+ mOpenedChannels[channelNumber]);
+ sestatus = SecureElementStatus::FAILED;
+ } 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status != ESESTATUS_SUCCESS) {
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::FAILED;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+ESESTATUS VirtualISO::seHalInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ status = phNxpEse_open(initParams);
+ if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ mIsEseInitialized = true;
+ LOG(INFO) << "VISO init complete!!!";
+ return ESESTATUS_SUCCESS;
+ }
+ deInitStatus = phNxpEse_deInit();
+ }
+ phNxpEse_close(deInitStatus);
+ mIsEseInitialized = false;
+ }
+ return status;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::seHalDeInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsDeInitDone = true;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
+ sestatus = SecureElementStatus::SUCCESS;
+ ;
+ } else {
+ LOG(ERROR) << "seHalDeInit: Failed";
+ }
+ // Clear all the flags as SPI driver is closed.
+ mIsEseInitialized = false;
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+ return sestatus;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace virtual_iso
+} // namespace nxp
+} // namespace vendor
diff --git a/snxxx/1.0/VirtualISO.h b/snxxx/1.0/VirtualISO.h
new file mode 100644
index 0000000..9d7438f
--- /dev/null
+++ b/snxxx/1.0/VirtualISO.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * Copyright 2018 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
+#define VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
+
+#include <android-base/stringprintf.h>
+#include <android/hardware/secure_element/1.0/ISecureElement.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "phNxpEse_Api.h"
+
+namespace vendor {
+namespace nxp {
+namespace virtual_iso {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::wp;
+using android::base::StringPrintf;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::secure_element::V1_0::ISecureElement;
+using ::android::hardware::secure_element::V1_0::LogicalChannelResponse;
+using ::android::hardware::secure_element::V1_0::SecureElementStatus;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifndef DEFAULT_BASIC_CHANNEL
+#define DEFAULT_BASIC_CHANNEL 0x00
+#endif
+
+struct VirtualISO : public ISecureElement, public hidl_death_recipient {
+ VirtualISO();
+ Return<void> init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> getAtr(getAtr_cb _hidl_cb) override;
+ Return<bool> isCardPresent() override;
+ Return<void> transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) override;
+ Return<void> openLogicalChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) override;
+ Return<void> openBasicChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openBasicChannel_cb _hidl_cb) override;
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ closeChannel(uint8_t channelNumber) override;
+
+ virtual void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+ // TODO: Implement graceful closure, to close ongoing tx-rx and deinit
+ // T=1 stack
+ // close(0);
+ }
+
+ private:
+ uint8_t mMaxChannelCount;
+ uint8_t mOpenedchannelCount = 0;
+ bool mIsEseInitialized = false;
+ static std::vector<bool> mOpenedChannels;
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ seHalDeInit();
+ ESESTATUS seHalInit();
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ internalCloseChannel(uint8_t channelNumber);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace virtual_iso
+} // namespace nxp
+} // namespace vendor
+
+#endif // VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
diff --git a/snxxx/1.0/android.hardware.secure_element_snxxx@1.0-service.rc b/snxxx/1.0/android.hardware.secure_element_snxxx@1.0-service.rc
new file mode 100644
index 0000000..7c6c36e
--- /dev/null
+++ b/snxxx/1.0/android.hardware.secure_element_snxxx@1.0-service.rc
@@ -0,0 +1,4 @@
+service secure_element_hal_service /vendor/bin/hw/android.hardware.secure_element_snxxx@1.0-service
+ class hal
+ user secure_element
+ group secure_element
diff --git a/snxxx/1.1/NxpEseService.cpp b/snxxx/1.1/NxpEseService.cpp
new file mode 100755
index 0000000..dcb1541
--- /dev/null
+++ b/snxxx/1.1/NxpEseService.cpp
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#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 <string.h>
+#include <regex>
+#include "NxpEse.h"
+#include "SecureElement.h"
+#include "eSEClient.h"
+
+// Generated HIDL files
+using android::OK;
+using android::base::StringPrintf;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::secure_element::V1_1::ISecureElement;
+using android::hardware::secure_element::V1_1::implementation::SecureElement;
+using vendor::nxp::nxpese::V1_0::INxpEse;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+using vendor::nxp::virtual_iso::V1_0::implementation::VirtualISO;
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+int main() {
+ status_t status;
+
+ char terminalID[5];
+ const char* SEterminal = "eSEx";
+ bool ret = false;
+
+ android::sp<ISecureElement> se_service = nullptr;
+ android::sp<INxpEse> nxp_se_service = nullptr;
+ android::sp<ISecureElement> virtual_iso_service = nullptr;
+
+ ALOGI("Secure Element HAL Service 1.1 is starting.");
+ try {
+ se_service = new SecureElement();
+ if (se_service == nullptr) {
+ ALOGE("Can not create an instance of Secure Element HAL Iface, exiting.");
+ goto shutdown;
+ }
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ checkEseClientUpdate();
+ ret = geteSETerminalId(terminalID);
+ ALOGI("Terminal val = %s", terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ ALOGI("Terminal ID found");
+ status = se_service->registerAsService(terminalID);
+
+ if (status != OK) {
+ ALOGE("Could not register service for Secure Element HAL Iface (%d).",
+ status);
+ goto shutdown;
+ }
+ ALOGI("Secure Element Service is ready");
+
+ ALOGI("NXP Secure Element Extn Service 1.0 is starting.");
+ nxp_se_service = new NxpEse();
+ if (nxp_se_service == nullptr) {
+ ALOGE(
+ "Can not create an instance of NXP Secure Element Extn "
+ "Iface,exiting.");
+ goto shutdown;
+ }
+ status = nxp_se_service->registerAsService();
+ if (status != OK) {
+ ALOGE(
+ "Could not register service for Power Secure Element Extn Iface "
+ "(%d).",
+ status);
+ goto shutdown;
+ }
+ ALOGI("Secure Element Service is ready");
+ }
+
+ ALOGI("Virtual ISO HAL Service 1.0 is starting.");
+ virtual_iso_service = new VirtualISO();
+ if (virtual_iso_service == nullptr) {
+ ALOGE("Can not create an instance of Virtual ISO HAL Iface, exiting.");
+ goto shutdown;
+ }
+ ret = geteUICCTerminalId(terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ status = virtual_iso_service->registerAsService(terminalID);
+ if (status != OK) {
+ ALOGE("Could not register service for Virtual ISO HAL Iface (%d).",
+ status);
+ goto shutdown;
+ }
+ }
+
+ ALOGI("Virtual ISO: Secure Element Service is ready");
+ perform_eSEClientUpdate();
+ joinRpcThreadpool();
+ } catch (const std::length_error& e) {
+ ALOGE("Length Exception occurred = %s ", e.what());
+ } catch (const std::__1::ios_base::failure& e) {
+ ALOGE("ios failure Exception occurred = %s ", e.what());
+ } catch (std::__1::regex_error& e) {
+ ALOGE("Regex Exception occurred = %s ", e.what());
+ }
+// Should not pass this line
+shutdown:
+ // In normal operation, we don't expect the thread pool to exit
+ ALOGE("Secure Element Service is shutting down");
+ return 1;
+}
diff --git a/snxxx/1.1/SecureElement.cpp b/snxxx/1.1/SecureElement.cpp
new file mode 100755
index 0000000..409811f
--- /dev/null
+++ b/snxxx/1.1/SecureElement.cpp
@@ -0,0 +1,691 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#include "SecureElement.h"
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include "NxpEse.h"
+#include "eSEClient.h"
+#include "hal_nxpese.h"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Api.h"
+/* Mutex to synchronize multiple transceive */
+
+namespace android {
+namespace hardware {
+namespace secure_element {
+namespace V1_1 {
+namespace implementation {
+
+#define LOG_TAG "nxpese@1.1-service"
+#define DEFAULT_BASIC_CHANNEL 0x00
+#define INVALID_LEN_SW1 0x64
+#define INVALID_LEN_SW2 0xFF
+
+typedef struct gsTransceiveBuffer {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+ hidl_vec<uint8_t>* pRspDataBuff;
+} sTransceiveBuffer_t;
+
+static sTransceiveBuffer_t gsTxRxBuffer;
+static hidl_vec<uint8_t> gsRspDataBuff(256);
+sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
+sp<V1_1::ISecureElementHalCallback> SecureElement::mCallbackV1_1 = nullptr;
+std::vector<bool> SecureElement::mOpenedChannels;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+SecureElement::SecureElement()
+ : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
+
+void SecureElement::NotifySeWaitExtension(phNxpEse_wtxState state) {
+ if (state == WTX_ONGOING) {
+ LOG(INFO) << "SecureElement::WTX ongoing";
+ } else if (state == WTX_END) {
+ LOG(INFO) << "SecureElement::WTX ended";
+ }
+}
+
+Return<void> SecureElement::init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+ initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ LOG(INFO) << "SecureElement::init called here";
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_0 = clientCallback;
+ clientCallback->onStateChange(false);
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setSeCallBack(clientCallback);
+ return Void();
+ // Register
+ }
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange(true);
+ return Void();
+ }
+
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ LOG(INFO) << "ESE SPI init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange(true);
+ mCallbackV1_0 = clientCallback;
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ clientCallback->onStateChange(false);
+ }
+ return Void();
+}
+
+Return<void> SecureElement::init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+ initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ LOG(INFO) << "SecureElement::init called here";
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_1 = clientCallback;
+ clientCallback->onStateChange_1_1(false, "NXP SE update going on");
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setSeCallBack_1_1(clientCallback);
+ return Void();
+ // Register
+ }
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
+ return Void();
+ }
+
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ LOG(INFO) << "ESE SPI init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
+ mCallbackV1_1 = clientCallback;
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ clientCallback->onStateChange_1_1(false, "NXP SE HAL init failed");
+ }
+ return Void();
+}
+
+Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ LOG(ERROR) << "Processing ATR.....";
+ phNxpEse_data atrData;
+ hidl_vec<uint8_t> response;
+ ESESTATUS status = ESESTATUS_FAILED;
+ bool mIsSeHalInitDone = false;
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(response); /*Return with empty Vector*/
+ return Void();
+ } else {
+ mIsSeHalInitDone = true;
+ }
+ }
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "Endpoint set failed";
+ }
+ status = phNxpEse_getAtr(&atrData);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_getAtr failed";
+ _hidl_cb(response); /*Return with empty Vector*/
+ return Void();
+ } else {
+ response.resize(atrData.len);
+ memcpy(&response[0], atrData.p_data, atrData.len);
+ }
+
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "Endpoint set failed";
+ }
+
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(INFO) << StringPrintf("ATR Data[BytebyByte]=Look below for %d bytes",
+ atrData.len);
+ for (auto i = response.begin(); i != response.end(); ++i)
+ LOG(INFO) << StringPrintf("0x%x\t", *i);
+ }
+
+ _hidl_cb(response);
+ if (atrData.p_data != NULL) {
+ phNxpEse_free(atrData.p_data);
+ }
+ if (mIsSeHalInitDone) {
+ if (SecureElementStatus::SUCCESS != seHalDeInit())
+ LOG(ERROR) << "phNxpEse_getAtr seHalDeInit failed";
+ mIsEseInitialized = false;
+ mIsSeHalInitDone = false;
+ }
+ return Void();
+}
+
+Return<bool> SecureElement::isCardPresent() { return true; }
+
+Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ ESESTATUS status = ESESTATUS_FAILED;
+ hidl_vec<uint8_t> result;
+ phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
+ gsTxRxBuffer.cmdData.len = (uint32_t)data.size();
+ gsTxRxBuffer.cmdData.p_data =
+ (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
+ if (NULL == gsTxRxBuffer.cmdData.p_data) {
+ LOG(ERROR) << "transmit failed to allocate the Memory!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ }
+ memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
+ LOG(INFO) << "Acquired lock for SPI";
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
+
+ if (status == ESESTATUS_SUCCESS) {
+ result.resize(gsTxRxBuffer.rspData.len);
+ memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
+ } else if (status == ESESTATUS_INVALID_RECEIVE_LENGTH) {
+ uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
+ result.resize(sizeof(respBuf));
+ memcpy(&result[0], respBuf, sizeof(respBuf));
+ } else {
+ LOG(ERROR) << "transmit failed!!!";
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+
+ _hidl_cb(result);
+ if (NULL != gsTxRxBuffer.cmdData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
+ gsTxRxBuffer.cmdData.p_data = NULL;
+ }
+ if (NULL != gsTxRxBuffer.rspData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.rspData.p_data);
+ gsTxRxBuffer.rspData.p_data = NULL;
+ }
+
+ return Void();
+}
+
+Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
+
+ LogicalChannelResponse resApduBuff;
+ resApduBuff.channelNumber = 0xff;
+ memset(&resApduBuff, 0x00, sizeof(resApduBuff));
+
+ LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ SecureElementStatus sestatus = SecureElementStatus::IOERROR;
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEse_data cmdApdu;
+ phNxpEse_data rspApdu;
+
+ phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+
+ phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+ cmdApdu.len = (uint32_t)manageChannelCommand.size();
+ cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
+ sizeof(uint8_t));
+ memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+ if (status != ESESTATUS_SUCCESS) {
+ resApduBuff.channelNumber = 0xff;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x81) {
+ resApduBuff.channelNumber = 0xff;
+ sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ resApduBuff.channelNumber = rspApdu.p_data[0];
+ mOpenedchannelCount++;
+ mOpenedChannels[resApduBuff.channelNumber] = true;
+ sestatus = SecureElementStatus::SUCCESS;
+ } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
+ (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ }
+ /*Free the allocations*/
+ phNxpEse_free(cmdApdu.p_data);
+ phNxpEse_free(rspApdu.p_data);
+
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ if (mOpenedchannelCount == 0) {
+ SecureElementStatus deInitStatus = seHalDeInit();
+ if (deInitStatus != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ }
+ }
+ /*If manageChanle is failed in any of above cases
+ send the callback and return*/
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ return Void();
+ }
+ LOG(INFO) << "openLogicalChannel Sending selectApdu";
+ sestatus = SecureElementStatus::IOERROR;
+ status = ESESTATUS_FAILED;
+
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ if ((resApduBuff.channelNumber > 0x03) &&
+ (resApduBuff.channelNumber < 0x14)) {
+ /* update CLA byte accoridng to GP spec Table 11-12*/
+ cpdu.cla =
+ 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
+ } else if ((resApduBuff.channelNumber > 0x00) &&
+ (resApduBuff.channelNumber < 0x04)) {
+ /* update CLA byte accoridng to GP spec Table 11-11*/
+ cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
+ } else {
+ LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
+ resApduBuff.channelNumber);
+ resApduBuff.channelNumber = 0xff;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = (uint16_t)aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status != ESESTATUS_SUCCESS) {
+ /*Transceive failed*/
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ resApduBuff.selectResponse.resize(responseLen);
+ memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
+ resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
+ resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
+ (rpdu.sw1 == 0x63)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
+ (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(resApduBuff.channelNumber);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ } else {
+ resApduBuff.channelNumber = 0xff;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+
+ return Void();
+}
+
+Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openBasicChannel_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ hidl_vec<uint8_t> result;
+ hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
+ 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
+
+ LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ cpdu.cla = 0x00; /* Class of instruction */
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = (uint16_t)aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ SecureElementStatus sestatus;
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ if (status != ESESTATUS_SUCCESS) {
+ /* Transceive failed */
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ result.resize(responseLen);
+ memcpy(&result[0], rpdu.pdata, rpdu.len);
+ result[responseLen - 1] = rpdu.sw2;
+ result[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
+ (rpdu.sw1 == 0x63)) {
+ /*Set basic channel reference if it is not set */
+ if (!mOpenedChannels[0]) {
+ mOpenedChannels[0] = true;
+ mOpenedchannelCount++;
+ }
+
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
+ (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(DEFAULT_BASIC_CHANNEL);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ }
+ }
+ _hidl_cb(result, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+ return Void();
+}
+
+Return<SecureElementStatus> SecureElement::internalCloseChannel(
+ uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ 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) {
+ 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status == ESESTATUS_SUCCESS) {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ }
+ if (channelNumber < mMaxChannelCount) {
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+
+Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
+ AutoMutex guard(seHalLock);
+ return internalCloseChannel(channelNumber);
+}
+
+void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+ LOG(ERROR) << " SecureElement serviceDied!!!";
+ mIsEseInitialized = false;
+ if (seHalDeInit() != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "SE Deinit not successful";
+ }
+}
+ESESTATUS SecureElement::seHalInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+ initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
+
+ status = phNxpEse_open(initParams);
+ if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ mIsEseInitialized = true;
+ LOG(INFO) << "ESE SPI init complete!!!";
+ return ESESTATUS_SUCCESS;
+ }
+ deInitStatus = phNxpEse_deInit();
+ } else {
+ LOG(INFO) << "ESE SPI init NOT successful";
+ status = ESESTATUS_FAILED;
+ }
+ if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
+ LOG(INFO) << "ESE close not successful";
+ status = ESESTATUS_FAILED;
+ }
+ mIsEseInitialized = false;
+ }
+ return status;
+}
+
+Return<SecureElementStatus> SecureElement::seHalDeInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsDeInitDone = true;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
+ sestatus = SecureElementStatus::SUCCESS;
+ ;
+ } else {
+ LOG(ERROR) << "seHalDeInit: Failed";
+ }
+ mIsEseInitialized = false;
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+
+ return sestatus;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace secure_element
+} // namespace hardware
+} // namespace android
diff --git a/snxxx/1.1/SecureElement.h b/snxxx/1.1/SecureElement.h
new file mode 100755
index 0000000..5c15da1
--- /dev/null
+++ b/snxxx/1.1/SecureElement.h
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef ANDROID_HARDWARE_SECURE_ELEMENT_V1_1_SECUREELEMENT_H
+#define ANDROID_HARDWARE_SECURE_ELEMENT_V1_1_SECUREELEMENT_H
+
+#include <SyncEvent.h>
+#include <android-base/stringprintf.h>
+#include <android/hardware/secure_element/1.0/types.h>
+#include <android/hardware/secure_element/1.1/ISecureElement.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <pthread.h>
+#include "phNxpEse_Api.h"
+
+class ThreadMutex {
+ public:
+ ThreadMutex();
+ virtual ~ThreadMutex();
+ void lock();
+ void unlock();
+ operator pthread_mutex_t*() { return &mMutex; }
+
+ private:
+ pthread_mutex_t mMutex;
+};
+
+class AutoThreadMutex {
+ public:
+ AutoThreadMutex(ThreadMutex& m);
+ virtual ~AutoThreadMutex();
+ operator ThreadMutex&() { return mm; }
+ operator pthread_mutex_t*() { return (pthread_mutex_t*)mm; }
+
+ private:
+ ThreadMutex& mm;
+};
+
+namespace android {
+namespace hardware {
+namespace secure_element {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::sp;
+using android::base::StringPrintf;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::secure_element::V1_0::LogicalChannelResponse;
+using ::android::hardware::secure_element::V1_0::SecureElementStatus;
+using ::android::hardware::secure_element::V1_1::ISecureElement;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifndef MIN_APDU_LENGTH
+#define MIN_APDU_LENGTH 0x04
+#endif
+#ifndef DEFAULT_BASIC_CHANNEL
+#define DEFAULT_BASIC_CHANNEL 0x00
+#endif
+
+struct SecureElement : public V1_1::ISecureElement,
+ public hidl_death_recipient {
+ SecureElement();
+ Return<void> init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> getAtr(getAtr_cb _hidl_cb) override;
+ Return<bool> isCardPresent() override;
+ Return<void> transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) override;
+ Return<void> openLogicalChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) override;
+ Return<void> openBasicChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openBasicChannel_cb _hidl_cb) override;
+ Return<SecureElementStatus> closeChannel(uint8_t channelNumber) override;
+
+ void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/);
+
+ static void NotifySeWaitExtension(phNxpEse_wtxState state);
+
+ private:
+ uint8_t mMaxChannelCount;
+ uint8_t mOpenedchannelCount = 0;
+ Mutex seHalLock;
+ bool mIsEseInitialized = false;
+ static std::vector<bool> mOpenedChannels;
+ static sp<V1_0::ISecureElementHalCallback> mCallbackV1_0;
+ static sp<V1_1::ISecureElementHalCallback> mCallbackV1_1;
+ Return<SecureElementStatus> seHalDeInit();
+ ESESTATUS seHalInit();
+ Return<SecureElementStatus> internalCloseChannel(uint8_t channelNumber);
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace secure_element
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_SECURE_ELEMENT_V1_1_SECUREELEMENT_H
diff --git a/snxxx/1.1/VirtualISO.cpp b/snxxx/1.1/VirtualISO.cpp
new file mode 100755
index 0000000..aa0355e
--- /dev/null
+++ b/snxxx/1.1/VirtualISO.cpp
@@ -0,0 +1,655 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#include "VirtualISO.h"
+#include <android-base/logging.h>
+#include "NxpEse.h"
+#include "SecureElement.h"
+#include "eSEClient.h"
+#include "hal_nxpese.h"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Api.h"
+
+namespace vendor {
+namespace nxp {
+namespace virtual_iso {
+namespace V1_0 {
+namespace implementation {
+
+#define LOG_TAG "nxpVIsoese@1.1-service"
+
+#define DEFAULT_BASIC_CHANNEL 0x00
+
+using ::android::hardware::secure_element::V1_1::ISecureElement;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+
+typedef struct gsTransceiveBuffer {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+ hidl_vec<uint8_t>* pRspDataBuff;
+} sTransceiveBuffer_t;
+
+static sTransceiveBuffer_t gsTxRxBuffer;
+static hidl_vec<uint8_t> gsRspDataBuff(256);
+sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback>
+ VirtualISO::mCallbackV1_0 = nullptr;
+sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
+ VirtualISO::mCallbackV1_1 = nullptr;
+std::vector<bool> VirtualISO::mOpenedChannels;
+
+VirtualISO::VirtualISO()
+ : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
+
+Return<void> VirtualISO::init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ LOG(INFO) << "Virtual ISO::init Enter";
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_0 = clientCallback;
+ clientCallback->onStateChange(false);
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setVirtualISOCallBack(clientCallback);
+ return Void();
+ // Register
+ }
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange(true);
+ return Void();
+ }
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ LOG(INFO) << "VISO init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange(true);
+ } else {
+ LOG(ERROR) << "VISO-Hal Init failed";
+ clientCallback->onStateChange(false);
+ }
+ return Void();
+}
+
+Return<void> VirtualISO::init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ LOG(INFO) << "Virtual ISO::init Enter";
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_1 = clientCallback;
+ clientCallback->onStateChange_1_1(false, "NXP SE update going on");
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setVirtualISOCallBack_1_1(clientCallback);
+ return Void();
+ // Register
+ }
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange_1_1(true, "NXP VISIO HAL init ok");
+ return Void();
+ }
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ LOG(INFO) << "VISO init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange_1_1(true, "NXP VISIO HAL init ok");
+ } else {
+ LOG(ERROR) << "VISO-Hal Init failed";
+ clientCallback->onStateChange_1_1(false, "NXP VISIO HAL init failed");
+ }
+ return Void();
+}
+
+Return<void> VirtualISO::getAtr(getAtr_cb _hidl_cb) {
+ hidl_vec<uint8_t> response;
+ _hidl_cb(response);
+ return Void();
+}
+
+Return<bool> VirtualISO::isCardPresent() { return true; }
+
+Return<void> VirtualISO::transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ hidl_vec<uint8_t> result;
+ phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
+ gsTxRxBuffer.cmdData.len = data.size();
+ gsTxRxBuffer.cmdData.p_data =
+ (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
+ if (NULL == gsTxRxBuffer.cmdData.p_data) {
+ LOG(ERROR) << "transmit failed to allocate the Memory!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ }
+ memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
+ LOG(ERROR) << "Acquired the lock in VISO ";
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
+
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "transmit failed!!!";
+ } else {
+ result.resize(gsTxRxBuffer.rspData.len);
+ memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+
+ _hidl_cb(result);
+ if (NULL != gsTxRxBuffer.cmdData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
+ gsTxRxBuffer.cmdData.p_data = NULL;
+ }
+ if (NULL != gsTxRxBuffer.rspData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.rspData.p_data);
+ gsTxRxBuffer.rspData.p_data = NULL;
+ }
+
+ return Void();
+}
+
+Return<void> VirtualISO::openLogicalChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) {
+ hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
+
+ LogicalChannelResponse resApduBuff;
+
+ LOG(INFO) << "Acquired the lock in VISO openLogicalChannel";
+
+ resApduBuff.channelNumber = 0xff;
+ memset(&resApduBuff, 0x00, sizeof(resApduBuff));
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ SecureElementStatus sestatus = SecureElementStatus::IOERROR;
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEse_data cmdApdu;
+ phNxpEse_data rspApdu;
+
+ phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+ cmdApdu.len = manageChannelCommand.size();
+ cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
+ sizeof(uint8_t));
+ memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
+
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+ if (status != ESESTATUS_SUCCESS) {
+ resApduBuff.channelNumber = 0xff;
+ if (NULL != rspApdu.p_data && rspApdu.len > 0) {
+ if ((rspApdu.p_data[0] == 0x64 && rspApdu.p_data[1] == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ }
+ }
+ if (SecureElementStatus::IOERROR != sestatus) {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x81) {
+ resApduBuff.channelNumber = 0xff;
+ sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ resApduBuff.channelNumber = rspApdu.p_data[0];
+ mOpenedchannelCount++;
+ mOpenedChannels[resApduBuff.channelNumber] = true;
+ sestatus = SecureElementStatus::SUCCESS;
+ } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
+ (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ }
+
+ /*Free the allocations*/
+ phNxpEse_free(cmdApdu.p_data);
+ phNxpEse_free(rspApdu.p_data);
+
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ }
+ }
+ /*If manageChanle is failed in any of above cases
+ send the callback and return*/
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ return Void();
+ }
+ LOG(INFO) << "openLogicalChannel Sending selectApdu";
+ sestatus = SecureElementStatus::IOERROR;
+ status = ESESTATUS_FAILED;
+
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ if ((resApduBuff.channelNumber > 0x03) &&
+ (resApduBuff.channelNumber < 0x14)) {
+ /* update CLA byte accoridng to GP spec Table 11-12*/
+ cpdu.cla =
+ 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
+ } else if ((resApduBuff.channelNumber > 0x00) &&
+ (resApduBuff.channelNumber < 0x04)) {
+ /* update CLA byte accoridng to GP spec Table 11-11*/
+ cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
+ } else {
+ LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
+ resApduBuff.channelNumber);
+ resApduBuff.channelNumber = 0xff;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status != ESESTATUS_SUCCESS) {
+ /*Transceive failed*/
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ resApduBuff.selectResponse.resize(responseLen);
+ memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
+ resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
+ resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if (rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(resApduBuff.channelNumber);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ } else {
+ resApduBuff.channelNumber = 0xff;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+
+ return Void();
+}
+
+Return<void> VirtualISO::openBasicChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openBasicChannel_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ hidl_vec<uint8_t> result;
+
+ LOG(INFO) << "Acquired the lock in VISO openBasicChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ cpdu.cla = 0x00; /* Class of instruction */
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ SecureElementStatus sestatus;
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ if (status != ESESTATUS_SUCCESS) {
+ /* Transceive failed */
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ result.resize(responseLen);
+ memcpy(&result[0], rpdu.pdata, rpdu.len);
+ result[responseLen - 1] = rpdu.sw2;
+ result[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ /*Set basic channel reference if it is not set */
+ if (!mOpenedChannels[0]) {
+ mOpenedChannels[0] = true;
+ mOpenedchannelCount++;
+ }
+
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(DEFAULT_BASIC_CHANNEL);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ }
+ }
+ _hidl_cb(result, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+ return Void();
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::internalCloseChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(ERROR) << "internalCloseChannel Enter";
+ LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
+ mMaxChannelCount, channelNumber);
+ if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
+ 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status == ESESTATUS_SUCCESS) {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::closeChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(INFO) << "Acquired the lock in VISO closeChannel";
+ if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
+ 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status == ESESTATUS_SUCCESS) {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+ESESTATUS VirtualISO::seHalInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ status = phNxpEse_open(initParams);
+ if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ mIsEseInitialized = true;
+ LOG(INFO) << "VISO init complete!!!";
+ return ESESTATUS_SUCCESS;
+ }
+ deInitStatus = phNxpEse_deInit();
+ }
+ phNxpEse_close(deInitStatus);
+ mIsEseInitialized = false;
+ }
+ return status;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::seHalDeInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsDeInitDone = true;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
+ sestatus = SecureElementStatus::SUCCESS;
+ ;
+ } else {
+ LOG(ERROR) << "seHalDeInit: Failed";
+ }
+ // Clear all the flags as SPI driver is closed.
+ mIsEseInitialized = false;
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+ return sestatus;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace virtual_iso
+} // namespace nxp
+} // namespace vendor
diff --git a/snxxx/1.1/VirtualISO.h b/snxxx/1.1/VirtualISO.h
new file mode 100755
index 0000000..504a535
--- /dev/null
+++ b/snxxx/1.1/VirtualISO.h
@@ -0,0 +1,105 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
+#define VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
+
+#include <android-base/stringprintf.h>
+#include <android/hardware/secure_element/1.0/types.h>
+#include <android/hardware/secure_element/1.1/ISecureElement.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "phNxpEse_Api.h"
+
+namespace vendor {
+namespace nxp {
+namespace virtual_iso {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::wp;
+using android::base::StringPrintf;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::secure_element::V1_0::LogicalChannelResponse;
+using ::android::hardware::secure_element::V1_0::SecureElementStatus;
+using ::android::hardware::secure_element::V1_1::ISecureElement;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifndef MIN_APDU_LENGTH
+#define MIN_APDU_LENGTH 0x04
+#endif
+#ifndef DEFAULT_BASIC_CHANNEL
+#define DEFAULT_BASIC_CHANNEL 0x00
+#endif
+
+struct VirtualISO : public ISecureElement, public hidl_death_recipient {
+ VirtualISO();
+ Return<void> init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> getAtr(getAtr_cb _hidl_cb) override;
+ Return<bool> isCardPresent() override;
+ Return<void> transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) override;
+ Return<void> openLogicalChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) override;
+ Return<void> openBasicChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openBasicChannel_cb _hidl_cb) override;
+ Return<SecureElementStatus> closeChannel(uint8_t channelNumber) override;
+
+ virtual void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+ // TODO: Implement graceful closure, to close ongoing tx-rx and deinit
+ // T=1 stack
+ // close(0);
+ }
+
+ private:
+ uint8_t mMaxChannelCount;
+ uint8_t mOpenedchannelCount = 0;
+ bool mIsEseInitialized = false;
+ static std::vector<bool> mOpenedChannels;
+ static sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>
+ mCallbackV1_0;
+ static sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
+ mCallbackV1_1;
+ Return<SecureElementStatus> seHalDeInit();
+ ESESTATUS seHalInit();
+ Return<SecureElementStatus> internalCloseChannel(uint8_t channelNumber);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace virtual_iso
+} // namespace nxp
+} // namespace vendor
+
+#endif // VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
diff --git a/snxxx/1.1/android.hardware.secure_element_snxxx@1.1-service.rc b/snxxx/1.1/android.hardware.secure_element_snxxx@1.1-service.rc
new file mode 100755
index 0000000..1a29769
--- /dev/null
+++ b/snxxx/1.1/android.hardware.secure_element_snxxx@1.1-service.rc
@@ -0,0 +1,4 @@
+service vendor.secure_element_hal_service /vendor/bin/hw/android.hardware.secure_element_snxxx@1.1-service
+ class hal
+ user secure_element
+ group secure_element
diff --git a/snxxx/1.2/NxpEseService.cpp b/snxxx/1.2/NxpEseService.cpp
new file mode 100755
index 0000000..7e9559a
--- /dev/null
+++ b/snxxx/1.2/NxpEseService.cpp
@@ -0,0 +1,145 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "nxpese@1.2-service"
+#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 <string.h>
+#include <regex>
+#include "NxpEse.h"
+#include "SecureElement.h"
+#ifdef NXP_BOOTTIME_UPDATE
+#include "eSEClient.h"
+#endif
+
+// Generated HIDL files
+using android::OK;
+using android::base::StringPrintf;
+using android::hardware::configureRpcThreadpool;
+using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::registerPassthroughServiceImplementation;
+using android::hardware::secure_element::V1_2::ISecureElement;
+using android::hardware::secure_element::V1_2::implementation::SecureElement;
+using vendor::nxp::nxpese::V1_0::INxpEse;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+using vendor::nxp::virtual_iso::V1_0::implementation::VirtualISO;
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+int main() {
+ status_t status;
+
+ char terminalID[5] = "eSE1";
+ const char* SEterminal = "eSEx";
+ bool ret = false;
+
+ android::sp<ISecureElement> se_service = nullptr;
+ android::sp<INxpEse> nxp_se_service = nullptr;
+ android::sp<ISecureElement> virtual_iso_service = nullptr;
+
+ ALOGI("Secure Element HAL Service 1.2 is starting.");
+ try {
+ se_service = new SecureElement();
+ if (se_service == nullptr) {
+ ALOGE("Can not create an instance of Secure Element HAL Iface, exiting.");
+ goto shutdown;
+ }
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+#ifdef NXP_BOOTTIME_UPDATE
+ checkEseClientUpdate();
+ ret = geteSETerminalId(terminalID);
+#else
+ ret = true;
+#endif
+ ALOGI("Terminal val = %s", terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ ALOGI("Terminal ID found");
+ status = se_service->registerAsService(terminalID);
+
+ if (status != OK) {
+ ALOGE("Could not register service for Secure Element HAL Iface (%d).",
+ status);
+ goto shutdown;
+ }
+ ALOGI("Secure Element Service is ready");
+
+ ALOGI("NXP Secure Element Extn Service 1.0 is starting.");
+ nxp_se_service = new NxpEse();
+ if (nxp_se_service == nullptr) {
+ ALOGE(
+ "Can not create an instance of NXP Secure Element Extn "
+ "Iface,exiting.");
+ goto shutdown;
+ }
+ status = nxp_se_service->registerAsService();
+ if (status != OK) {
+ ALOGE(
+ "Could not register service for Power Secure Element Extn Iface "
+ "(%d).",
+ status);
+ goto shutdown;
+ }
+ ALOGI("Secure Element Service is ready");
+ }
+
+ ALOGI("Virtual ISO HAL Service 1.0 is starting.");
+ virtual_iso_service = new VirtualISO();
+ if (virtual_iso_service == nullptr) {
+ ALOGE("Can not create an instance of Virtual ISO HAL Iface, exiting.");
+ goto shutdown;
+ }
+#ifdef NXP_BOOTTIME_UPDATE
+ ret = geteUICCTerminalId(terminalID);
+#else
+ strncpy(terminalID, "eSE2", 4);
+ ret = true;
+#endif
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ status = virtual_iso_service->registerAsService(terminalID);
+ if (status != OK) {
+ ALOGE("Could not register service for Virtual ISO HAL Iface (%d).",
+ status);
+ } else {
+ ALOGI("Virtual ISO: Secure Element Service is ready");
+ }
+ }
+
+#ifdef NXP_BOOTTIME_UPDATE
+ perform_eSEClientUpdate();
+#endif
+ joinRpcThreadpool();
+ } catch (const std::length_error& e) {
+ ALOGE("Length Exception occurred = %s ", e.what());
+ } catch (const std::__1::ios_base::failure& e) {
+ ALOGE("ios failure Exception occurred = %s ", e.what());
+ } catch (std::__1::regex_error& e) {
+ ALOGE("Regex Exception occurred = %s ", e.what());
+ }
+// Should not pass this line
+shutdown:
+ // In normal operation, we don't expect the thread pool to exit
+ ALOGE("Secure Element Service is shutting down");
+ return 1;
+}
diff --git a/snxxx/1.2/OsuHal/inc/OsuHalExtn.h b/snxxx/1.2/OsuHal/inc/OsuHalExtn.h
new file mode 100644
index 0000000..6630d7a
--- /dev/null
+++ b/snxxx/1.2/OsuHal/inc/OsuHalExtn.h
@@ -0,0 +1,80 @@
+/******************************************************************************
+ *
+ * Copyright 2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <string.h>
+#include "phNxpEse_Api.h"
+
+using ::android::hardware::hidl_vec;
+#define OSU_PROP_CLA 0x80
+#define OSU_PROP_INS 0xDF
+#define OSU_PROP_RST_P1 0xEF
+
+#define ISO7816_BASIC_CHANNEL 0x00
+#define ISO7816_CLA_OFFSET 0
+#define ISO7816_INS_OFFSET 1
+#define ISO7816_P1_OFFSET 2
+#define ISO7816_P2_OFFSET 3
+#define ISO7816_LC_OFFSET 4
+#define ISO7816_EXTENDED_LC_VALUE 0
+#define ISO7816_SHORT_APDU_HEADER 5
+#define ISO7816_EXTENDED_APDU_HEADER 7
+#define ISO7816_CLA_CHN_MASK 0x03
+#define IS_OSU_MODE(...) (OsuHalExtn::getInstance().isOsuMode(__VA_ARGS__))
+
+class OsuHalExtn {
+ public:
+ typedef enum {
+ NON_OSU_MODE, // Normal Mode : All HAL APIs allowed
+ OSU_PROP_MODE, // OSU mode : Only OSU JAR command allowed
+ OSU_GP_MODE, // OSU Mode : GP command in the OSU mode
+ OSU_RST_MODE, // OSU mode : Proprietary HARD reset
+ OSU_BLOCKED_MODE, // OSU mode : Command not allowed return error
+ } OsuApduMode;
+
+ typedef enum {
+ INIT,
+ OPENBASIC,
+ OPENLOGICAL,
+ TRANSMIT,
+ CLOSE,
+ RESET,
+ } SecureElementAPI;
+
+ static OsuHalExtn& getInstance();
+
+ OsuApduMode isOsuMode(const hidl_vec<uint8_t>& evt, uint8_t type,
+ phNxpEse_data* pCmdData = nullptr);
+ bool isOsuMode(uint8_t type, uint8_t channel = 0xFF);
+ virtual ~OsuHalExtn();
+ OsuHalExtn() noexcept;
+ void checkAndUpdateOsuMode();
+ unsigned long int getOSUMaxWtxCount();
+
+ private:
+ bool isAppOSUMode;
+ bool isJcopOSUMode;
+ static const hidl_vec<uint8_t> osu_aid[10];
+ OsuApduMode checkTransmit(uint8_t* input, size_t length, uint32_t* outLength);
+ bool isOsuMode();
+};
diff --git a/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp b/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp
new file mode 100644
index 0000000..8fcffb7
--- /dev/null
+++ b/snxxx/1.2/OsuHal/src/OsuHalExtn.cpp
@@ -0,0 +1,273 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#include "OsuHalExtn.h"
+#include <ese_config.h>
+
+#define LOG_TAG "OsuHalExtn"
+#include <log/log.h>
+
+#define DEFAULT_MAX_WTX_COUNT 60
+
+const static hidl_vec<uint8_t> OSU_AID = {0x4F, 0x70, 0x80, 0x13, 0x04,
+ 0xDE, 0xAD, 0xBE, 0xEF};
+const static uint8_t defaultSelectAid[] = {0x00, 0xA4, 0x04, 0x00, 0x00};
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::isOsuMode
+**
+** Description: Check, update and return current mode for below SE HAL API
+** requests openBasicChannel() and transmit()
+**
+** Returns: OsuApduMode(NON_OSU_MODE, OSU_PROP_MODE, OSU_RST_MODE,
+** OSU_BLOCKED_MODE, OSU_GP_MODE)
+**
+*******************************************************************************/
+OsuHalExtn::OsuApduMode OsuHalExtn::isOsuMode(const hidl_vec<uint8_t>& evt,
+ uint8_t type,
+ phNxpEse_data* pCmdData) {
+ OsuApduMode osuSubState = (isAppOSUMode ? OSU_PROP_MODE : NON_OSU_MODE);
+
+ switch (type) {
+ case OPENBASIC:
+ /*
+ * update & return OSU_PROP_MODE if OpenBasicChannel AID request matches
+ * OSU_AID
+ */
+ if (!memcmp(&evt[0], &OSU_AID[0], OSU_AID.size())) {
+ isAppOSUMode = true;
+ osuSubState = OSU_PROP_MODE;
+ ALOGD("Dedicated mode is set !!!!!!!!!!!!!!!!!");
+ } else if (isOsuMode()) {
+ // OpenBasic channel requests with non OSU_AID are not allowed/blocked
+ osuSubState = OSU_BLOCKED_MODE;
+ ALOGE("Non OSU AID Not allowed");
+ }
+ 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);
+ } else {
+ pCmdData->len = evt.size();
+ osuSubState = NON_OSU_MODE;
+ }
+ break;
+ }
+ return osuSubState;
+}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::isOsuMode
+**
+** Description: Check, update and return current mode for below SE HAL API
+** requests init(), openLogicalChannel() and closeChannel()
+**
+** Returns: true(OSU)/false(normal)
+**
+*******************************************************************************/
+bool OsuHalExtn::isOsuMode(uint8_t type, uint8_t channel) {
+ switch (type) {
+ case INIT:
+ checkAndUpdateOsuMode();
+ break;
+ case OPENLOGICAL:
+ // No action, only return current mode
+ break;
+ case CLOSE:
+ /*
+ * If in OSU mode close basic channel is called
+ * clear osu APP and update JCOP mode
+ */
+ if (channel == ISO7816_BASIC_CHANNEL && isOsuMode()) {
+ if (phNxpEse_doResetProtection(false) != ESESTATUS_SUCCESS) {
+ ALOGE("Disable Reset Protection Failed");
+ }
+ phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
+ isAppOSUMode = false;
+ ALOGD("Setting to normal mode!!!");
+ }
+ break;
+ }
+ return isOsuMode();
+}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::checkAndUpdateOsuMode
+**
+** Description: Check and update current JCOP mode OSU/Normal
+**
+** Returns: None
+**
+*******************************************************************************/
+void OsuHalExtn::checkAndUpdateOsuMode() {
+ isJcopOSUMode = (phNxpEse_GetOsMode() == OSU_MODE);
+}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::getInstance
+**
+** Description: get class singleton object
+**
+** Returns: OsuHalExtn
+**
+*******************************************************************************/
+OsuHalExtn& OsuHalExtn::getInstance() {
+ static OsuHalExtn manager;
+ return manager;
+}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::OsuHalExtn()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+OsuHalExtn::OsuHalExtn() noexcept {
+ isAppOSUMode = false;
+ isJcopOSUMode = false;
+}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::~OsuHalExtn()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+OsuHalExtn::~OsuHalExtn() {}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::isOsuMode()
+**
+** Description: Returns current JCOP mode
+**
+** Returns: true(OSU)/false(Normal)
+**
+*******************************************************************************/
+bool OsuHalExtn::isOsuMode() { return (isAppOSUMode || isJcopOSUMode); }
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::checkTransmit
+**
+** Description: Process transmit request in OSU mode
+** 1) Unwrap proprietary APDU's to native commands
+** 2) Block unexpected command request in OSU Mode
+** 3) Perform hard reset on receiving proprietary reset APDU
+**
+** Returns: OsuApduMode
+**
+*******************************************************************************/
+OsuHalExtn::OsuApduMode OsuHalExtn::checkTransmit(uint8_t* input, size_t length,
+ uint32_t* outLength) {
+ OsuHalExtn::OsuApduMode halMode = NON_OSU_MODE;
+
+ /*
+ * 1) Transmit request on logical channels(ISO7816_CLA_CHN_MASK)shall be
+ * blocked in OSU mode
+ * 2) Empty/Default GP card manager select from OMAPI shall
+ * be blocked in OSU Mode
+ */
+ if (((*input & ISO7816_CLA_CHN_MASK) != ISO7816_BASIC_CHANNEL) ||
+ (isJcopOSUMode && (length == ISO7816_SHORT_APDU_HEADER &&
+ !memcmp(input, defaultSelectAid, length)))) {
+ phNxpEse_free(input);
+ input = nullptr;
+ halMode = OSU_BLOCKED_MODE;
+ } else if ((*input == OSU_PROP_CLA) &&
+ (*(input + ISO7816_INS_OFFSET) == OSU_PROP_INS) &&
+ (*(input + ISO7816_P1_OFFSET) != OSU_PROP_RST_P1)) {
+ /*
+ * 1) Unwrap GP command to native commands
+ * 2) Check APDU type short/extended before unwrapping
+ */
+ ALOGD("checkTransmit in OSU_PROP_MODE");
+ 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);
+ } else {
+ *outLength = 0;
+ ALOGE("checkTransmit input data length is incorrect");
+ }
+ } 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);
+ } else {
+ *outLength = 0;
+ ALOGE("checkTransmit input data length is incorrect");
+ }
+ }
+ halMode = OSU_PROP_MODE;
+ } else if ((*input == OSU_PROP_CLA) &&
+ (*(input + ISO7816_INS_OFFSET) == OSU_PROP_INS) &&
+ (*(input + ISO7816_P1_OFFSET) == OSU_PROP_RST_P1)) {
+ // eSE hard reset on receiving proprietary reset APDU
+ ALOGD("checkTransmit in OSU_PROP_RST_INS");
+ if (phNxpEse_SetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SetEndPoint_Cntxt failed!!!");
+ }
+ phNxpEse_resetJcopUpdate();
+ if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_ResetEndPoint_Cntxt failed!!!");
+ }
+ // Update mode after eSE reset
+ checkAndUpdateOsuMode();
+ phNxpEse_free(input);
+ input = nullptr;
+ halMode = OSU_RST_MODE;
+ } else {
+ // Process remaining OSU commands
+ *outLength = length;
+ halMode = OSU_GP_MODE;
+ }
+ return halMode;
+}
+
+/*******************************************************************************
+**
+** Function: OsuHalExtn::getOSUMaxWtxCount
+**
+** Description: Read OSU_MAX_WTX_COUNT from config file allowed when in OSU
+** mode
+**
+** Returns: Return maximum WTX count
+**
+*******************************************************************************/
+unsigned long int OsuHalExtn::getOSUMaxWtxCount() {
+ return EseConfig::getUnsigned(NAME_NXP_OSU_MAX_WTX_COUNT,
+ DEFAULT_MAX_WTX_COUNT);
+}
diff --git a/snxxx/1.2/SecureElement.cpp b/snxxx/1.2/SecureElement.cpp
new file mode 100755
index 0000000..4c6756d
--- /dev/null
+++ b/snxxx/1.2/SecureElement.cpp
@@ -0,0 +1,832 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#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
+/* Mutex to synchronize multiple transceive */
+
+namespace android {
+namespace hardware {
+namespace secure_element {
+namespace V1_2 {
+namespace implementation {
+
+#define LOG_TAG "nxpese@1.2-service"
+#define DEFAULT_BASIC_CHANNEL 0x00
+#define INVALID_LEN_SW1 0x64
+#define INVALID_LEN_SW2 0xFF
+
+typedef struct gsTransceiveBuffer {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+ hidl_vec<uint8_t>* pRspDataBuff;
+} sTransceiveBuffer_t;
+
+static sTransceiveBuffer_t gsTxRxBuffer;
+static hidl_vec<uint8_t> gsRspDataBuff(256);
+sp<V1_0::ISecureElementHalCallback> SecureElement::mCallbackV1_0 = nullptr;
+sp<V1_1::ISecureElementHalCallback> SecureElement::mCallbackV1_1 = nullptr;
+std::vector<bool> SecureElement::mOpenedChannels;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+SecureElement::SecureElement()
+ : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
+
+void SecureElement::NotifySeWaitExtension(phNxpEse_wtxState state) {
+ if (state == WTX_ONGOING) {
+ LOG(INFO) << "SecureElement::WTX ongoing";
+ } else if (state == WTX_END) {
+ LOG(INFO) << "SecureElement::WTX ended";
+ }
+}
+
+Return<void> SecureElement::init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+ initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ LOG(INFO) << "SecureElement::init called here";
+#ifdef NXP_BOOTTIME_UPDATE
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_0 = clientCallback;
+ clientCallback->onStateChange(false);
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setSeCallBack(clientCallback);
+ return Void();
+ // Register
+ }
+#endif
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange(true);
+ return Void();
+ }
+
+ phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ /*update OS mode during first init*/
+ IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
+
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ LOG(INFO) << "ESE SPI init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange(true);
+ mCallbackV1_0 = clientCallback;
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ clientCallback->onStateChange(false);
+ }
+ return Void();
+}
+
+Return<void> SecureElement::init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+ initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+ LOG(INFO) << "SecureElement::init called here";
+#ifdef NXP_BOOTTIME_UPDATE
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_1 = clientCallback;
+ clientCallback->onStateChange_1_1(false, "NXP SE update going on");
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setSeCallBack_1_1(clientCallback);
+ return Void();
+ // Register
+ }
+#endif
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
+ return Void();
+ }
+
+ phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ /*update OS mode during first init*/
+ IS_OSU_MODE(OsuHalExtn::getInstance().INIT, 0);
+
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ LOG(INFO) << "ESE SPI init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange_1_1(true, "NXP SE HAL init ok");
+ mCallbackV1_1 = clientCallback;
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ clientCallback->onStateChange_1_1(false, "NXP SE HAL init failed");
+ }
+ return Void();
+}
+
+Return<void> SecureElement::getAtr(getAtr_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ LOG(ERROR) << "Processing ATR.....";
+ phNxpEse_data atrData;
+ hidl_vec<uint8_t> response;
+ ESESTATUS status = ESESTATUS_FAILED;
+ bool mIsSeHalInitDone = false;
+
+ if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >=
+ OsuHalExtn::getInstance().OSU_PROP_MODE) {
+ LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
+ _hidl_cb(response);
+ return Void();
+ }
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(response); /*Return with empty Vector*/
+ return Void();
+ } else {
+ mIsSeHalInitDone = true;
+ }
+ }
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "Endpoint set failed";
+ }
+ status = phNxpEse_getAtr(&atrData);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_getAtr failed";
+ _hidl_cb(response); /*Return with empty Vector*/
+ return Void();
+ } else {
+ response.resize(atrData.len);
+ memcpy(&response[0], atrData.p_data, atrData.len);
+ }
+
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "Endpoint set failed";
+ }
+
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(INFO) << StringPrintf("ATR Data[BytebyByte]=Look below for %d bytes",
+ atrData.len);
+ for (auto i = response.begin(); i != response.end(); ++i)
+ LOG(INFO) << StringPrintf("0x%x\t", *i);
+ }
+
+ _hidl_cb(response);
+ if (atrData.p_data != NULL) {
+ phNxpEse_free(atrData.p_data);
+ }
+ if (mIsSeHalInitDone) {
+ if (SecureElementStatus::SUCCESS != seHalDeInit())
+ LOG(ERROR) << "phNxpEse_getAtr seHalDeInit failed";
+ mIsEseInitialized = false;
+ mIsSeHalInitDone = false;
+ }
+ return Void();
+}
+
+Return<bool> SecureElement::isCardPresent() { return true; }
+
+Return<void> SecureElement::transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ ESESTATUS status = ESESTATUS_FAILED;
+ hidl_vec<uint8_t> result;
+ phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
+ gsTxRxBuffer.cmdData.len = (uint32_t)data.size();
+ gsTxRxBuffer.cmdData.p_data =
+ (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
+ if (NULL == gsTxRxBuffer.cmdData.p_data) {
+ LOG(ERROR) << "transmit failed to allocate the Memory!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ }
+ OsuHalExtn::OsuApduMode mode = IS_OSU_MODE(
+ data, OsuHalExtn::getInstance().TRANSMIT, &gsTxRxBuffer.cmdData);
+ if (mode == OsuHalExtn::getInstance().OSU_BLOCKED_MODE) {
+ LOG(ERROR) << "Not allowed in dedicated mode!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ } else if (mode == OsuHalExtn::getInstance().OSU_RST_MODE) {
+ uint8_t sw[2] = {0x90, 0x00};
+ result.resize(sizeof(sw));
+ memcpy(&result[0], sw, sizeof(sw));
+ _hidl_cb(result);
+ return Void();
+ } else {
+ // continue with normal processing
+ }
+ // memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
+ LOG(INFO) << "Acquired lock for SPI";
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
+
+ if (status == ESESTATUS_SUCCESS) {
+ result.resize(gsTxRxBuffer.rspData.len);
+ memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
+ } else if (status == ESESTATUS_INVALID_RECEIVE_LENGTH) {
+ uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
+ result.resize(sizeof(respBuf));
+ memcpy(&result[0], respBuf, sizeof(respBuf));
+ } else {
+ LOG(ERROR) << "transmit failed!!!";
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+
+ _hidl_cb(result);
+ if (NULL != gsTxRxBuffer.cmdData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
+ gsTxRxBuffer.cmdData.p_data = NULL;
+ }
+ if (NULL != gsTxRxBuffer.rspData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.rspData.p_data);
+ gsTxRxBuffer.rspData.p_data = NULL;
+ }
+
+ return Void();
+}
+
+Return<void> SecureElement::openLogicalChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
+
+ LogicalChannelResponse resApduBuff;
+ resApduBuff.channelNumber = 0xff;
+ memset(&resApduBuff, 0x00, sizeof(resApduBuff));
+
+ LOG(INFO) << "Acquired the lock from SPI openLogicalChannel";
+
+ if (IS_OSU_MODE(OsuHalExtn::getInstance().OPENLOGICAL) >=
+ OsuHalExtn::getInstance().OSU_PROP_MODE) {
+ LOG(ERROR) << "%s: Not allowed in dedicated mode!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ if (mOpenedChannels.size() == 0x00) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ }
+
+ SecureElementStatus sestatus = SecureElementStatus::IOERROR;
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEse_data cmdApdu;
+ phNxpEse_data rspApdu;
+
+ phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+
+ phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+ cmdApdu.len = (uint32_t)manageChannelCommand.size();
+ cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
+ sizeof(uint8_t));
+ memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+ if (status != ESESTATUS_SUCCESS) {
+ resApduBuff.channelNumber = 0xff;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x81) {
+ resApduBuff.channelNumber = 0xff;
+ sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ resApduBuff.channelNumber = rspApdu.p_data[0];
+ mOpenedchannelCount++;
+ mOpenedChannels[resApduBuff.channelNumber] = true;
+ sestatus = SecureElementStatus::SUCCESS;
+ } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
+ (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ }
+ /*Free the allocations*/
+ phNxpEse_free(cmdApdu.p_data);
+ phNxpEse_free(rspApdu.p_data);
+
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ if (mOpenedchannelCount == 0) {
+ SecureElementStatus deInitStatus = seHalDeInit();
+ if (deInitStatus != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ }
+ }
+ /*If manageChanle is failed in any of above cases
+ send the callback and return*/
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ return Void();
+ }
+ LOG(INFO) << "openLogicalChannel Sending selectApdu";
+ sestatus = SecureElementStatus::IOERROR;
+ status = ESESTATUS_FAILED;
+
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ if ((resApduBuff.channelNumber > 0x03) &&
+ (resApduBuff.channelNumber < 0x14)) {
+ /* update CLA byte accoridng to GP spec Table 11-12*/
+ cpdu.cla =
+ 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
+ } else if ((resApduBuff.channelNumber > 0x00) &&
+ (resApduBuff.channelNumber < 0x04)) {
+ /* update CLA byte accoridng to GP spec Table 11-11*/
+ cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
+ } else {
+ LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
+ resApduBuff.channelNumber);
+ resApduBuff.channelNumber = 0xff;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = (uint16_t)aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status != ESESTATUS_SUCCESS) {
+ /*Transceive failed*/
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ resApduBuff.selectResponse.resize(responseLen);
+ memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
+ resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
+ resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if ((rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) || (rpdu.sw1 == 0x62) ||
+ (rpdu.sw1 == 0x63)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
+ (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(resApduBuff.channelNumber);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ } else {
+ resApduBuff.channelNumber = 0xff;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+
+ return Void();
+}
+
+Return<void> SecureElement::openBasicChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openBasicChannel_cb _hidl_cb) {
+ AutoMutex guard(seHalLock);
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ hidl_vec<uint8_t> result;
+ hidl_vec<uint8_t> ls_aid = {0xA0, 0x00, 0x00, 0x03, 0x96, 0x41, 0x4C,
+ 0x41, 0x01, 0x43, 0x4F, 0x52, 0x01};
+
+ LOG(ERROR) << "Acquired the lock in SPI openBasicChannel";
+ OsuHalExtn::OsuApduMode mode =
+ IS_OSU_MODE(aid, OsuHalExtn::getInstance().OPENBASIC);
+ if (mode == OsuHalExtn::OSU_PROP_MODE) {
+ uint8_t sw[2] = {0x90, 0x00};
+ result.resize(sizeof(sw));
+ memcpy(&result[0], sw, 2);
+ if (mIsEseInitialized) {
+ /*Close existing sessions if any to start dedicated OSU Mode
+ * with OSU specific settings in TZ/TEE*/
+ if (seHalDeInit() != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+ phNxpEse_setWtxCountLimit(OsuHalExtn::getInstance().getOSUMaxWtxCount());
+ ESESTATUS status = ESESTATUS_FAILED;
+ uint8_t retry = 0;
+ do {
+ /*For Reset Recovery*/
+ status = seHalInit();
+ } while (status != ESESTATUS_SUCCESS && retry++ < 1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ phNxpEse_setWtxCountLimit(RESET_APP_WTX_COUNT);
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ if (phNxpEse_doResetProtection(true) != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: Enable Reset Protection Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::FAILED);
+ } else {
+ _hidl_cb(result, SecureElementStatus::SUCCESS);
+ }
+ return Void();
+ } else if (mode == OsuHalExtn::OSU_BLOCKED_MODE) {
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ } else {
+ }
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ if (mOpenedChannels.size() == 0x00) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ }
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ cpdu.cla = 0x00; /* Class of instruction */
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = (uint16_t)aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ SecureElementStatus sestatus;
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ if (status != ESESTATUS_SUCCESS) {
+ /* Transceive failed */
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ result.resize(responseLen);
+ memcpy(&result[0], rpdu.pdata, rpdu.len);
+ result[responseLen - 1] = rpdu.sw2;
+ result[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if (((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) || (rpdu.sw1 == 0x62) ||
+ (rpdu.sw1 == 0x63)) {
+ /*Set basic channel reference if it is not set */
+ if (!mOpenedChannels[0]) {
+ mOpenedChannels[0] = true;
+ mOpenedchannelCount++;
+ }
+
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if ((rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) ||
+ (rpdu.sw1 == 0x69 && (rpdu.sw2 == 0x99 || rpdu.sw2 == 0x85))) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(DEFAULT_BASIC_CHANNEL);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ }
+ }
+ _hidl_cb(result, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+ return Void();
+}
+
+Return<SecureElementStatus> SecureElement::internalCloseChannel(
+ uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ 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) {
+ 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status == ESESTATUS_SUCCESS) {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ }
+ if (channelNumber < mMaxChannelCount) {
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+
+Return<SecureElementStatus> SecureElement::closeChannel(uint8_t channelNumber) {
+ AutoMutex guard(seHalLock);
+ if (IS_OSU_MODE(OsuHalExtn::getInstance().CLOSE, channelNumber) ==
+ OsuHalExtn::getInstance().NON_OSU_MODE) {
+ return internalCloseChannel(channelNumber);
+ } else {
+ /*Decrement channel count opened to
+ * keep in sync with service */
+ if (channelNumber < mMaxChannelCount) {
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+ return SecureElementStatus::SUCCESS;
+ }
+}
+
+void SecureElement::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+ LOG(ERROR) << " SecureElement serviceDied!!!";
+ mIsEseInitialized = false;
+ if (seHalDeInit() != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "SE Deinit not successful";
+ }
+}
+ESESTATUS SecureElement::seHalInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+ initParams.fPtr_WtxNtf = SecureElement::NotifySeWaitExtension;
+
+ status = phNxpEse_open(initParams);
+ if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(0) &&
+ ESESTATUS_SUCCESS == (status = phNxpEse_init(initParams))) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(0)) {
+ mIsEseInitialized = true;
+ LOG(INFO) << "ESE SPI init complete!!!";
+ return ESESTATUS_SUCCESS;
+ }
+ } else {
+ LOG(INFO) << "ESE SPI init NOT successful";
+ status = ESESTATUS_FAILED;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (phNxpEse_close(deInitStatus) != ESESTATUS_SUCCESS) {
+ LOG(INFO) << "ESE close not successful";
+ status = ESESTATUS_FAILED;
+ }
+ mIsEseInitialized = false;
+ }
+ return status;
+}
+
+Return<SecureElementStatus> SecureElement::seHalDeInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsDeInitDone = true;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
+ sestatus = SecureElementStatus::SUCCESS;
+ ;
+ } else {
+ LOG(ERROR) << "seHalDeInit: Failed";
+ }
+ mIsEseInitialized = false;
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+
+ return sestatus;
+}
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+SecureElement::reset() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ LOG(ERROR) << "%s: Enter" << __func__;
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ }
+ }
+ if (status == ESESTATUS_SUCCESS) {
+ mCallbackV1_1->onStateChange_1_1(false, "reset the SE");
+ status = phNxpEse_reset();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: SecureElement reset failed!!" << __func__;
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ if (mOpenedChannels.size() == 0x00) {
+ mMaxChannelCount =
+ (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ }
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+ mCallbackV1_1->onStateChange_1_1(true, "SE initialized");
+ }
+ }
+ LOG(ERROR) << "%s: Exit" << __func__;
+ return sestatus;
+}
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace secure_element
+} // namespace hardware
+} // namespace android
diff --git a/snxxx/1.2/SecureElement.h b/snxxx/1.2/SecureElement.h
new file mode 100755
index 0000000..8853444
--- /dev/null
+++ b/snxxx/1.2/SecureElement.h
@@ -0,0 +1,127 @@
+/******************************************************************************
+ *
+ * Copyright 2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef ANDROID_HARDWARE_SECURE_ELEMENT_V1_2_SECUREELEMENT_H
+#define ANDROID_HARDWARE_SECURE_ELEMENT_V1_2_SECUREELEMENT_H
+
+#include <SyncEvent.h>
+#include <android-base/stringprintf.h>
+#include <android/hardware/secure_element/1.0/types.h>
+#include <android/hardware/secure_element/1.2/ISecureElement.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <pthread.h>
+#include "OsuHalExtn.h"
+#include "phNxpEse_Api.h"
+
+class ThreadMutex {
+ public:
+ ThreadMutex();
+ virtual ~ThreadMutex();
+ void lock();
+ void unlock();
+ operator pthread_mutex_t*() { return &mMutex; }
+
+ private:
+ pthread_mutex_t mMutex;
+};
+
+class AutoThreadMutex {
+ public:
+ AutoThreadMutex(ThreadMutex& m);
+ virtual ~AutoThreadMutex();
+ operator ThreadMutex&() { return mm; }
+ operator pthread_mutex_t*() { return (pthread_mutex_t*)mm; }
+
+ private:
+ ThreadMutex& mm;
+};
+
+namespace android {
+namespace hardware {
+namespace secure_element {
+namespace V1_2 {
+namespace implementation {
+
+using ::android::sp;
+using android::base::StringPrintf;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::secure_element::V1_0::LogicalChannelResponse;
+using ::android::hardware::secure_element::V1_0::SecureElementStatus;
+using ::android::hardware::secure_element::V1_2::ISecureElement;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifndef MIN_APDU_LENGTH
+#define MIN_APDU_LENGTH 0x04
+#endif
+#ifndef DEFAULT_BASIC_CHANNEL
+#define DEFAULT_BASIC_CHANNEL 0x00
+#endif
+
+struct SecureElement : public V1_2::ISecureElement,
+ public hidl_death_recipient {
+ SecureElement();
+ Return<void> init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> getAtr(getAtr_cb _hidl_cb) override;
+ Return<bool> isCardPresent() override;
+ Return<void> transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) override;
+ Return<void> openLogicalChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) override;
+ Return<void> openBasicChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openBasicChannel_cb _hidl_cb) override;
+ Return<SecureElementStatus> closeChannel(uint8_t channelNumber) override;
+
+ void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/);
+
+ static void NotifySeWaitExtension(phNxpEse_wtxState state);
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ reset();
+
+ private:
+ uint8_t mMaxChannelCount;
+ uint8_t mOpenedchannelCount = 0;
+ Mutex seHalLock;
+ bool mIsEseInitialized = false;
+ static std::vector<bool> mOpenedChannels;
+ static sp<V1_0::ISecureElementHalCallback> mCallbackV1_0;
+ static sp<V1_1::ISecureElementHalCallback> mCallbackV1_1;
+ Return<SecureElementStatus> seHalDeInit();
+ ESESTATUS seHalInit();
+ Return<SecureElementStatus> internalCloseChannel(uint8_t channelNumber);
+};
+
+} // namespace implementation
+} // namespace V1_2
+} // namespace secure_element
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_SECURE_ELEMENT_V1_1_SECUREELEMENT_H
diff --git a/snxxx/1.2/VirtualISO.cpp b/snxxx/1.2/VirtualISO.cpp
new file mode 100755
index 0000000..4550605
--- /dev/null
+++ b/snxxx/1.2/VirtualISO.cpp
@@ -0,0 +1,704 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#include "VirtualISO.h"
+#include <android-base/logging.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 "hal_nxpese.h"
+
+namespace vendor {
+namespace nxp {
+namespace virtual_iso {
+namespace V1_0 {
+namespace implementation {
+
+#define LOG_TAG "nxpVIsoese@1.2-service"
+
+#define DEFAULT_BASIC_CHANNEL 0x00
+
+using ::android::hardware::secure_element::V1_2::ISecureElement;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+
+typedef struct gsTransceiveBuffer {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+ hidl_vec<uint8_t>* pRspDataBuff;
+} sTransceiveBuffer_t;
+
+static sTransceiveBuffer_t gsTxRxBuffer;
+static hidl_vec<uint8_t> gsRspDataBuff(256);
+sp<::android::hardware::secure_element::V1_0::ISecureElementHalCallback>
+ VirtualISO::mCallbackV1_0 = nullptr;
+sp<::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
+ VirtualISO::mCallbackV1_1 = nullptr;
+std::vector<bool> VirtualISO::mOpenedChannels;
+
+VirtualISO::VirtualISO()
+ : mMaxChannelCount(0), mOpenedchannelCount(0), mIsEseInitialized(false) {}
+
+Return<void> VirtualISO::init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ LOG(INFO) << "Virtual ISO::init Enter";
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+#ifdef NXP_BOOTTIME_UPDATE
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_0 = clientCallback;
+ clientCallback->onStateChange(false);
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setVirtualISOCallBack(clientCallback);
+ return Void();
+ // Register
+ }
+#endif
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange(true);
+ return Void();
+ }
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ LOG(INFO) << "VISO init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange(true);
+ } else {
+ LOG(ERROR) << "VISO-Hal Init failed";
+ clientCallback->onStateChange(false);
+ }
+ return Void();
+}
+
+Return<void> VirtualISO::init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsInitDone = false;
+ phNxpEse_initParams initParams;
+ LOG(INFO) << "Virtual ISO::init Enter";
+ gsTxRxBuffer.pRspDataBuff = &gsRspDataBuff;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (clientCallback == nullptr) {
+ return Void();
+ } else {
+ clientCallback->linkToDeath(this, 0 /*cookie*/);
+ }
+#ifdef NXP_BOOTTIME_UPDATE
+ if (ese_update != ESE_UPDATE_COMPLETED) {
+ mCallbackV1_1 = clientCallback;
+ clientCallback->onStateChange_1_1(false, "NXP SE update going on");
+ LOG(INFO) << "ESE JCOP Download in progress";
+ NxpEse::setVirtualISOCallBack_1_1(clientCallback);
+ return Void();
+ // Register
+ }
+#endif
+ if (mIsEseInitialized) {
+ clientCallback->onStateChange_1_1(true, "NXP VISIO HAL init ok");
+ return Void();
+ }
+ status = phNxpEse_open(initParams);
+ if (status == ESESTATUS_SUCCESS || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ LOG(INFO) << "VISO init complete!!!";
+ mIsInitDone = true;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ }
+ if (status == ESESTATUS_SUCCESS && mIsInitDone) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ clientCallback->onStateChange_1_1(true, "NXP VISIO HAL init ok");
+ } else {
+ LOG(ERROR) << "VISO-Hal Init failed";
+ clientCallback->onStateChange_1_1(false, "NXP VISIO HAL init failed");
+ }
+ return Void();
+}
+
+Return<void> VirtualISO::getAtr(getAtr_cb _hidl_cb) {
+ hidl_vec<uint8_t> response;
+ _hidl_cb(response);
+ return Void();
+}
+
+Return<bool> VirtualISO::isCardPresent() { return true; }
+
+Return<void> VirtualISO::transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ hidl_vec<uint8_t> result;
+ phNxpEse_memset(&gsTxRxBuffer.cmdData, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&gsTxRxBuffer.rspData, 0x00, sizeof(phNxpEse_data));
+ gsTxRxBuffer.cmdData.len = data.size();
+ gsTxRxBuffer.cmdData.p_data =
+ (uint8_t*)phNxpEse_memalloc(data.size() * sizeof(uint8_t));
+ if (NULL == gsTxRxBuffer.cmdData.p_data) {
+ LOG(ERROR) << "transmit failed to allocate the Memory!!!";
+ /*Return empty hidl_vec*/
+ _hidl_cb(result);
+ return Void();
+ }
+ memcpy(gsTxRxBuffer.cmdData.p_data, data.data(), gsTxRxBuffer.cmdData.len);
+ LOG(ERROR) << "Acquired the lock in VISO ";
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&gsTxRxBuffer.cmdData, &gsTxRxBuffer.rspData);
+
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "transmit failed!!!";
+ } else {
+ result.resize(gsTxRxBuffer.rspData.len);
+ memcpy(&result[0], gsTxRxBuffer.rspData.p_data, gsTxRxBuffer.rspData.len);
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+
+ _hidl_cb(result);
+ if (NULL != gsTxRxBuffer.cmdData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.cmdData.p_data);
+ gsTxRxBuffer.cmdData.p_data = NULL;
+ }
+ if (NULL != gsTxRxBuffer.rspData.p_data) {
+ phNxpEse_free(gsTxRxBuffer.rspData.p_data);
+ gsTxRxBuffer.rspData.p_data = NULL;
+ }
+
+ return Void();
+}
+
+Return<void> VirtualISO::openLogicalChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) {
+ hidl_vec<uint8_t> manageChannelCommand = {0x00, 0x70, 0x00, 0x00, 0x01};
+
+ LogicalChannelResponse resApduBuff;
+
+ LOG(INFO) << "Acquired the lock in VISO openLogicalChannel";
+
+ resApduBuff.channelNumber = 0xff;
+ memset(&resApduBuff, 0x00, sizeof(resApduBuff));
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ if (mOpenedChannels.size() == 0x00) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ }
+
+ SecureElementStatus sestatus = SecureElementStatus::IOERROR;
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEse_data cmdApdu;
+ phNxpEse_data rspApdu;
+
+ phNxpEse_memset(&cmdApdu, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&rspApdu, 0x00, sizeof(phNxpEse_data));
+
+ cmdApdu.len = manageChannelCommand.size();
+ cmdApdu.p_data = (uint8_t*)phNxpEse_memalloc(manageChannelCommand.size() *
+ sizeof(uint8_t));
+ memcpy(cmdApdu.p_data, manageChannelCommand.data(), cmdApdu.len);
+
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_Transceive(&cmdApdu, &rspApdu);
+ if (status != ESESTATUS_SUCCESS) {
+ resApduBuff.channelNumber = 0xff;
+ if (NULL != rspApdu.p_data && rspApdu.len > 0) {
+ if ((rspApdu.p_data[0] == 0x64 && rspApdu.p_data[1] == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ }
+ }
+ if (SecureElementStatus::IOERROR != sestatus) {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x6A &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x81) {
+ resApduBuff.channelNumber = 0xff;
+ sestatus = SecureElementStatus::CHANNEL_NOT_AVAILABLE;
+ } else if (rspApdu.p_data[rspApdu.len - 2] == 0x90 &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ resApduBuff.channelNumber = rspApdu.p_data[0];
+ mOpenedchannelCount++;
+ mOpenedChannels[resApduBuff.channelNumber] = true;
+ sestatus = SecureElementStatus::SUCCESS;
+ } else if (((rspApdu.p_data[rspApdu.len - 2] == 0x6E) ||
+ (rspApdu.p_data[rspApdu.len - 2] == 0x6D)) &&
+ rspApdu.p_data[rspApdu.len - 1] == 0x00) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ }
+
+ /*Free the allocations*/
+ phNxpEse_free(cmdApdu.p_data);
+ phNxpEse_free(rspApdu.p_data);
+
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ LOG(INFO) << "seDeInit Failed";
+ }
+ }
+ /*If manageChanle is failed in any of above cases
+ send the callback and return*/
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ return Void();
+ }
+ LOG(INFO) << "openLogicalChannel Sending selectApdu";
+ sestatus = SecureElementStatus::IOERROR;
+ status = ESESTATUS_FAILED;
+
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ if ((resApduBuff.channelNumber > 0x03) &&
+ (resApduBuff.channelNumber < 0x14)) {
+ /* update CLA byte accoridng to GP spec Table 11-12*/
+ cpdu.cla =
+ 0x40 + (resApduBuff.channelNumber - 4); /* Class of instruction */
+ } else if ((resApduBuff.channelNumber > 0x00) &&
+ (resApduBuff.channelNumber < 0x04)) {
+ /* update CLA byte accoridng to GP spec Table 11-11*/
+ cpdu.cla = resApduBuff.channelNumber; /* Class of instruction */
+ } else {
+ LOG(ERROR) << StringPrintf("%s: Invalid Channel no: %02x", __func__,
+ resApduBuff.channelNumber);
+ resApduBuff.channelNumber = 0xff;
+ _hidl_cb(resApduBuff, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+ if (status != ESESTATUS_SUCCESS) {
+ /*Transceive failed*/
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ resApduBuff.selectResponse.resize(responseLen);
+ memcpy(&resApduBuff.selectResponse[0], rpdu.pdata, rpdu.len);
+ resApduBuff.selectResponse[responseLen - 1] = rpdu.sw2;
+ resApduBuff.selectResponse[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if (rpdu.sw1 == 0x90 && rpdu.sw2 == 0x00) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(resApduBuff.channelNumber);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ } else {
+ resApduBuff.channelNumber = 0xff;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ _hidl_cb(resApduBuff, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+
+ return Void();
+}
+
+Return<void> VirtualISO::openBasicChannel(const hidl_vec<uint8_t>& aid,
+ uint8_t p2,
+ openBasicChannel_cb _hidl_cb) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+ hidl_vec<uint8_t> result;
+
+ LOG(INFO) << "Acquired the lock in VISO openBasicChannel";
+
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ _hidl_cb(result, SecureElementStatus::IOERROR);
+ return Void();
+ }
+ }
+
+ if (mOpenedChannels.size() == 0x00) {
+ mMaxChannelCount = (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ }
+
+ phNxpEse_memset(&cpdu, 0x00, sizeof(phNxpEse_7816_cpdu_t));
+ phNxpEse_memset(&rpdu, 0x00, sizeof(phNxpEse_7816_rpdu_t));
+
+ cpdu.cla = 0x00; /* Class of instruction */
+ cpdu.ins = 0xA4; /* Instruction code */
+ cpdu.p1 = 0x04; /* Instruction parameter 1 */
+ cpdu.p2 = p2; /* Instruction parameter 2 */
+ cpdu.lc = aid.size();
+ cpdu.le_type = 0x01;
+ cpdu.pdata = (uint8_t*)phNxpEse_memalloc(aid.size() * sizeof(uint8_t));
+ memcpy(cpdu.pdata, aid.data(), cpdu.lc);
+ cpdu.le = 256;
+
+ rpdu.len = 0x02;
+ rpdu.pdata = (uint8_t*)phNxpEse_memalloc(cpdu.le * sizeof(uint8_t));
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ SecureElementStatus sestatus;
+ memset(&sestatus, 0x00, sizeof(sestatus));
+
+ if (status != ESESTATUS_SUCCESS) {
+ /* Transceive failed */
+ if (rpdu.len > 0 && (rpdu.sw1 == 0x64 && rpdu.sw2 == 0xFF)) {
+ sestatus = SecureElementStatus::IOERROR;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ } else {
+ /*Status word to be passed as part of response
+ So include additional length*/
+ uint16_t responseLen = rpdu.len + 2;
+ result.resize(responseLen);
+ memcpy(&result[0], rpdu.pdata, rpdu.len);
+ result[responseLen - 1] = rpdu.sw2;
+ result[responseLen - 2] = rpdu.sw1;
+
+ /*Status is success*/
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ /*Set basic channel reference if it is not set */
+ if (!mOpenedChannels[0]) {
+ mOpenedChannels[0] = true;
+ mOpenedchannelCount++;
+ }
+
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ /*AID provided doesn't match any applet on the secure element*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x82) {
+ sestatus = SecureElementStatus::NO_SUCH_ELEMENT_ERROR;
+ }
+ /*Operation provided by the P2 parameter is not permitted by the applet.*/
+ else if (rpdu.sw1 == 0x6A && rpdu.sw2 == 0x86) {
+ sestatus = SecureElementStatus::UNSUPPORTED_OPERATION;
+ } else {
+ sestatus = SecureElementStatus::FAILED;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (sestatus != SecureElementStatus::SUCCESS) {
+ SecureElementStatus closeChannelStatus =
+ internalCloseChannel(DEFAULT_BASIC_CHANNEL);
+ if (closeChannelStatus != SecureElementStatus::SUCCESS) {
+ LOG(ERROR) << "%s: closeChannel Failed" << __func__;
+ }
+ }
+ _hidl_cb(result, sestatus);
+ phNxpEse_free(cpdu.pdata);
+ phNxpEse_free(rpdu.pdata);
+ return Void();
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::internalCloseChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(ERROR) << "internalCloseChannel Enter";
+ LOG(INFO) << StringPrintf("mMaxChannelCount = %d, Closing Channel = %d",
+ mMaxChannelCount, channelNumber);
+ if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
+ 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status == ESESTATUS_SUCCESS) {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::closeChannel(uint8_t channelNumber) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ phNxpEse_7816_cpdu_t cpdu;
+ phNxpEse_7816_rpdu_t rpdu;
+
+ LOG(INFO) << "Acquired the lock in VISO closeChannel";
+ if ((int8_t)channelNumber < DEFAULT_BASIC_CHANNEL ||
+ 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 */
+ cpdu.ins = 0x70; /* Instruction code */
+ cpdu.p1 = 0x80; /* Instruction parameter 1 */
+ cpdu.p2 = channelNumber; /* Instruction parameter 2 */
+ cpdu.lc = 0x00;
+ cpdu.le = 0x9000;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ status = phNxpEse_7816_Transceive(&cpdu, &rpdu);
+
+ if (status == ESESTATUS_SUCCESS) {
+ if ((rpdu.sw1 == 0x90) && (rpdu.sw2 == 0x00)) {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ }
+ if (mOpenedChannels[channelNumber]) {
+ mOpenedChannels[channelNumber] = false;
+ mOpenedchannelCount--;
+ }
+ }
+
+ /*If there are no channels remaining close secureElement*/
+ if (mOpenedchannelCount == 0) {
+ sestatus = seHalDeInit();
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ }
+ return sestatus;
+}
+ESESTATUS VirtualISO::seHalInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ status = phNxpEse_open(initParams);
+ if (ESESTATUS_SUCCESS == status || ESESTATUS_BUSY == status) {
+ if (ESESTATUS_SUCCESS == phNxpEse_SetEndPoint_Cntxt(1) &&
+ ESESTATUS_SUCCESS == phNxpEse_init(initParams)) {
+ if (ESESTATUS_SUCCESS == phNxpEse_ResetEndPoint_Cntxt(1)) {
+ mIsEseInitialized = true;
+ LOG(INFO) << "VISO init complete!!!";
+ return ESESTATUS_SUCCESS;
+ }
+ deInitStatus = phNxpEse_deInit();
+ }
+ phNxpEse_close(deInitStatus);
+ mIsEseInitialized = false;
+ }
+ return status;
+}
+
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::seHalDeInit() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ bool mIsDeInitDone = true;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ deInitStatus = phNxpEse_deInit();
+ if (ESESTATUS_SUCCESS != deInitStatus) mIsDeInitDone = false;
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "phNxpEse_SetEndPoint_Cntxt failed!!!";
+ mIsDeInitDone = false;
+ }
+ status = phNxpEse_close(deInitStatus);
+ if (status == ESESTATUS_SUCCESS && mIsDeInitDone) {
+ sestatus = SecureElementStatus::SUCCESS;
+ ;
+ } else {
+ LOG(ERROR) << "seHalDeInit: Failed";
+ }
+ // Clear all the flags as SPI driver is closed.
+ mIsEseInitialized = false;
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+ return sestatus;
+}
+Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+VirtualISO::reset() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ SecureElementStatus sestatus = SecureElementStatus::FAILED;
+ LOG(ERROR) << "%s: Enter" << __func__;
+ if (!mIsEseInitialized) {
+ ESESTATUS status = seHalInit();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: seHalInit Failed!!!" << __func__;
+ }
+ }
+ if (status == ESESTATUS_SUCCESS) {
+ mCallbackV1_1->onStateChange_1_1(false, "reset the SE");
+ status = phNxpEse_reset();
+ if (status != ESESTATUS_SUCCESS) {
+ LOG(ERROR) << "%s: SecureElement reset failed!!" << __func__;
+ } else {
+ sestatus = SecureElementStatus::SUCCESS;
+ if (mOpenedChannels.size() == 0x00) {
+ mMaxChannelCount =
+ (GET_CHIP_OS_VERSION() >= OS_VERSION_6_2) ? 0x0C : 0x04;
+ mOpenedChannels.resize(mMaxChannelCount, false);
+ }
+ for (uint8_t xx = 0; xx < mMaxChannelCount; xx++) {
+ mOpenedChannels[xx] = false;
+ }
+ mOpenedchannelCount = 0;
+ mCallbackV1_1->onStateChange_1_1(true, "SE initialized");
+ }
+ }
+ LOG(ERROR) << "%s: Exit" << __func__;
+ return sestatus;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace virtual_iso
+} // namespace nxp
+} // namespace vendor
diff --git a/snxxx/1.2/VirtualISO.h b/snxxx/1.2/VirtualISO.h
new file mode 100755
index 0000000..b664fa0
--- /dev/null
+++ b/snxxx/1.2/VirtualISO.h
@@ -0,0 +1,103 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
+#define VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
+
+#include <android-base/stringprintf.h>
+#include <android/hardware/secure_element/1.0/types.h>
+#include <android/hardware/secure_element/1.2/ISecureElement.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include "phNxpEse_Api.h"
+
+namespace vendor {
+namespace nxp {
+namespace virtual_iso {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::wp;
+using android::base::StringPrintf;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_death_recipient;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::secure_element::V1_0::LogicalChannelResponse;
+using ::android::hardware::secure_element::V1_0::SecureElementStatus;
+using ::android::hardware::secure_element::V1_2::ISecureElement;
+using ::android::hidl::base::V1_0::IBase;
+
+#ifndef DEFAULT_BASIC_CHANNEL
+#define DEFAULT_BASIC_CHANNEL 0x00
+#endif
+
+struct VirtualISO : public ISecureElement, public hidl_death_recipient {
+ VirtualISO();
+ Return<void> init(
+ const sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> init_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) override;
+ Return<void> getAtr(getAtr_cb _hidl_cb) override;
+ Return<bool> isCardPresent() override;
+ Return<void> transmit(const hidl_vec<uint8_t>& data,
+ transmit_cb _hidl_cb) override;
+ Return<void> openLogicalChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openLogicalChannel_cb _hidl_cb) override;
+ Return<void> openBasicChannel(const hidl_vec<uint8_t>& aid, uint8_t p2,
+ openBasicChannel_cb _hidl_cb) override;
+ Return<SecureElementStatus> closeChannel(uint8_t channelNumber) override;
+ Return<::android::hardware::secure_element::V1_0::SecureElementStatus>
+ reset();
+ virtual void serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/) {
+ // TODO: Implement graceful closure, to close ongoing tx-rx and deinit
+ // T=1 stack
+ // close(0);
+ }
+
+ private:
+ uint8_t mMaxChannelCount;
+ uint8_t mOpenedchannelCount = 0;
+ bool mIsEseInitialized = false;
+ static std::vector<bool> mOpenedChannels;
+ static sp<
+ ::android::hardware::secure_element::V1_0::ISecureElementHalCallback>
+ mCallbackV1_0;
+ static sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
+ mCallbackV1_1;
+ Return<SecureElementStatus> seHalDeInit();
+ ESESTATUS seHalInit();
+ Return<SecureElementStatus> internalCloseChannel(uint8_t channelNumber);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace virtual_iso
+} // namespace nxp
+} // namespace vendor
+
+#endif // VENDOR_NXP_VIRTUAL_ISO_V1_0_SECUREELEMENT_H
diff --git a/snxxx/1.2/android.hardware.secure_element_snxxx@1.2-service.rc b/snxxx/1.2/android.hardware.secure_element_snxxx@1.2-service.rc
new file mode 100755
index 0000000..3625cce
--- /dev/null
+++ b/snxxx/1.2/android.hardware.secure_element_snxxx@1.2-service.rc
@@ -0,0 +1,4 @@
+service vendor.secure_element_hal_service /vendor/bin/hw/android.hardware.secure_element_snxxx@1.2-service
+ class hal
+ user secure_element
+ group secure_element
diff --git a/snxxx/Android.bp b/snxxx/Android.bp
new file mode 100755
index 0000000..c7cd477
--- /dev/null
+++ b/snxxx/Android.bp
@@ -0,0 +1,64 @@
+
+cc_binary {
+ relative_install_path: "hw",
+ name: "android.hardware.secure_element_snxxx@1.2-service",
+ init_rc: ["1.2/android.hardware.secure_element_snxxx@1.2-service.rc"],
+ proprietary: true,
+ defaults: ["hidl_defaults"],
+ srcs: [
+ "1.2/NxpEseService.cpp",
+ "1.2/SecureElement.cpp",
+ "1.2/VirtualISO.cpp",
+ "extns/impl/NxpEse.cpp",
+ "1.2/OsuHal/src/OsuHalExtn.cpp",
+ ],
+
+ shared_libs: [
+ "android.hardware.secure_element@1.0",
+ "android.hardware.secure_element@1.1",
+ "android.hardware.secure_element@1.2",
+ "ese_spi_nxp_snxxx",
+ "libbase",
+ "libcutils",
+ "libdl",
+ "libhardware",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ "libchrome",
+ "vendor.nxp.nxpese@1.0",
+ "vendor.nxp.nxpnfc@2.0",
+ "android.hardware.nfc@1.0",
+ "android.hardware.nfc@1.1",
+ ],
+
+ local_include_dirs: [
+ "libese-spi/common/include",
+ "libese-spi/p73/common",
+ "libese-spi/p73/inc",
+ "libese-spi/p73/lib",
+ "libese-spi/p73/pal",
+ "libese-spi/p73/pal/spi",
+ "libese-spi/p73/utils",
+ "libese-spi/p73/spm",
+ "libese-spi/src/include",
+ "1.2/OsuHal/inc",
+ "extns/impl",
+ ],
+
+ cflags: [
+ "-DANDROID",
+ "-DJCOP_VER_3_1=1",
+ "-DJCOP_VER_3_2=2",
+ "-DJCOP_VER_3_3=3",
+ "-DJCOP_VER_4_0=4",
+ "-DJCOP_VER_5_x=5",
+ "-DBUILDCFG=1",
+ "-DNXP_EXTNS=TRUE",
+ "-DNFC_NXP_ESE_VER=JCOP_VER_5_x",
+ "-Wall",
+ "-Werror",
+ "-fexceptions",
+ ],
+
+}
diff --git a/snxxx/ese-clients/inc/eSEClient.h b/snxxx/ese-clients/inc/eSEClient.h
new file mode 100644
index 0000000..425cada
--- /dev/null
+++ b/snxxx/ese-clients/inc/eSEClient.h
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h>
+#include "../../../secure_element_extns/inc/eSEClientIntf.h"
+#include "phNxpEse_Api.h"
+
+#ifndef ESE_UPDATE_2_H_
+#define ESE_UPDATE_2_H_
+
+extern ese_update_state_t ese_update;
+using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback;
+
+void checkEseClientUpdate();
+
+SESTATUS perform_eSEClientUpdate();
+
+void eSEClientUpdate_SE_Thread();
+
+void seteSEClientState(uint8_t state);
+typedef enum {
+ ESE = 0,
+ EUICC = 1,
+} SEDomainID;
+
+#endif /* ESE_UPDATE_2_H_ */
diff --git a/snxxx/ese-clients/src/eSEClient.cpp b/snxxx/ese-clients/src/eSEClient.cpp
new file mode 100644
index 0000000..f87e80c
--- /dev/null
+++ b/snxxx/ese-clients/src/eSEClient.cpp
@@ -0,0 +1,484 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include "eSEClient.h"
+#include <IChannel.h>
+#include <JcDnld.h>
+#include <LsClient.h>
+#include <dirent.h>
+#include <ese_config.h>
+#include <log/log.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#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"
+#include "phNxpEse_Apdu_Api.h"
+#include "phNxpEse_Spm.h"
+
+using android::sp;
+using android::hardware::hidl_vec;
+using android::hardware::Void;
+using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
+using vendor::nxp::nxpnfc::V2_0::INxpNfc;
+sp<INxpNfc> mHalNxpNfc = nullptr;
+
+void seteSEClientState(uint8_t state);
+
+IChannel_t Ch;
+se_extns_entry se_intf;
+void* eSEClientUpdate_ThreadHandler(void* data);
+void* eSEClientUpdate_Thread(void* data);
+void* eSEUpdate_SE_SeqHandler(void* data);
+void eSEClientUpdate_Thread();
+SESTATUS ESE_ChannelInit(IChannel* ch);
+SESTATUS handleJcopOsDownload();
+void* LSUpdate_Thread(void* data);
+uint8_t performLSUpdate();
+SESTATUS initializeEse(phNxpEse_initMode mode, SEDomainID Id);
+ese_update_state_t ese_update = ESE_UPDATE_COMPLETED;
+SESTATUS eSEUpdate_SeqHandler();
+int16_t SE_Open() { return SESTATUS_SUCCESS; }
+
+void SE_Reset() { phNxpEse_coldReset(); }
+
+bool SE_Transmit(uint8_t* xmitBuffer, int32_t xmitBufferSize,
+ uint8_t* recvBuffer, int32_t recvBufferMaxSize,
+ int32_t& recvBufferActualSize, int32_t timeoutMillisec) {
+ phNxpEse_data cmdData;
+ phNxpEse_data rspData;
+
+ cmdData.len = xmitBufferSize;
+ cmdData.p_data = xmitBuffer;
+
+ recvBufferMaxSize++;
+ timeoutMillisec++;
+ if (phNxpEse_Transceive(&cmdData, &rspData) != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Ese Transceive failed", __FUNCTION__);
+ }
+ recvBufferActualSize = rspData.len;
+
+ if (rspData.p_data != NULL && rspData.len) {
+ memcpy(&recvBuffer[0], rspData.p_data, rspData.len);
+ }
+
+ ALOGE("%s: size = 0x%x ", __FUNCTION__, recvBufferActualSize);
+ return true;
+}
+
+void SE_JcopDownLoadReset() { phNxpEse_resetJcopUpdate(); }
+
+bool SE_Close(int16_t mHandle) {
+ if (mHandle != 0)
+ return true;
+ else
+ return false;
+}
+uint8_t SE_getInterfaceInfo() { return INTF_SE; }
+
+/***************************************************************************
+**
+** Function: checkEseClientUpdate
+**
+** Description: Check the initial condition
+ and interafce for eSE Client update for LS and JCOP download
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void checkEseClientUpdate() {
+ ALOGD("%s enter: ", __func__);
+ checkeSEClientRequired(ESE_INTF_SPI);
+ se_intf.isJcopUpdateRequired = getJcopUpdateRequired();
+ se_intf.isLSUpdateRequired = getLsUpdateRequired();
+ se_intf.sJcopUpdateIntferface = getJcopUpdateIntf();
+ se_intf.sLsUpdateIntferface = getLsUpdateIntf();
+ if ((se_intf.isJcopUpdateRequired && se_intf.sJcopUpdateIntferface) ||
+ (se_intf.isLSUpdateRequired && se_intf.sLsUpdateIntferface))
+ seteSEClientState(ESE_UPDATE_STARTED);
+}
+
+/***************************************************************************
+**
+** Function: perform_eSEClientUpdate
+**
+** Description: Perform LS and JCOP download during hal service init
+**
+** Returns: SUCCESS / SESTATUS_FAILED
+**
+*******************************************************************************/
+SESTATUS perform_eSEClientUpdate() {
+ ALOGD("%s enter: ", __func__);
+
+ eSEClientUpdate_Thread();
+ return SESTATUS_SUCCESS;
+}
+
+SESTATUS ESE_ChannelInit(IChannel* ch) {
+ ch->open = SE_Open;
+ ch->close = SE_Close;
+ ch->transceive = SE_Transmit;
+ ch->transceiveRaw = SE_Transmit;
+ ch->doeSE_Reset = SE_Reset;
+ ch->doeSE_JcopDownLoadReset = SE_JcopDownLoadReset;
+ ch->getInterfaceInfo = SE_getInterfaceInfo;
+ return SESTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function: eSEClientUpdate_Thread
+**
+** Description: Perform eSE update
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void eSEClientUpdate_Thread() {
+ SESTATUS status = SESTATUS_FAILED;
+ pthread_t thread;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if (pthread_create(&thread, &attr, &eSEClientUpdate_ThreadHandler, NULL) !=
+ 0) {
+ ALOGD("Thread creation failed");
+ status = SESTATUS_FAILED;
+ } else {
+ status = SESTATUS_SUCCESS;
+ ALOGD("Thread creation success");
+ }
+ pthread_attr_destroy(&attr);
+}
+/*******************************************************************************
+**
+** Function: eSEClientUpdate_Thread
+**
+** Description: Perform eSE update
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void eSEClientUpdate_SE_Thread() {
+ SESTATUS status = SESTATUS_FAILED;
+ pthread_t thread;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if (pthread_create(&thread, &attr, &eSEUpdate_SE_SeqHandler, NULL) != 0) {
+ ALOGD("Thread creation failed");
+ status = SESTATUS_FAILED;
+ } else {
+ status = SESTATUS_SUCCESS;
+ ALOGD("Thread creation success");
+ }
+ pthread_attr_destroy(&attr);
+}
+/*******************************************************************************
+**
+** Function: eSEClientUpdate_ThreadHandler
+**
+** Description: Perform JCOP Download
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void* eSEUpdate_SE_SeqHandler(void* data) {
+ (void)data;
+ ALOGD("%s Enter\n", __func__);
+ eSEUpdate_SeqHandler();
+ ALOGD("%s Exit eSEUpdate_SE_SeqHandler\n", __func__);
+ return NULL;
+}
+/*******************************************************************************
+**
+** Function: eSEClientUpdate_ThreadHandler
+**
+** Description: Perform JCOP Download
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void* eSEClientUpdate_ThreadHandler(void* data) {
+ (void)data;
+ int cnt = 0;
+
+ ALOGD("%s Enter\n", __func__);
+ while (((mHalNxpNfc == nullptr) && (cnt < 3))) {
+ mHalNxpNfc = INxpNfc::tryGetService();
+ if (mHalNxpNfc == nullptr) ALOGD(": Failed to retrieve the NXP NFC HAL!");
+ if (mHalNxpNfc != nullptr) {
+ ALOGD("INxpNfc::getService() returned %p (%s)", mHalNxpNfc.get(),
+ (mHalNxpNfc->isRemote() ? "remote" : "local"));
+ }
+ usleep(100 * 1000);
+ cnt++;
+ }
+
+ if (mHalNxpNfc != nullptr) {
+ if (!se_intf.isJcopUpdateRequired && mHalNxpNfc->isJcopUpdateRequired()) {
+ se_intf.isJcopUpdateRequired = true;
+ ALOGD(" se_intf.isJcopUpdateRequired = %d", se_intf.isJcopUpdateRequired);
+ }
+ if (!se_intf.isLSUpdateRequired && mHalNxpNfc->isLsUpdateRequired()) {
+ se_intf.isLSUpdateRequired = true;
+ ALOGD("se_intf.isLSUpdateRequired = %d", se_intf.isLSUpdateRequired);
+ }
+ }
+
+ if (se_intf.isJcopUpdateRequired) {
+ if (se_intf.sJcopUpdateIntferface == ESE_INTF_NFC) {
+ seteSEClientState(ESE_JCOP_UPDATE_REQUIRED);
+ return NULL;
+ } else if (se_intf.sJcopUpdateIntferface == ESE_INTF_SPI) {
+ seteSEClientState(ESE_JCOP_UPDATE_REQUIRED);
+ }
+ }
+
+ if ((ESE_JCOP_UPDATE_REQUIRED != ese_update) &&
+ (se_intf.isLSUpdateRequired)) {
+ if (se_intf.sLsUpdateIntferface == ESE_INTF_NFC) {
+ seteSEClientState(ESE_LS_UPDATE_REQUIRED);
+ return NULL;
+ } else if (se_intf.sLsUpdateIntferface == ESE_INTF_SPI) {
+ seteSEClientState(ESE_LS_UPDATE_REQUIRED);
+ }
+ }
+
+ if ((ese_update == ESE_JCOP_UPDATE_REQUIRED) ||
+ (ese_update == ESE_LS_UPDATE_REQUIRED))
+ eSEUpdate_SeqHandler();
+
+ ALOGD("%s Exit eSEClientUpdate_Thread\n", __func__);
+ return NULL;
+}
+
+/*******************************************************************************
+**
+** Function: handleJcopOsDownload
+**
+** Description: Perform JCOP update
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+SESTATUS handleJcopOsDownload() {
+ SESTATUS status = SESTATUS_FAILED;
+ uint8_t retstat;
+ status = initializeEse(ESE_MODE_OSU, ESE);
+ if (status == SESTATUS_SUCCESS) {
+ retstat = JCDNLD_Init(&Ch);
+ if (retstat != STATUS_SUCCESS) {
+ ALOGE("%s: JCDND initialization failed", __FUNCTION__);
+ if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
+ }
+ phNxpEse_close(ESESTATUS_SUCCESS);
+ return status;
+ } else {
+ retstat = JCDNLD_StartDownload();
+ if (retstat != SESTATUS_SUCCESS) {
+ ALOGE("%s: JCDNLD_StartDownload failed", __FUNCTION__);
+ }
+ }
+ JCDNLD_DeInit();
+ if (phNxpEse_ResetEndPoint_Cntxt(0) != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
+ }
+ phNxpEse_close(ESESTATUS_SUCCESS);
+ }
+ status = SESTATUS_SUCCESS;
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function: performLSUpdate
+**
+** Description: Perform LS update
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+uint8_t performLSUpdate() {
+ const char* SEterminal = "eSEx";
+ bool ret = false;
+ char terminalID[5];
+ uint8_t status = SESTATUS_FAILED;
+ bool isSEPresent = false;
+ bool isVISOPresent = false;
+ ret = geteSETerminalId(terminalID);
+ ALOGI("performLSUpdate Terminal val = %s", terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ isSEPresent = true;
+ }
+ ret = geteUICCTerminalId(terminalID);
+ if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
+ isVISOPresent = true;
+ }
+ seteSEClientState(ESE_UPDATE_STARTED);
+ if (isSEPresent) {
+ ALOGE("%s:On eSE domain ", __FUNCTION__);
+ status = initializeEse(ESE_MODE_NORMAL, ESE);
+ ALOGE("%s:On eSE domain ", __FUNCTION__);
+ if (status == SESTATUS_SUCCESS) {
+ status = performLSDownload(&Ch);
+ if (phNxpEse_ResetEndPoint_Cntxt(ESE) != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
+ }
+ }
+ phNxpEse_close(ESESTATUS_SUCCESS);
+ }
+ if (isVISOPresent) {
+ ALOGE("%s:On eUICC domain ", __FUNCTION__);
+ status = initializeEse(ESE_MODE_NORMAL, EUICC);
+ if (status == SESTATUS_SUCCESS) {
+ status = performLSDownload(&Ch);
+ if (phNxpEse_ResetEndPoint_Cntxt(EUICC) != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
+ }
+ }
+ phNxpEse_close(ESESTATUS_SUCCESS);
+ }
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function: initializeEse
+**
+** Description: Open & Initialize libese
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+SESTATUS initializeEse(phNxpEse_initMode mode, SEDomainID Id) {
+ uint8_t retstat;
+ SESTATUS status = SESTATUS_FAILED;
+ phNxpEse_initParams initParams;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+
+ initParams.initMode = mode;
+ ALOGE("%s: Mode = %d", __FUNCTION__, mode);
+ retstat = phNxpEse_open(initParams);
+ if (retstat != ESESTATUS_SUCCESS) {
+ return status;
+ }
+ retstat = phNxpEse_SetEndPoint_Cntxt(Id);
+ if (retstat != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Set SE EndPoint failed", __FUNCTION__);
+ }
+ retstat = phNxpEse_init(initParams);
+ if (retstat != ESESTATUS_SUCCESS) {
+ if (phNxpEse_ResetEndPoint_Cntxt(Id) != ESESTATUS_SUCCESS) {
+ ALOGE("%s: Reset SE EndPoint failed", __FUNCTION__);
+ }
+ phNxpEse_close(ESESTATUS_SUCCESS);
+ return status;
+ }
+ ESE_ChannelInit(&Ch);
+ status = SESTATUS_SUCCESS;
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function: seteSEClientState
+**
+** Description: Function to set the eSEUpdate state
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void seteSEClientState(uint8_t state) {
+ ALOGE("%s: State = %d", __FUNCTION__, state);
+ ese_update = (ese_update_state_t)state;
+}
+
+/*******************************************************************************
+**
+** Function: sendeSEUpdateState
+**
+** Description: Notify NFC HAL LS / JCOP download state
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+void sendeSEUpdateState(uint8_t state) {
+ ALOGE("%s: State = %d", __FUNCTION__, state);
+ phNxpEse_SPM_SetEseClientUpdateState(state);
+}
+
+/*******************************************************************************
+**
+** Function: eSEUpdate_SeqHandler
+**
+** Description: ESE client update handler
+**
+** Returns: SUCCESS of ok
+**
+*******************************************************************************/
+SESTATUS eSEUpdate_SeqHandler() {
+ switch (ese_update) {
+ case ESE_UPDATE_STARTED:
+ break;
+ case ESE_JCOP_UPDATE_REQUIRED:
+ ALOGE("%s: ESE_JCOP_UPDATE_REQUIRED", __FUNCTION__);
+ if (se_intf.isJcopUpdateRequired) {
+ if (se_intf.sJcopUpdateIntferface == ESE_INTF_SPI) {
+ handleJcopOsDownload();
+ sendeSEUpdateState(ESE_JCOP_UPDATE_COMPLETED);
+ setJcopUpdateRequired(false);
+ } else if (se_intf.sJcopUpdateIntferface == ESE_INTF_NFC) {
+ return SESTATUS_SUCCESS;
+ }
+ }
+ [[fallthrough]];
+ case ESE_JCOP_UPDATE_COMPLETED:
+ ALOGE("%s: ESE_JCOP_UPDATE_COMPLETED", __FUNCTION__);
+ [[fallthrough]];
+ case ESE_LS_UPDATE_REQUIRED:
+ if (se_intf.isLSUpdateRequired) {
+ if (se_intf.sLsUpdateIntferface == ESE_INTF_SPI) {
+ performLSUpdate();
+ sendeSEUpdateState(ESE_LS_UPDATE_COMPLETED);
+ setLsUpdateRequired(false);
+ } else if (se_intf.sLsUpdateIntferface == ESE_INTF_NFC) {
+ seteSEClientState(ESE_LS_UPDATE_REQUIRED);
+ return SESTATUS_SUCCESS;
+ }
+ }
+ ALOGE("%s: ESE_LS_UPDATE_REQUIRED", __FUNCTION__);
+ [[fallthrough]];
+ case ESE_LS_UPDATE_COMPLETED:
+ ALOGE("%s: ESE_LS_UPDATE_COMPLETED", __FUNCTION__);
+ [[fallthrough]];
+ case ESE_UPDATE_COMPLETED:
+ seteSEClientState(ESE_UPDATE_COMPLETED);
+ sendeSEUpdateState(ESE_UPDATE_COMPLETED);
+ NxpEse::initSEService();
+ NxpEse::initVIrtualISOService();
+ ALOGE("%s: ESE_UPDATE_COMPLETED", __FUNCTION__);
+ break;
+ }
+ return SESTATUS_SUCCESS;
+}
diff --git a/snxxx/extns/impl/NxpEse.cpp b/snxxx/extns/impl/NxpEse.cpp
new file mode 100755
index 0000000..c72d162
--- /dev/null
+++ b/snxxx/extns/impl/NxpEse.cpp
@@ -0,0 +1,224 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2018-2021 NXP Semiconductors
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#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
+
+namespace vendor {
+namespace nxp {
+namespace nxpese {
+namespace V1_0 {
+namespace implementation {
+using android::base::StringPrintf;
+// using android::hardware::secure_element::V1_0::implementation::SecureElement;
+static android::sp<ISecureElementHalCallback> seCallback;
+static android::sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
+ seCallback_1_1;
+static android::sp<ISecureElementHalCallback> virtualISOCallback;
+static android::sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>
+ virtualISOCallback_1_1;
+bool isSeHalV1_1 = false;
+// Methods from ::vendor::nxp::nxpese::V1_0::INxpEse follow.
+Return<void> NxpEse::setSeCallBack(
+ const android::sp<ISecureElementHalCallback>& clientCallback) {
+ seCallback = clientCallback;
+ return Void();
+}
+
+Return<void> NxpEse::setSeCallBack_1_1(
+ const sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) {
+ seCallback_1_1 = clientCallback;
+ isSeHalV1_1 = true;
+ return Void();
+}
+
+Return<void> NxpEse::setVirtualISOCallBack(
+ const android::sp<ISecureElementHalCallback>& clientCallback) {
+ virtualISOCallback = clientCallback;
+ return Void();
+}
+
+Return<void> NxpEse::setVirtualISOCallBack_1_1(
+ const android::sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback) {
+ virtualISOCallback_1_1 = clientCallback;
+ isSeHalV1_1 = true;
+ return Void();
+}
+void NxpEse::initSEService() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (!seCallback && !isSeHalV1_1) return;
+
+ if (!seCallback_1_1 && isSeHalV1_1) return;
+
+ status = phNxpEse_open(initParams);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit;
+ }
+
+ status = phNxpEse_SetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit1;
+ }
+ status = phNxpEse_init(initParams);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit1;
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(0);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit2;
+ }
+
+ LOG(INFO) << "ESE SPI init complete !!!";
+exit2:
+ deInitStatus = phNxpEse_deInit();
+exit1:
+ status = phNxpEse_close(deInitStatus);
+exit:
+ if (status == ESESTATUS_SUCCESS) {
+ if (isSeHalV1_1)
+ seCallback_1_1->onStateChange_1_1(true, "NXP SE HAL init ok");
+ else
+ seCallback->onStateChange(true);
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ if (isSeHalV1_1)
+ seCallback_1_1->onStateChange_1_1(false, "NXP SE HAL init not ok");
+ else
+ seCallback->onStateChange(false);
+ }
+}
+
+void NxpEse::initVIrtualISOService() {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_initParams initParams;
+ ESESTATUS deInitStatus = ESESTATUS_SUCCESS;
+ memset(&initParams, 0x00, sizeof(phNxpEse_initParams));
+ initParams.initMode = ESE_MODE_NORMAL;
+ initParams.mediaType = ESE_PROTOCOL_MEDIA_SPI_APDU_GATE;
+
+ if (!virtualISOCallback && !isSeHalV1_1) return;
+
+ if (!virtualISOCallback_1_1 && isSeHalV1_1) return;
+
+ status = phNxpEse_SetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit1;
+ }
+ status = phNxpEse_init(initParams);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit1;
+ }
+ status = phNxpEse_ResetEndPoint_Cntxt(1);
+ if (status != ESESTATUS_SUCCESS) {
+ goto exit2;
+ }
+
+ LOG(INFO) << "ESE SPI init complete !!!";
+exit2:
+ deInitStatus = phNxpEse_deInit();
+exit1:
+ status = phNxpEse_close(deInitStatus);
+
+ if (status == ESESTATUS_SUCCESS) {
+ if (isSeHalV1_1)
+ virtualISOCallback_1_1->onStateChange_1_1(true, "NXP SE HAL init ok");
+ else
+ virtualISOCallback->onStateChange(true);
+ } else {
+ LOG(ERROR) << "eSE-Hal Init failed";
+ if (isSeHalV1_1)
+ virtualISOCallback_1_1->onStateChange_1_1(false,
+ "NXP SE HAL init not ok");
+ else
+ virtualISOCallback->onStateChange(false);
+ }
+}
+#ifdef NXP_BOOTTIME_UPDATE
+Return<void> NxpEse::ioctlHandler(uint64_t ioctlType,
+ ese_nxp_IoctlInOutData_t& inpOutData) {
+ switch (ioctlType) {
+ case HAL_ESE_IOCTL_NFC_JCOP_DWNLD: {
+ // nfc_nci_IoctlInOutData_t* inpOutData =
+ // (nfc_nci_IoctlInOutData_t*)inpOutData;
+ int update_state = inpOutData.inp.data.nxpCmd.p_cmd[0];
+ if (update_state == ESE_JCOP_UPDATE_COMPLETED ||
+ update_state == ESE_LS_UPDATE_COMPLETED) {
+ seteSEClientState(update_state);
+ eSEClientUpdate_SE_Thread();
+ }
+ } break;
+ }
+ return Void();
+}
+#endif
+
+Return<void> NxpEse::ioctl(uint64_t ioctlType,
+ const hidl_vec<uint8_t>& inOutData,
+ ioctl_cb _hidl_cb) {
+ ese_nxp_IoctlInOutData_t inpOutData;
+ ese_nxp_IoctlInOutData_t* pInOutData =
+ (ese_nxp_IoctlInOutData_t*)&inOutData[0];
+
+ /*data from proxy->stub is copied to local data which can be updated by
+ * underlying HAL implementation since it's an inout argument*/
+ memcpy(&inpOutData, pInOutData, sizeof(ese_nxp_IoctlInOutData_t));
+ ESESTATUS status = phNxpEse_spiIoctl(ioctlType, &inpOutData);
+#ifdef NXP_BOOTTIME_UPDATE
+ ioctlHandler(ioctlType, inpOutData);
+#endif
+ /*copy data and additional fields indicating status of ioctl operation
+ * and context of the caller. Then invoke the corresponding proxy callback*/
+ inpOutData.out.ioctlType = ioctlType;
+ inpOutData.out.result = status;
+#ifdef NXP_BOOTTIME_UPDATE
+ if (ioctlType == HAL_ESE_IOCTL_GET_ESE_UPDATE_STATE) {
+ inpOutData.out.data.status =
+ (getJcopUpdateRequired() | (getLsUpdateRequired() << 8));
+ }
+#endif
+ hidl_vec<uint8_t> outputData;
+ outputData.setToExternal((uint8_t*)&inpOutData.out,
+ sizeof(ese_nxp_ExtnOutputData_t));
+ LOG(ERROR) << "GET ESE update state2 = " << inpOutData.out.data.status;
+ _hidl_cb(outputData);
+ return Void();
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace nxpese
+} // namespace nxp
+} // namespace vendor
diff --git a/snxxx/extns/impl/NxpEse.h b/snxxx/extns/impl/NxpEse.h
new file mode 100755
index 0000000..8c4ec5f
--- /dev/null
+++ b/snxxx/extns/impl/NxpEse.h
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2018-2019 NXP Semiconductors
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef VENDOR_NXP_NXPNFC_V1_0_NXPNFC_H
+#define VENDOR_NXP_NXPNFC_V1_0_NXPNFC_H
+
+#include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h>
+#include <android/hardware/secure_element/1.1/ISecureElement.h>
+#include <android/hardware/secure_element/1.1/ISecureElementHalCallback.h>
+#include <hardware/hardware.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <vendor/nxp/nxpese/1.0/INxpEse.h>
+#include "hal_nxpese.h"
+namespace vendor {
+namespace nxp {
+namespace nxpese {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::secure_element::V1_0::ISecureElementHalCallback;
+using ::android::hidl::base::V1_0::DebugInfo;
+using ::android::hidl::base::V1_0::IBase;
+using ::vendor::nxp::nxpese::V1_0::INxpEse;
+struct NxpEse : public INxpEse {
+ Return<void> ioctl(uint64_t ioctlType, const hidl_vec<uint8_t>& inOutData,
+ ioctl_cb _hidl_cb) override;
+ static Return<void> setSeCallBack(
+ const android::sp<ISecureElementHalCallback>& clientCallback);
+ static Return<void> setSeCallBack_1_1(
+ const android::sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback);
+ static Return<void> setVirtualISOCallBack(
+ const android::sp<ISecureElementHalCallback>& clientCallback);
+ static Return<void> setVirtualISOCallBack_1_1(
+ const android::sp<
+ ::android::hardware::secure_element::V1_1::ISecureElementHalCallback>&
+ clientCallback);
+ static void initSEService();
+ static void initVIrtualISOService();
+
+ private:
+ Return<void> ioctlHandler(uint64_t ioctlType,
+ ese_nxp_IoctlInOutData_t& inpOutData);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace nxpese
+} // namespace nxp
+} // namespace vendor
+
+#endif // VENDOR_NXP_NXPNFC_V1_0_NXPNFC_H
diff --git a/snxxx/extns/impl/hal_nxpese.h b/snxxx/extns/impl/hal_nxpese.h
new file mode 100755
index 0000000..e0a183c
--- /dev/null
+++ b/snxxx/extns/impl/hal_nxpese.h
@@ -0,0 +1,169 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2018-2020 NXP Semiconductors
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef ANDROID_HARDWARE_HAL_NXPESE_V1_0_H
+#define ANDROID_HARDWARE_HAL_NXPESE_V1_0_H
+
+#define ESE_NXPNFC_HARDWARE_MODULE_ID "ese_nxp.pn54x"
+
+#define MAX_IOCTL_TRANSCEIVE_CMD_LEN 256
+#define MAX_IOCTL_TRANSCEIVE_RESP_LEN 256
+#define MAX_ATR_INFO_LEN 128
+#define HAL_NFC_IOCTL_FIRST_EVT 0xA0
+enum {
+ HAL_ESE_IOCTL_P61_IDLE_MODE = 0,
+ HAL_ESE_IOCTL_P61_WIRED_MODE,
+ HAL_ESE_IOCTL_P61_PWR_MODE,
+ HAL_ESE_IOCTL_P61_DISABLE_MODE,
+ HAL_ESE_IOCTL_P61_ENABLE_MODE,
+ HAL_ESE_IOCTL_SET_BOOT_MODE,
+ HAL_ESE_IOCTL_GET_CONFIG_INFO,
+ HAL_ESE_IOCTL_CHECK_FLASH_REQ,
+ HAL_ESE_IOCTL_FW_DWNLD,
+ HAL_ESE_IOCTL_FW_MW_VER_CHECK,
+ HAL_ESE_IOCTL_DISABLE_HAL_LOG,
+ HAL_ESE_IOCTL_NXP_TRANSCEIVE,
+ HAL_ESE_IOCTL_P61_GET_ACCESS,
+ HAL_ESE_IOCTL_P61_REL_ACCESS,
+ HAL_ESE_IOCTL_ESE_CHIP_RST,
+ HAL_ESE_IOCTL_REL_SVDD_WAIT,
+ HAL_ESE_IOCTL_SET_JCP_DWNLD_ENABLE,
+ HAL_ESE_IOCTL_SET_JCP_DWNLD_DISABLE,
+ HAL_ESE_IOCTL_SET_ESE_SERVICE_PID,
+ HAL_ESE_IOCTL_REL_DWP_WAIT,
+ HAL_ESE_IOCTL_GET_FEATURE_LIST,
+ HAL_ESE_IOCTL_RF_STATUS_UPDATE,
+ HAL_ESE_IOCTL_NFC_JCOP_DWNLD,
+#if (NXP_EXTNS == TRUE)
+ HAL_ESE_IOCTL_GET_ESE_UPDATE_STATE,
+#endif
+};
+
+/*
+ * Data structures provided below are used of Hal Ioctl calls
+ */
+/*
+ * ese_nxp_ExtnCmd_t shall contain data for commands used for transceive command
+ * in ioctl
+ */
+typedef struct {
+ uint16_t cmd_len;
+ uint8_t p_cmd[MAX_IOCTL_TRANSCEIVE_CMD_LEN];
+} ese_nxp_ExtnCmd_t;
+
+/*
+ * ese_nxp_ExtnRsp_t shall contain response for command sent in transceive
+ * command
+ */
+typedef struct {
+ uint16_t rsp_len;
+ uint8_t p_rsp[MAX_IOCTL_TRANSCEIVE_RESP_LEN];
+} ese_nxp_ExtnRsp_t;
+/*
+ * InputData_t :ioctl has multiple subcommands
+ * Each command has corresponding input data which needs to be populated in this
+ */
+typedef union {
+ uint16_t bootMode;
+ uint8_t halType;
+ ese_nxp_ExtnCmd_t nxpCmd;
+ uint32_t timeoutMilliSec;
+ long eseServicePid;
+} eseInputData_t;
+/*
+ * ese_nxp_ExtnInputData_t :Apart from InputData_t, there are context data
+ * which is required during callback from stub to proxy.
+ * To avoid additional copy of data while propagating from libese to Adaptation
+ * and Esestub to nxphal, common structure is used. As a sideeffect, context
+ * data is exposed to libese (Not encapsulated).
+ */
+typedef struct {
+ /*context to be used/updated only by users of proxy & stub of Ese.hal
+ * i.e., EseAdaptation & hardware/interface/Ese.
+ */
+ eseInputData_t data;
+ uint8_t data_source;
+ long level;
+} ese_nxp_ExtnInputData_t;
+
+/*
+ * outputData_t :ioctl has multiple commands/responses
+ * This contains the output types for each ioctl.
+ */
+typedef union {
+ uint32_t status;
+ ese_nxp_ExtnRsp_t nxpRsp;
+ uint8_t nxpNciAtrInfo[MAX_ATR_INFO_LEN];
+ uint32_t p61CurrentState;
+ uint16_t fwUpdateInf;
+ uint16_t fwDwnldStatus;
+ uint16_t fwMwVerStatus;
+ uint8_t chipType;
+} eseOutputData_t;
+
+typedef union {
+ uint8_t nfc_jcop_download_state;
+} eseIoctlData_t;
+extern eseIoctlData_t eseioctldata;
+
+/*
+ * ese_nxp_ExtnOutputData_t :Apart from outputData_t, there are other
+ * information which is required during callback from stub to proxy. For ex
+ * (context, result of the operation , type of ioctl which was completed). To
+ * avoid additional copy of data while propagating from libese to Adaptation and
+ * Esestub to nxphal, common structure is used. As a sideeffect, these data is
+ * exposed(Not encapsulated).
+ */
+typedef struct {
+ /*ioctlType, result & context to be used/updated only by users of
+ * proxy & stub of Ese.hal.
+ * i.e., EseAdaptation & hardware/interface/Ese
+ * These fields shall not be used by libese or halimplementation*/
+ uint64_t ioctlType;
+ uint32_t result;
+ eseOutputData_t data;
+} ese_nxp_ExtnOutputData_t;
+
+/*
+ * ese_nxp_IoctlInOutData_t :data structure for input & output
+ * to be sent for ioctl command. input is populated by client/proxy side
+ * output is provided from server/stub to client/proxy
+ */
+typedef struct {
+ ese_nxp_ExtnInputData_t inp;
+ ese_nxp_ExtnOutputData_t out;
+} ese_nxp_IoctlInOutData_t;
+
+/*
+ * nxpese_nxp_device_t :data structure for nxp's extended ese_nxp_device
+ * Extra features added are
+ * -ioctl(manage sync between and DWP & SPI)
+ * -check request for fw download
+ */
+typedef struct nxpese_nxp_device {
+ // ese_nxp_device_t nxp_device;
+ /*
+ * (*ioctl)() For P61 power management synchronization
+ * between ESE Wired and SPI.
+ */
+ int (*ioctl)(const struct nxpese_nxp_device* p_dev, long arg, void* p_data);
+ /*
+ * (*check_fw_dwnld_flag)() Is called to get FW downlaod request.
+ */
+} nxpese_nxp_device_t;
+
+#endif // ANDROID_HARDWARE_HAL_NXPESE_V1_0_H
diff --git a/snxxx/libese-spi/Android.bp b/snxxx/libese-spi/Android.bp
new file mode 100755
index 0000000..e7c00ba
--- /dev/null
+++ b/snxxx/libese-spi/Android.bp
@@ -0,0 +1,76 @@
+cc_library_shared {
+
+ name: "ese_spi_nxp_snxxx",
+ defaults: ["hidl_defaults"],
+ proprietary: true,
+
+ srcs: [
+ "p73/lib/phNxpEseDataMgr.cpp",
+ "p73/lib/phNxpEseProto7816_3.cpp",
+ "p73/lib/phNxpEse_Apdu_Api.cpp",
+ "p73/lib/phNxpEse_Api.cpp",
+ "p73/pal/phNxpEsePal.cpp",
+ "p73/pal/EseTransportFactory.cpp",
+ "p73/pal/spi/EseSpiTransport.cpp",
+ "p73/spm/phNxpEse_Spm.cpp",
+ "p73/utils/ese_config.cpp",
+ "p73/utils/config.cpp",
+ "p73/utils/ringbuffer.cpp",
+ "src/adaptation/NfcAdaptation.cpp",
+ "src/adaptation/CondVar.cpp",
+ "src/adaptation/Mutex.cpp",
+ ],
+
+ local_include_dirs: [
+ "common/include",
+ "p73/common",
+ "p73/inc",
+ "p73/lib",
+ "p73/pal",
+ "p73/pal/spi",
+ "p73/utils",
+ "src/include",
+ ],
+ include_dirs: [
+ "hardware/nxp/nfc/snxxx/extns/impl/nxpnfc/2.0",
+ "hardware/nxp/secure_element/snxxx/extns/impl",
+],
+
+ cflags: [
+ "-DANDROID",
+ "-DJCOP_VER_3_1=1",
+ "-DJCOP_VER_3_2=2",
+ "-DJCOP_VER_3_3=3",
+ "-DJCOP_VER_4_0=4",
+ "-DJCOP_VER_5_x=5",
+ "-DBUILDCFG=1",
+ "-DNXP_EXTNS=TRUE",
+ "-DNFC_NXP_ESE_VER=JCOP_VER_5_x",
+ "-Wall",
+ "-Werror",
+ ],
+
+ shared_libs: [
+ "android.hardware.nfc@1.0",
+ "android.hardware.nfc@1.1",
+ "android.hardware.secure_element@1.0",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ "libbase",
+ "libchrome",
+ "vendor.nxp.nxpese@1.0",
+ "vendor.nxp.nxpnfc@2.0",
+ ],
+
+ product_variables: {
+ debuggable: {
+ cflags: [
+ "-DDCHECK_ALWAYS_ON"
+ ],
+ },
+ },
+
+}
diff --git a/snxxx/libese-spi/common/include/phNxpEseFeatures.h b/snxxx/libese-spi/common/include/phNxpEseFeatures.h
new file mode 100644
index 0000000..f6fef6c
--- /dev/null
+++ b/snxxx/libese-spi/common/include/phNxpEseFeatures.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * NXP ESE features macros definitions
+ */
+
+#ifndef NXP_ESE_FEATURES_H
+#define NXP_ESE_FEATURES_H
+
+#define ESE_DEBUG_UTILS_INCLUDED true
+
+#define NXP_POWER_SCHEME_SUPPORT true
+#define NXP_ESE_END_OF_SESSION true
+
+#define NXP_ESE_WTX_RES_DELAY true
+#define NXP_ESE_P73_ISO_RST true
+
+typedef enum OS_VERSION {
+ OS_VERSION_DEFAULT = 0,
+ OS_VERSION_4_0 = 1,
+ OS_VERSION_5_1 = 2,
+ OS_VERSION_5_2 = 3,
+ OS_VERSION_5_2_2 = 4,
+ OS_VERSION_6_2 = 5,
+ INVALID_OS_VERSION = 0xFF,
+} phNxpEse_OsVersion_t;
+
+extern phNxpEse_OsVersion_t phNxpEse_getOsVersion();
+extern bool ese_debug_enabled;
+#define GET_CHIP_OS_VERSION() phNxpEse_getOsVersion()
+
+#endif /* end of #ifndef NXP_ESE_FEATURES_H */
diff --git a/snxxx/libese-spi/p73/common/phEseStatus.h b/snxxx/libese-spi/p73/common/phEseStatus.h
new file mode 100644
index 0000000..80db0b5
--- /dev/null
+++ b/snxxx/libese-spi/p73/common/phEseStatus.h
@@ -0,0 +1,222 @@
+/******************************************************************************
+ *
+ * Copyright 2018 - 2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+/**
+ * \addtogroup ISO7816-3_protocol_lib_common
+ *
+ * @{ */
+
+#ifndef PHESESTATUS_H
+#define PHESESTATUS_H
+
+/*! Internally required by PHESESTVAL. */
+#define PHESESTSHL8 (8U)
+
+/*! Required by PHESESTVAL. */
+#define PHESESTBLOWER ((ESESTATUS)(0x00FFU))
+
+/*!
+ * ESE Status Composition Macro
+ *
+ * This is the macro which must be used to compose status values.
+ *
+ * phEseCompID Component ID, as defined in phEseCompId.h .
+ * phEseStatus Status values, as defined in phEseStatus.h .
+ *
+ * The macro is not required for the ESESTATUS_SUCCESS value.
+ * This is the only return value to be used directly.
+ * For all other values it shall be used in assignment and conditional
+ *statements, e.g.:
+ * ESESTATUS status = PHESESTVAL(phEseCompID, phEseStatus); ...
+ * if (status == PHESESTVAL(phEseCompID, phEseStatus)) ...
+ */
+#define PHESESTVAL(phEseCompID, phEseStatus) \
+ (((phEseStatus) == (ESESTATUS_SUCCESS)) \
+ ? (ESESTATUS_SUCCESS) \
+ : ((((ESESTATUS)(phEseStatus)) & (PHESESTBLOWER)) | \
+ (((uint16_t)(phEseCompID)) << (PHESESTSHL8))))
+
+/*!
+ * PHESESTATUS
+ * Get grp_retval from Status Code
+ */
+#define PHESESTATUS(phEseStatus) ((phEseStatus)&0x00FFU)
+
+/**
+ * \ingroup ISO7816-3_protocol_lib_common
+ * \brief Ese Channel mode
+ *
+ */
+typedef enum {
+ ESESTATUS_SUCCESS = (0x0000),
+
+ ESESTATUS_FAILED = (0x0001),
+
+ ESESTATUS_IOCTL_FAILED = -1,
+
+ ESESTATUS_INVALID_BUFFER = (0x0002),
+
+ ESESTATUS_BUFFER_TOO_SMALL = (0x0003),
+
+ ESESTATUS_INVALID_CLA = (0x0004),
+
+ ESESTATUS_INVALID_CPDU_TYPE = (0x0005),
+
+ ESESTATUS_INVALID_LE_TYPE = (0x0007),
+
+ ESESTATUS_INVALID_DEVICE = (0x0006),
+
+ ESESTATUS_MORE_FRAME = (0x0008),
+
+ ESESTATUS_LAST_FRAME = (0x0009),
+
+ ESESTATUS_CRC_ERROR = (0x000A),
+
+ ESESTATUS_SOF_ERROR = (0x000B),
+
+ ESESTATUS_INSUFFICIENT_RESOURCES = (0x000C),
+
+ ESESTATUS_PENDING = (0x000D),
+
+ ESESTATUS_BOARD_COMMUNICATION_ERROR = (0x000F),
+
+ ESESTATUS_INVALID_STATE = (0x0011),
+
+ ESESTATUS_NOT_INITIALISED = (0x0031),
+
+ ESESTATUS_ALREADY_INITIALISED = (0x0032),
+
+ ESESTATUS_FEATURE_NOT_SUPPORTED = (0x0033),
+
+ ESESTATUS_PARITY_ERROR = (0x0034),
+
+ ESESTATUS_ALREADY_REGISTERED = (0x0035),
+
+ ESESTATUS_CHAINED_FRAME = (0x0036),
+
+ ESESTATUS_SINGLE_FRAME = (0x0037),
+
+ ESESTATUS_DESELECTED = (0x0038),
+
+ ESESTATUS_RELEASED = (0x0039),
+
+ ESESTATUS_NOT_ALLOWED = (0x003A),
+
+ ESESTATUS_OTHER_ERROR = (0x003C),
+
+ ESESTATUS_DRIVER_BUSY = (0x006D),
+
+ ESESTATUS_DWNLD_BUSY = (0x006E),
+
+ ESESTATUS_BUSY = (0x006F),
+
+ ESESTATUS_INVALID_REMOTE_DEVICE = (0x001D),
+
+ ESESTATUS_READ_FAILED = (0x0014),
+
+ ESESTATUS_WRITE_FAILED = (0x0015),
+
+ ESESTATUS_NO_NDEF_SUPPORT = (0x0016),
+
+ ESESTATUS_RESET_SEQ_COUNTER_FRAME_RESEND = (0x001A),
+
+ ESESTATUS_INVALID_RECEIVE_LENGTH = (0x001B),
+
+ ESESTATUS_INVALID_FORMAT = (0x001C),
+
+ ESESTATUS_INSUFFICIENT_STORAGE = (0x001F),
+
+ ESESTATUS_FRAME_RESEND = (0x0023),
+
+ ESESTATUS_WRITE_TIMEOUT = (0x0024),
+
+ ESESTATUS_RESPONSE_TIMEOUT = (0x0025),
+
+ ESESTATUS_FRAME_RESEND_R_FRAME = (0x0026),
+
+ ESESTATUS_SEND_NEXT_FRAME = (0x0027),
+
+ ESESTATUS_RECOVERY_STARTED = (0x0028),
+
+ ESESTATUS_SEND_R_FRAME = (0x0029),
+
+ ESESTATUS_FRAME_RESEND_RNAK = (0x0030),
+
+ ESESTATUS_FRAME_SEND_R_FRAME = (0x003B),
+
+ ESESTATUS_UNKNOWN_ERROR = (0x00FE),
+
+ ESESTATUS_INVALID_PARAMETER = (0x00FF),
+
+ ESESTATUS_CMD_ABORTED = (0x0002),
+
+ ESESTATUS_NO_TARGET_FOUND = (0x000A),
+
+ ESESTATUS_NO_DEVICE_CONNECTED = (0x000B),
+
+ ESESTATUS_RESYNCH_REQ = (0x000E),
+
+ ESESTATUS_RESYNCH_RES = (0x0010),
+
+ ESESTATUS_IFS_REQ = (0x001E),
+
+ ESESTATUS_IFS_RES = (0x0017),
+
+ ESESTATUS_ABORT_REQ = (0x00F0),
+
+ ESESTATUS_ABORT_RES = (0x00F2),
+
+ ESESTATUS_WTX_REQ = (0x00F5),
+
+ ESESTATUS_WTX_RES = (0x00F6),
+
+ ESESTATUS_RESET_REQ = (0x00F7),
+
+ ESESTATUS_RESET_RES = (0x00F8),
+
+ ESESTATUS_END_APDU_REQ = (0x00F9),
+
+ ESESTATUS_END_APDU_RES = (0x00FA),
+
+ ESESTATUS_SHUTDOWN = (0x0091),
+
+ ESESTATUS_TARGET_LOST = (0x0092),
+
+ ESESTATUS_REJECTED = (0x0093),
+
+ ESESTATUS_TARGET_NOT_CONNECTED = (0x0094),
+
+ ESESTATUS_INVALID_HANDLE = (0x0095),
+
+ ESESTATUS_ABORTED = (0x0096),
+
+ ESESTATUS_COMMAND_NOT_SUPPORTED = (0x0097),
+
+ ESESTATUS_NON_NDEF_COMPLIANT = (0x0098),
+
+ ESESTATUS_NOT_ENOUGH_MEMORY = (0x001F),
+
+ ESESTATUS_INCOMING_CONNECTION = (0x0045),
+
+ ESESTATUS_CONNECTION_SUCCESS = (0x0046),
+
+ ESESTATUS_CONNECTION_FAILED = (0x0047),
+
+ ESESTATUS_TRANSCEIVE_FAILED = (0x0048),
+} ESESTATUS;
+#endif /* PHESESTATUS_H */
+/** @} */
diff --git a/snxxx/libese-spi/p73/inc/phNxpEse_Apdu_Api.h b/snxxx/libese-spi/p73/inc/phNxpEse_Apdu_Api.h
new file mode 100644
index 0000000..1f80f83
--- /dev/null
+++ b/snxxx/libese-spi/p73/inc/phNxpEse_Apdu_Api.h
@@ -0,0 +1,105 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019,2021 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/**
+ * \addtogroup ISO7816-4_application_protocol_implementation
+ *
+ * @{ */
+
+#ifndef _PHNXPESE_APDU_H
+#define _PHNXPESE_APDU_H
+#include <phEseStatus.h>
+
+/**
+ * \brief 7816-4 APDU command Header Size
+ *
+ */
+
+#define MIN_HEADER_LEN 4
+
+/**
+ * \ingroup ISO7816-4_application_protocol_implementation
+ * \brief Command data unit structure params
+ *
+ */
+typedef struct phNxpEse_7816_cpdu {
+ uint8_t cla; /*!< Class of instruction */
+ uint8_t ins; /*!< Instruction code */
+ uint8_t p1; /*!< Instruction parameter 1 */
+ uint8_t p2; /*!< Instruction parameter 2 */
+ uint16_t lc; /*!< No of data present in the data field of the command */
+ uint8_t cpdu_type; /*!< 0 - short len, 1 = extended len, this field is valid
+ only if le > 0*/
+ uint8_t* pdata; /*!< application data*/
+ uint8_t le_type; /*!< 0 - Le absent ,1 - one byte le,2 - two byte le or 3 - 3
+ byte le*/
+ uint32_t le; /*!< le value field */
+} phNxpEse_7816_cpdu_t;
+
+/**
+ * \ingroup ISO7816-4_application_protocol_implementation
+ * \brief Command data unit structure params
+ *
+ */
+typedef phNxpEse_7816_cpdu_t* pphNxpEse_7816_cpdu_t;
+
+/**
+ * \ingroup ISO7816-4_application_protocol_implementation
+ * \brief Response data unit structure params
+ *
+ */
+typedef struct phNxpEse_7816_rpdu {
+ uint8_t sw1; /*!< Status byte most significant byte */
+ uint8_t sw2; /*!< Status byte least significant byte */
+ uint8_t* pdata; /*!< Buffer allocated by caller*/
+ uint16_t len; /*!< Length of the buffer, updated by calling api */
+} phNxpEse_7816_rpdu_t;
+
+/**
+ * \ingroup ISO7816-4_application_protocol_implementation
+ * \brief Response data unit structure params
+ *
+ */
+typedef phNxpEse_7816_rpdu_t* pphNxpEse_7816_rpdu_t;
+
+/**
+ * \ingroup ISO7816-4_application_protocol_implementation
+ * \brief This function prepares C-APDU and sends to p61 and receives response
+ *from the p61.
+ * also it parses all required fields of the response PDU.
+ *
+ * \param[in] pCmd - CMD to p61
+ * \param[out] pRsp - RSP from p61(all required memory
+ *allocated by caller)
+ *
+ * \retval ESESTATUS_SUCCESS - On Success #pphNxpEse_7816_rpdu_t all fields are
+ *filled correctly.
+ * else proper error code.
+ * \retval ESESTATUS_INVALID_PARAMETER - If any invalid buffer passed from
+ *application \n
+ * \retval ESESTATUS_INSUFFICIENT_RESOURCES - Any problem occurred during
+ *allocating the memory \n
+ * \retval ESESTATUS_INVALID_BUFFER - If any invalid buffer received \n
+ * \retval ESESTATUS_FAILED - Any other error occurred. \n
+ */
+
+ESESTATUS phNxpEse_7816_Transceive(pphNxpEse_7816_cpdu_t pCmd,
+ pphNxpEse_7816_rpdu_t pRsp);
+
+#endif /* _PHNXPESE_APDU_H */
+/** @} */
diff --git a/snxxx/libese-spi/p73/inc/phNxpEse_Api.h b/snxxx/libese-spi/p73/inc/phNxpEse_Api.h
new file mode 100755
index 0000000..fc9655d
--- /dev/null
+++ b/snxxx/libese-spi/p73/inc/phNxpEse_Api.h
@@ -0,0 +1,459 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+
+/**
+ * \addtogroup spi_libese
+ * \brief ESE Lib layer interface to application
+ * @{ */
+
+#ifndef _PHNXPSPILIB_API_H_
+#define _PHNXPSPILIB_API_H_
+
+#include <phEseStatus.h>
+#include <phNxpEsePal.h>
+
+/**
+ * \ingroup spi_libese
+ * \brief Ese data buffer
+ *
+ */
+typedef struct phNxpEse_data {
+ uint32_t len; /*!< length of the buffer */
+ uint8_t* p_data; /*!< pointer to a buffer */
+} phNxpEse_data;
+
+/**
+ * \ingroup spi_libese
+ * \brief Ese Channel mode
+ *
+ */
+typedef enum {
+ ESE_MODE_NORMAL = 0, /*!< All wired transaction other OSU */
+ ESE_MODE_OSU /*!< Jcop Os update mode */
+} phNxpEse_initMode;
+
+/**
+ * \ingroup spi_libese
+ * \brief Ese logical interface i.e. MediaType
+ *
+ */
+typedef enum {
+ ESE_PROTOCOL_MEDIA_SPI = 0x08, /*!< Media Type - SPI legacy */
+ ESE_PROTOCOL_MEDIA_SPI_APDU_GATE = 0xD0 /*!Media Type - APDU Gate */
+} phNxpEse_mediaType;
+
+typedef enum {
+ WTX_ONGOING = 1,
+ WTX_END = 2,
+} phNxpEse_wtxState;
+
+typedef enum phNxpEseProto7816_OsType {
+ UNKNOWN_MODE = 0,
+ JCOP_MODE = 0x1,
+ OSU_MODE = 0x2,
+} phNxpEseProto7816_OsType_t;
+
+#define MODE_JCOP 0x01
+#define MODE_OSU 0x02
+#define RESET_APP_WTX_COUNT 0
+
+typedef void(NotifyWtxReq)(phNxpEse_wtxState);
+/**
+ * \ingroup spi_libese
+ * \brief Ese library init parameters to be set while calling phNxpEse_init
+ *
+ */
+typedef struct phNxpEse_initParams {
+ phNxpEse_initMode initMode; /*!< Ese communication mode */
+ phNxpEse_mediaType mediaType; /*!< Logical channel for Ese communication */
+ NotifyWtxReq* fPtr_WtxNtf; /*!< Wait extension callback notification*/
+} phNxpEse_initParams;
+
+/*!
+ * \brief SEAccess kit MW Android version
+ */
+#define NXP_ANDROID_VER (9U)
+
+/*!
+ * \brief SEAccess kit MW Major version
+ */
+#define ESELIB_MW_VERSION_MAJ (0x0U)
+
+/*!
+ * \brief SEAccess kit MW Minor version
+ */
+#define ESELIB_MW_VERSION_MIN (0x04)
+
+/*!
+ * \brief eSE debugging log Level
+ */
+extern bool ese_debug_enabled;
+
+/**
+ * \ingroup spi_libese
+ *
+ * \brief This function is called by Jni/phNxpEse_open during the
+ * initialization of the ESE. It initializes protocol stack instance
+ * variables.
+ *
+ * \param[in] initParams - init parameters to be set while calling
+ * phNxpEse_init
+ *
+ * \retval This function return ESESTATUS_SUCCESS (0) in case of success
+ * In case of failure returns other failure value.
+ *
+ */
+ESESTATUS phNxpEse_init(phNxpEse_initParams initParams);
+
+/**
+ * \ingroup spi_libese
+ *
+ * \brief Check if libese has opened
+ *
+ * \retval return false if it is close, otherwise true.
+ *
+ */
+bool phNxpEse_isOpen();
+
+/**
+ * \ingroup spi_libese
+ *
+ * \brief This function is used to communicate from nfc-hal to ese-hal
+ *
+ * \param[in] ioctlType - ioctl cmd
+ *\param[out] p_data - value read out
+ *
+ * \retval This function return ESESTATUS_SUCCESS (0) in case of success
+ * In case of failure returns other failure value.
+ *
+ */
+ESESTATUS phNxpEse_spiIoctl(uint64_t ioctlType, void* p_data);
+/**
+ * \ingroup spi_libese
+ *
+ * \brief This function is called by hal interface api before any
+ * communication. It sets the end point variables
+ *
+ * \param[in] uEndPoint - select the end point type ( END_POINT_ESE = 0,
+ * END_POINT_eUICC =1 ).
+ *
+ * \retval This function return ESESTATUS_SUCCESS (0) in case of success
+ * In case of failure returns other failure value.
+ *
+ */
+ESESTATUS phNxpEse_SetEndPoint_Cntxt(uint8_t uEndPoint);
+
+/**
+ * \ingroup spi_libese
+ *
+ * \brief This function is called by hal interface api before any
+ * communication. It resets the end point variables
+ *
+ * \param[in] uEndPoint - select the end point type ( END_POINT_ESE = 0,
+ * END_POINT_eUICC =1 ).
+ *
+ * \retval This function return ESESTATUS_SUCCESS (0) in case of success
+ * In case of failure returns other failure value.
+ *
+ */
+ESESTATUS phNxpEse_ResetEndPoint_Cntxt(uint8_t uEndPoint);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function is called by Jni during the
+ * initialization of the ESE. It opens the physical connection
+ * with ESE () and initializes the protocol stack
+ *
+ * \param[in] initParams - Initialize with init mode ( normal/osu) and media
+ * type(SPI- legacy/ APDU type).
+ *
+ * \retval ESESTATUS_SUCCESS On Success ESESTATUS_SUCCESS else proper error code
+ *
+ */
+ESESTATUS phNxpEse_open(phNxpEse_initParams initParams);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function is called by Jni during the
+ * initialization of the ESE. It opens the physical connection
+ * with ESE () and creates required client thread for
+ * operation. This will get priority access to ESE for timeout period.
+ *
+ * \param[in] initParams - Initialize with init mode ( normal/osu) and media
+ * type(SPI- legacy/ APDU type).
+ *
+ * \retval ESESTATUS_SUCCESS On Success ESESTATUS_SUCCESS else proper error code
+ *
+ */
+ESESTATUS phNxpEse_openPrioSession(phNxpEse_initParams initParams);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function prepares the C-APDU, send to ESE and then receives the
+ *response from ESE,
+ * decode it and returns data.
+ *
+ * \param[in] pCmd: Command to ESE
+ * \param[out] pRsp: Response from ESE (Returned data to be freed
+ *after copying)
+ *
+ * \retval ESESTATUS_SUCCESS On Success ESESTATUS_SUCCESS else proper error code
+ *
+ */
+
+ESESTATUS phNxpEse_Transceive(phNxpEse_data* pCmd, phNxpEse_data* pRsp);
+
+/**
+ * \ingroup spi_libese
+ *
+ * \brief This function is called by Jni/phNxpEse_close during the
+ * de-initialization of the ESE. It de-initializes protocol stack
+ *instance variables
+ *
+ * \retval This function return ESESTATUS_SUCCESS (0) in case of success
+ * In case of failure returns other failure value.
+ *
+ */
+ESESTATUS phNxpEse_deInit(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function close the ESE interface and free all resources.
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+
+ESESTATUS phNxpEse_close(ESESTATUS deInitStatus = ESESTATUS_SUCCESS);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function reset the ESE interface and free all
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_reset(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function reset the ESE
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_resetJcopUpdate(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function reset the P73 through ISO RST pin
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_chipReset(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function is used to set IFSC size
+ *
+ * \param[in] IFS_Size
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_setIfs(uint16_t IFS_Size);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function is used to get the ATR data from ESE
+ *
+ * \param[out] pATR
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_getAtr(phNxpEse_data* pATR);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function sends the S-frame to indicate END_OF_APDU
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_EndOfApdu(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function suspends execution of the calling thread for
+ * (at least) usec microseconds
+ *
+ * \param[in] usec
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_Sleep(uint32_t usec);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function updates destination buffer with val
+ * data in len size
+ *
+ * \param[in] buff - Array to be updated
+ * \param[in] val - value to be updated
+ * \param[in] len - length of array to be updated
+ *
+ * \retval void
+ *
+ */
+void* phNxpEse_memset(void* buff, int val, size_t len);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function copies source buffer to destination buffer
+ * data in len size
+ *
+ * \param[in] dest - Destination array to be updated
+ * \param[in] src - Source array to be updated
+ * \param[in] len - length of array to be updated
+ *
+ * \retval void
+ *
+ */
+void* phNxpEse_memcpy(void* dest, const void* src, size_t len);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function suspends allocate memory
+ *
+ * \param[in] size
+ *
+ * \retval allocated memory.
+ *
+ */
+void* phNxpEse_memalloc(uint32_t size);
+
+/**
+ * \ingroup spi_libese
+ * \brief This is utility function for runtime heap memory allocation
+ *
+ *\param[in] dataType - data type
+ * \param[in] size - number of bytes to be allocated
+ *
+ * \retval void
+ *
+ */
+void* phNxpEse_calloc(size_t dataType, size_t size);
+
+/**
+ * \ingroup spi_libese
+ * \brief This is utility function for freeeing heap memory allocated
+ *
+ * \param[in] ptr - Address pointer to previous allocation
+ *
+ * \retval void
+ *
+ */
+void phNxpEse_free(void* ptr);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function performs disable/enable power control
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_DisablePwrCntrl(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function is used to get the ESE timer status
+ *
+ * \param[out] timer_buffer
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_GetEseStatus(phNxpEse_data* timer_buffer);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function power recycles the ESE
+ * (using prop. FW command) by talking to NFC HAL
+ *
+ * Note:
+ * After cold reset, phNxpEse_init need to be called to
+ * reset the host AP T=1 stack parameters
+ *
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_coldReset(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function notifies SE hal service if it registers
+ *
+ * \param[out] state - WTX_ONGOIGN/WTX_END
+ *
+ * \retval void.
+ *
+ */
+void phNxpEse_NotifySEWtxRequest(phNxpEse_wtxState state);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to get OS mode(JCOP/OSU)
+ *
+ * \retval OS mode(JCOP/OSU).
+ *
+ */
+phNxpEseProto7816_OsType_t phNxpEse_GetOsMode(void);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function enable/disable resetprotection
+ *
+ * \param[in] flag - indicated enable or disable resetprotection.
+ *
+ * \retval ESESTATUS_SUCCESS Always return ESESTATUS_SUCCESS (0).
+ *
+ */
+ESESTATUS phNxpEse_doResetProtection(bool flag);
+
+/**
+ * \ingroup spi_libese
+ * \brief This function is used to set the wtx count limit
+ *
+ * \param[in] wtxCount - value to set for wtx count limit
+ *
+ * \retval void.
+ *
+ */
+void phNxpEse_setWtxCountLimit(unsigned long int wtxCount);
+/** @} */
+#endif /* _PHNXPSPILIB_API_H_ */
diff --git a/snxxx/libese-spi/p73/lib/phNxpEseDataMgr.cpp b/snxxx/libese-spi/p73/lib/phNxpEseDataMgr.cpp
new file mode 100755
index 0000000..1267c07
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEseDataMgr.cpp
@@ -0,0 +1,165 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+#include <phNxpEseDataMgr.h>
+#include <phNxpEsePal.h>
+
+static phNxpEse_sCoreRecvBuff_List_t *head = NULL, *current = NULL;
+static uint32_t total_len = 0;
+
+static ESESTATUS phNxpEse_DeletList(phNxpEse_sCoreRecvBuff_List_t* head);
+static ESESTATUS phNxpEse_GetDataFromList(uint32_t* data_len, uint8_t* pbuff);
+/******************************************************************************
+ * Function phNxpEse_GetData
+ *
+ * Description This function update the len and provided buffer
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_GetData(uint32_t* data_len, uint8_t** pbuffer) {
+ uint32_t total_data_len = 0;
+ uint8_t* pbuff = NULL;
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ if (total_len > 0) {
+ pbuff = (uint8_t*)phNxpEse_memalloc(total_len);
+ if (NULL != pbuff) {
+ if (ESESTATUS_SUCCESS ==
+ phNxpEse_GetDataFromList(&total_data_len, pbuff)) {
+ if (total_data_len == total_len) {
+ /***** Success Case *****/
+ *pbuffer = pbuff;
+ *data_len = total_data_len;
+ phNxpEse_DeletList(head);
+ head = NULL;
+ current = NULL;
+ total_len = 0;
+ status = ESESTATUS_SUCCESS;
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "%s Mismatch of len total_data_len %d total_len %d",
+ __FUNCTION__, total_data_len, total_len);
+ phNxpEse_free(pbuff);
+ }
+ } else {
+ ALOGE("%s phNxpEse_GetDataFromList failed", __FUNCTION__);
+ phNxpEse_free(pbuff);
+ }
+ } else {
+ ALOGE("%s Error in malloc ", __FUNCTION__);
+ status = ESESTATUS_NOT_ENOUGH_MEMORY;
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled, "%s total_len = %d", __FUNCTION__, total_len);
+ }
+
+ if (ESESTATUS_SUCCESS != status) {
+ *pbuffer = NULL;
+ *data_len = 0;
+ }
+ ALOGD_IF(ese_debug_enabled, "%s exit status = %d", __FUNCTION__, status);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_StoreDatainList
+ *
+ * Description This function stores the received data in linked list
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_StoreDatainList(uint32_t data_len, uint8_t* pbuff) {
+ phNxpEse_sCoreRecvBuff_List_t* newNode = NULL;
+
+ newNode = (phNxpEse_sCoreRecvBuff_List_t*)phNxpEse_memalloc(
+ sizeof(phNxpEse_sCoreRecvBuff_List_t));
+ if (newNode == NULL) {
+ ALOGE("%s Error in malloc ", __FUNCTION__);
+ return ESESTATUS_NOT_ENOUGH_MEMORY;
+ }
+ newNode->pNext = NULL;
+ newNode->tData.wLen = data_len;
+ phNxpEse_memcpy(newNode->tData.sbuffer, pbuff, data_len);
+ total_len += data_len;
+ if (head == NULL) {
+ head = newNode;
+ current = newNode;
+ } else {
+ current->pNext = newNode;
+ current = newNode;
+ }
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEse_GetDataFromList
+ *
+ * Description This function copies all linked list data in provided buffer
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEse_GetDataFromList(uint32_t* data_len, uint8_t* pbuff) {
+ phNxpEse_sCoreRecvBuff_List_t* new_node;
+ uint32_t offset = 0;
+ ALOGD_IF(ese_debug_enabled, "%s Enter ", __FUNCTION__);
+ if (head == NULL || pbuff == NULL) {
+ return ESESTATUS_FAILED;
+ }
+
+ new_node = head;
+ while (new_node != NULL) {
+ phNxpEse_memcpy((pbuff + offset), new_node->tData.sbuffer,
+ new_node->tData.wLen);
+ offset += new_node->tData.wLen;
+ new_node = new_node->pNext;
+ }
+ *data_len = offset;
+ ALOGD_IF(ese_debug_enabled, "%s Exit ", __FUNCTION__);
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEse_DeletList
+ *
+ * Description This function deletes all nodes from linked list
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEse_DeletList(phNxpEse_sCoreRecvBuff_List_t* head) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ phNxpEse_sCoreRecvBuff_List_t *current, *next;
+ current = head;
+
+ if (head == NULL) {
+ return ESESTATUS_FAILED;
+ }
+
+ while (current != NULL) {
+ next = current->pNext;
+ phNxpEse_free(current);
+ current = NULL;
+ current = next;
+ }
+ head = NULL;
+ return status;
+}
diff --git a/snxxx/libese-spi/p73/lib/phNxpEseDataMgr.h b/snxxx/libese-spi/p73/lib/phNxpEseDataMgr.h
new file mode 100644
index 0000000..77fea80
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEseDataMgr.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef _PHNXPESE_RECVMGR_H_
+#define _PHNXPESE_RECVMGR_H_
+#include <phNxpEse_Internal.h>
+
+/*!
+ * \brief eSE Data buffer structure
+ *
+ *
+ */
+typedef struct phNxpEse_DataPacket {
+ uint8_t sbuffer[MAX_DATA_LEN]; /*!<buffer to be used to store the received
+ packet */
+ uint16_t wLen; /*!<hold the length of the buffer */
+} phNxpEse_DataPacket_t;
+
+/*!
+ * \brief eSE data receive buffer linkedlist
+ *
+ *
+ */
+typedef struct phNxpEse_sCoreRecvBuff_List {
+ phNxpEse_DataPacket_t
+ tData; /*!<buffer to be used to store the received payload */
+ struct phNxpEse_sCoreRecvBuff_List*
+ pNext; /*!<pointer to the next node present in lined list*/
+} phNxpEse_sCoreRecvBuff_List_t;
+
+ESESTATUS phNxpEse_GetData(uint32_t* data_len, uint8_t** pbuff);
+ESESTATUS phNxpEse_StoreDatainList(uint32_t data_len, uint8_t* pbuff);
+
+#endif /* PHNXPESE_RECVMGR_H */
diff --git a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
new file mode 100755
index 0000000..bf1aad2
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.cpp
@@ -0,0 +1,2231 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+#include <phNxpEseProto7816_3.h>
+
+/**
+ * \addtogroup ISO7816-3_protocol_lib
+ *
+ * @{ */
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to reset the 7816 protocol stack instance
+ *
+ *
+ */
+static ESESTATUS phNxpEseProto7816_ResetProtoParams(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called send the data to ESE
+ *\param[in] data_len - data len
+ *\param[in] p_data -address to raw data
+ *
+ */
+static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len,
+ uint8_t* p_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called read the data from the ESE
+ *\param[in] data_len - data len
+ *\param[in] pp_data -address to raw data
+ *
+ */
+static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len,
+ uint8_t** pp_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called compute the LRC
+ *\param[in] p_buff - raw data
+ *\param[in] offset -address to raw data
+ *\param[in] length - length of data.
+ *\retval LRC value.
+ *
+ */
+static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff,
+ uint32_t offset, uint32_t length);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called compute and compare the
+ * received LRC of the received data
+ *\param[in] data_len - raw data
+ *\param[in] p_data -address to raw data
+ *
+ */
+static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len, uint8_t* p_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to send S-frame with all
+ * updated 7816-3 headers
+ *\param[in] sFrameData -S frame APDU
+ *
+ */
+static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to send I-frame with all
+ * updated 7816-3 headers
+ *\param[in] iFrameData -I frame APDU
+ *
+ */
+static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to send R-frame with all
+ *updated 7816-3 headers
+ *\param[in] rFrameType -R frame APDU
+ *
+ */
+static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to set the context for first
+ *I-frame. Not applicable for the first I-frame of the transceive
+ *
+ */
+static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to set the context for next
+ *I-frame. Not applicable for the first I-frame of the transceive
+ *
+ */
+static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to push I-frame data to internal
+ *structure. \param[in] p_data -raw data buffer \param[in] data_len -data
+ *length
+ *
+ */
+static ESESTATUS phNxpEseProto7816_SaveIframeData(uint8_t* p_data,
+ uint32_t data_len);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called to do reset the recovery
+ *pareameters
+ *
+ */
+static ESESTATUS phNxpEseProto7816_ResetRecovery(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is called when 7816-3 stack failed to
+ *recover after PH_PROTO_7816_FRAME_RETRY_COUNT, and the interface has
+ *to be recovered
+ *
+ */
+static ESESTATUS phNxpEseProto7816_RecoverySteps(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is used to
+ * 1. Identify the received frame
+ * 2. If the received frame is I-frame with expected sequence
+ number, store it or else send R-NACK
+ 3. If the received frame is R-frame,
+ 3.1 R-ACK with expected seq. number: Send the next
+ chained I-frame
+ 3.2 R-ACK with different sequence number: Send the R-Nack
+ 3.3 R-NACK: Re-send the last frame
+ 4. If the received frame is S-frame, send back the correct
+ S-frame response.
+ *\param[in] p_data -address of data.
+ *\param[in] data_len -length of the frame
+ *
+ */
+static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data,
+ uint32_t data_len);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is used to
+ * 1. Check the LRC
+ * 2. Initiate decoding of received frame of data.
+ *
+ */
+static ESESTATUS phNxpEseProto7816_ProcessResponse(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is used to
+ * 1. Send the raw data received from application after
+ *computing LRC
+ * 2. Receive the response data from ESE, decode, process
+ *and
+ * store the data.
+ *
+ */
+static ESESTATUS TransceiveProcess(void);
+
+/**
+ * \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
+ *
+ */
+static ESESTATUS phNxpEseProto7816_RSync(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to reset the 7816 protocol stack
+ *
+ */
+static ESESTATUS phNxpEseProto7816_ResetProtoParams(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to send the spi hard reset command
+ *
+ */
+static ESESTATUS phNxpEseProto7816_HardReset(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is to decode the secure timer.
+ * value from the payload
+ *\param[in] frameOffset -To get the L of TLV
+ *\param[in] secureTimer -V of TLV: Retrieve each byte(4 byte) and push it
+ *to get the secure timer value (unsigned long) \param[in] p_data -pointer to
+ *data.
+ *
+ */
+static void phNxpEseProto7816_DecodeSecureTimer(uint8_t* frameOffset,
+ unsigned int* secureTimer,
+ uint8_t* p_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is to decode S-frame payload.
+ *\param[in] p_data -Raw Data IFS.
+ *
+ */
+static void phNxpEseProto7816_DecodeSFrameIFSData(uint8_t* p_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is to decode S-frame (ATR) payload.
+ *\param[in] p_data -ATR TLV.
+ *
+ */
+static void phNxpEseProto7816_DecodeSFrameATRData(uint8_t* p_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is to decode S-frame (secure timer TLV)
+ *payload. \param[in] p_data -raw data - secure timer TLV.
+ *
+ */
+static void phNxpEseProto7816_DecodeSFrameSecureTimerData(uint8_t* p_data);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function is to notify either WTX_ONGOING ot
+ *WTX_END \param[in] state - Either WTX_ONGOING/WTX_END
+ *
+ */
+static void phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This internal function to check Last sent frame is S-Frame
+ * request and if received block is not S-Frame response
+ * re-send Last S-frame request
+ */
+static bool phNxpEseProto7816_ResendLastSFrameReq(void);
+/*!
+ * \brief 7816_3 protocol stack parameter variable instance
+ */
+static phNxpEseProto7816_t phNxpEseProto7816_3_Var;
+
+/*!
+ * \brief 7816_3 protocol stack instance - pointer variable
+ */
+static phNxpEseProto7816_t phNxpEseProto7816_ptr[MAX_END_POINTS];
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SendRawFrame
+ *
+ * Description This internal function is called send the data to ESE
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_SendRawFrame(uint32_t data_len,
+ uint8_t* p_data) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ status = phNxpEse_WriteFrame(data_len, p_data);
+ if (ESESTATUS_SUCCESS != status) {
+ ALOGE("%s Error phNxpEse_WriteFrame\n", __FUNCTION__);
+ } else {
+ ALOGD_IF(ese_debug_enabled, "%s phNxpEse_WriteFrame Success \n",
+ __FUNCTION__);
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_GetRawFrame
+ *
+ * Description This internal function is called read the data from the ESE
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_GetRawFrame(uint32_t* data_len,
+ uint8_t** pp_data) {
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ status = phNxpEse_read(data_len, pp_data);
+ if (ESESTATUS_SUCCESS != status) {
+ ALOGE("%s phNxpEse_read failed , status : 0x%x", __FUNCTION__, status);
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ComputeLRC
+ *
+ * Description This internal function is called compute the LRC
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static uint8_t phNxpEseProto7816_ComputeLRC(unsigned char* p_buff,
+ uint32_t offset, uint32_t length) {
+ uint32_t LRC = 0, i = 0;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ for (i = offset; i < length; i++) {
+ LRC = LRC ^ p_buff[i];
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return (uint8_t)LRC;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_CheckLRC
+ *
+ * Description This internal function is called compute and compare the
+ * received LRC of the received data
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_CheckLRC(uint32_t data_len,
+ uint8_t* p_data) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ uint8_t calc_crc = 0;
+ uint8_t recv_crc = 0;
+ ALOGD_IF(ese_debug_enabled, "Enter %s len %d", __FUNCTION__, data_len);
+ if (data_len > 0) {
+ recv_crc = p_data[data_len - 1];
+
+ /* calculate the CRC after excluding CRC */
+ calc_crc = phNxpEseProto7816_ComputeLRC(p_data, 1, (data_len - 1));
+ ALOGD_IF(ese_debug_enabled, "Received LRC:0x%x Calculated LRC:0x%x",
+ recv_crc, calc_crc);
+ if (recv_crc != calc_crc) {
+ status = ESESTATUS_FAILED;
+ ALOGE("%s LRC failed", __FUNCTION__);
+ }
+ } else {
+ status = ESESTATUS_FAILED;
+ ALOGE("%s LRC failed length = 0", __FUNCTION__);
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SendSFrame
+ *
+ * Description This internal function is called to send S-frame with all
+ * updated 7816-3 headers
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_SendSFrame(sFrameInfo_t sFrameData) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ uint32_t frame_len = 0;
+ uint8_t* p_framebuff = NULL;
+ uint8_t pcb_byte = 0;
+ uint8_t lenIFS = 0;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ sFrameInfo_t sframeData = sFrameData;
+ /* This update is helpful in-case a R-NACK is transmitted from the MW */
+ phNxpEseProto7816_3_Var.lastSentNonErrorframeType = SFRAME;
+ switch (sframeData.sFrameType) {
+ case RESYNCH_REQ:
+ frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = 0;
+ p_framebuff[3] = 0x00;
+
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
+ pcb_byte |= PH_PROTO_7816_S_RESYNCH;
+ break;
+ case IFS_REQ:
+ frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
+ lenIFS = 0;
+ if (IFSC_SIZE_SEND < phNxpEseProto7816_3_Var.currentIFSDSize) {
+ frame_len += 2;
+ lenIFS = 2;
+ } else {
+ frame_len += 1;
+ lenIFS = 1;
+ }
+
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = lenIFS;
+ if (2 == lenIFS) {
+ p_framebuff[3] = (phNxpEseProto7816_3_Var.currentIFSDSize >> 8);
+ p_framebuff[4] =
+ (phNxpEseProto7816_3_Var.currentIFSDSize & EXTENDED_FRAME_MARKER);
+ } else {
+ p_framebuff[3] = phNxpEseProto7816_3_Var.currentIFSDSize;
+ }
+
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
+ pcb_byte |= IFS_REQ;
+ break;
+ case INTF_RESET_REQ:
+ frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = 0;
+ p_framebuff[3] = 0x00;
+
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
+ pcb_byte |= PH_PROTO_7816_S_RESET;
+ break;
+ case PROP_END_APDU_REQ:
+ frame_len =
+ (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN + sframeData.len);
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = sframeData.len;
+ if (!sframeData.len)
+ p_framebuff[3] = PH_PROTO_7816_VALUE_ZERO;
+ else
+ phNxpEse_memcpy(&(p_framebuff[3]), sframeData.p_data, sframeData.len);
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
+ pcb_byte |= PH_PROTO_7816_S_END_OF_APDU;
+ break;
+ case HARD_RESET_REQ:
+ frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = 0;
+ p_framebuff[3] = 0x00;
+
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
+ pcb_byte |= PH_PROTO_7816_S_HRD_RST_CMD;
+ break;
+ case WTX_RSP:
+ frame_len = (PH_PROTO_7816_HEADER_LEN + 1 + PH_PROTO_7816_CRC_LEN);
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = 0x01;
+ p_framebuff[3] = 0x01;
+
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_RSP;
+ pcb_byte |= PH_PROTO_7816_S_WTX;
+ break;
+ case ATR_REQ:
+ frame_len = (PH_PROTO_7816_HEADER_LEN + PH_PROTO_7816_CRC_LEN);
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ return ESESTATUS_FAILED;
+ }
+ p_framebuff[2] = 0;
+ p_framebuff[3] = 0x00;
+
+ pcb_byte |= PH_PROTO_7816_S_BLOCK_REQ; /* PCB */
+ pcb_byte |= ATR_REQ;
+ break;
+ default:
+ ALOGE("Invalid S-block");
+ break;
+ }
+ if (NULL != p_framebuff) {
+ /* frame the packet */
+ p_framebuff[0] = 0x00; /* NAD Byte */
+ p_framebuff[1] = pcb_byte; /* PCB */
+
+ p_framebuff[frame_len - 1] =
+ phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1));
+ ALOGD_IF(ese_debug_enabled, "S-Frame PCB: %x\n", p_framebuff[1]);
+ status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff);
+ phNxpEse_free(p_framebuff);
+ /*After S-Frame Tx 1 ms sleep before Rx*/
+ if ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) &&
+ (sframeData.sFrameType != PROP_END_APDU_REQ)) {
+ phNxpEse_Sleep(1 * 1000);
+ }
+ } else {
+ ALOGE("Invalid S-block or malloc for s-block failed");
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_sendRframe
+ *
+ * Description This internal function is called to send R-frame with all
+ * updated 7816-3 headers
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_sendRframe(rFrameTypes_t rFrameType) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ uint8_t recv_ack[4] = {0x00, 0x80, 0x00, 0x00};
+ if (RNACK == rFrameType) /* R-NACK */
+ {
+ recv_ack[1] = 0x82;
+ } else /* R-ACK*/
+ {
+ /* This update is helpful in-case a R-NACK is transmitted from the MW */
+ phNxpEseProto7816_3_Var.lastSentNonErrorframeType = RFRAME;
+ }
+ recv_ack[1] |=
+ ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo ^ 1)
+ << 4);
+ ALOGD_IF(ese_debug_enabled, "%s recv_ack[1]:0x%x", __FUNCTION__, recv_ack[1]);
+ recv_ack[3] =
+ phNxpEseProto7816_ComputeLRC(recv_ack, 0x00, (sizeof(recv_ack) - 1));
+ status = phNxpEseProto7816_SendRawFrame(sizeof(recv_ack), recv_ack);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SendIframe
+ *
+ * Description This internal function is called to send I-frame with all
+ * updated 7816-3 headers
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_SendIframe(iFrameInfo_t iFrameData) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ uint32_t frame_len = 0;
+ uint8_t* p_framebuff = NULL;
+ uint8_t pcb_byte = 0;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ if (0 == iFrameData.sendDataLen) {
+ ALOGE("I frame Len is 0, INVALID");
+ return ESESTATUS_FAILED;
+ }
+ /* This update is helpful in-case a R-NACK is transmitted from the MW */
+ phNxpEseProto7816_3_Var.lastSentNonErrorframeType = IFRAME;
+ frame_len = (iFrameData.sendDataLen + PH_PROTO_7816_HEADER_LEN +
+ PH_PROTO_7816_CRC_LEN + 2);
+
+ p_framebuff = (uint8_t*)phNxpEse_memalloc(frame_len * sizeof(uint8_t));
+ if (NULL == p_framebuff) {
+ ALOGE("Heap allocation failed");
+ return ESESTATUS_FAILED;
+ }
+
+ /* frame the packet */
+ p_framebuff[0] = 0x00; /* NAD Byte */
+
+ if (iFrameData.isChained) {
+ /* make B6 (M) bit high */
+ pcb_byte |= PH_PROTO_7816_CHAINING;
+ }
+
+ /* Update the send seq no */
+ pcb_byte |=
+ (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo << 6);
+
+ /* store the pcb byte */
+ p_framebuff[1] = pcb_byte;
+ if (iFrameData.sendDataLen >
+ IFSC_SIZE_SEND) { /* Case for frame size > 254 bytes */
+ p_framebuff[2] = EXTENDED_FRAME_MARKER;
+ uint8_t mask = (iFrameData.sendDataLen) & EXTENDED_FRAME_MARKER;
+ p_framebuff[4] = mask;
+ mask = ((iFrameData.sendDataLen) >> 8) & EXTENDED_FRAME_MARKER;
+ p_framebuff[3] = mask;
+ /* store I frame */
+ phNxpEse_memcpy(&(p_framebuff[5]),
+ iFrameData.p_data + iFrameData.dataOffset,
+ iFrameData.sendDataLen);
+ } else { /* Case for frame size < 254 bytes */
+ /* store I frame length */
+ p_framebuff[2] = iFrameData.sendDataLen;
+ frame_len = frame_len - 2;
+ /* store I frame */
+ phNxpEse_memcpy(&(p_framebuff[3]),
+ iFrameData.p_data + iFrameData.dataOffset,
+ iFrameData.sendDataLen);
+ }
+
+ p_framebuff[frame_len - 1] =
+ phNxpEseProto7816_ComputeLRC(p_framebuff, 0, (frame_len - 1));
+
+ status = phNxpEseProto7816_SendRawFrame(frame_len, p_framebuff);
+
+ phNxpEse_free(p_framebuff);
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SetNextIframeContxt
+ *
+ * Description This internal function is called to set the context for next
+ *I-frame.
+ * Not applicable for the first I-frame of the transceive
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_SetFirstIframeContxt(void) {
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset = 0;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME;
+ if (phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen >
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .currentDataLenIFS) {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .currentDataLenIFS;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen -
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .currentDataLenIFS;
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false;
+ }
+ ALOGD_IF(ese_debug_enabled, "I-Frame Data Len: %d Seq. no:%d",
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo);
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SetNextIframeContxt
+ *
+ * Description This internal function is called to set the context for next
+ *I-frame.
+ * Not applicable for the first I-frame of the transceive
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_SetNextIframeContxt(void) {
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ /* Expecting to reach here only after first of chained I-frame is sent and
+ * before the last chained is sent */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_IFRAME;
+
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo ^ 1;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.dataOffset =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.dataOffset +
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS;
+
+ // if chained
+ if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen >
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
+ .currentDataLenIFS) {
+ ALOGD_IF(ese_debug_enabled, "Process Chained Frame");
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = true;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
+ .currentDataLenIFS;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen -
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
+ .currentDataLenIFS;
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.isChained = false;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.totalDataLen;
+ }
+ ALOGD_IF(ese_debug_enabled, "I-Frame Data Len: %d",
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.sendDataLen);
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ResetRecovery
+ *
+ * Description This internal function is called to do reset the recovery
+ *pareameters
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_SaveIframeData(uint8_t* p_data,
+ uint32_t data_len) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ ALOGD_IF(ese_debug_enabled, "Data[0]=0x%x len=%d Data[%d]=0x%x", p_data[0],
+ data_len, data_len - 1, p_data[data_len - 1]);
+ if (ESESTATUS_SUCCESS != phNxpEse_StoreDatainList(data_len, p_data)) {
+ ALOGE("%s - Error storing chained data in list", __FUNCTION__);
+ } else {
+ status = ESESTATUS_SUCCESS;
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ResetRecovery
+ *
+ * Description This internal function is called to do reset the recovery
+ *pareameters
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_ResetRecovery(void) {
+ phNxpEseProto7816_3_Var.recoveryCounter = 0;
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_RecoverySteps
+ *
+ * Description This internal function is called when 7816-3 stack failed to
+ *recover
+ * after PH_PROTO_7816_FRAME_RETRY_COUNT, and the interface has
+ *to be
+ * recovered
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_RecoverySteps(void) {
+ if (phNxpEseProto7816_3_Var.recoveryCounter <= GET_FRAME_RETRY_COUNT()) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ INTF_RESET_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ INTF_RESET_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_INTF_RST;
+ } else { /* If recovery fails */
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
+ ALOGE("%s Recovery failed", __FUNCTION__);
+ }
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_DecodeSecureTimer
+ *
+ * Description This internal function is to decode the secure timer.
+ * value from the payload
+ * Returns void
+ *
+ ******************************************************************************/
+static void phNxpEseProto7816_DecodeSecureTimer(uint8_t* frameOffset,
+ unsigned int* secureTimer,
+ uint8_t* p_data) {
+ uint8_t byteCounter = 0;
+ uint8_t dataLength = p_data[++(*frameOffset)]; /* To get the L of TLV */
+ if (dataLength > 0) {
+ /* V of TLV: Retrieve each byte(4 byte) and push it to get the secure timer
+ * value (unsigned long) */
+ for (byteCounter = 1; byteCounter <= dataLength; byteCounter++) {
+ (*frameOffset)++;
+ *secureTimer = (*secureTimer) << 8;
+ *secureTimer |= p_data[(*frameOffset)];
+ }
+ } else {
+ (*frameOffset)++; /* Goto the end of current marker if length is zero */
+ }
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_DecodeSFrameIFSData
+ *
+ * Description This internal function is to decode S-frame payload.
+ * Returns void
+ *
+ ******************************************************************************/
+static void phNxpEseProto7816_DecodeSFrameIFSData(uint8_t* p_data) {
+ uint16_t ifsd_data = 0;
+ if (p_data[2] == 1) {
+ ifsd_data = p_data[3];
+ } else if (p_data[2] == 2) {
+ ifsd_data = p_data[3];
+ ifsd_data <<= 8;
+ ifsd_data |= p_data[4];
+ }
+ if (ifsd_data == phNxpEseProto7816_3_Var.currentIFSDSize) {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
+ phNxpEseProto7816_3_Var.currentIFSDSize;
+ ALOGD_IF(ese_debug_enabled, "%s IFS adjustment: Max DataLen=%d \n",
+ __FUNCTION__,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .currentDataLenIFS);
+ } else {
+ ALOGE("%s ERROR IFS adjustment: Max DataLen=%d \n", __FUNCTION__,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .currentDataLenIFS);
+ }
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_DecodeSFrameATRData
+ *
+ * Description This internal function is to decode S-frame payload.
+ * Returns void
+ *
+ ******************************************************************************/
+static void phNxpEseProto7816_DecodeSFrameATRData(uint8_t* p_data) {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC = 0;
+ /* Default IFSC size */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.defaultDataLenIFSC =
+ p_data[16];
+ // phNxpEse_memcpy(phNxpEseProto7816_3_Var.pAtrData, &p_data[3], p_data[2]);
+ /* Max IFSC size */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
+ (p_data[18] << 8);
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC |=
+ (p_data[19]);
+ if (!p_data[2])
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
+ IFSC_SIZE_SEND;
+
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.atrInfo.len,
+ &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET],
+ sizeof(phNxpEseProto7816_ATR_Info_t));
+
+ ALOGD_IF(
+ ese_debug_enabled,
+ "%s Max DataLen=%d Current DataLen=%d Default DataLen=%d \n",
+ __FUNCTION__,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .defaultDataLenIFSC);
+ ALOGD_IF(ese_debug_enabled, "ATR Data Follows");
+ ALOGD_IF(ese_debug_enabled, "======================");
+ ALOGD_IF(ese_debug_enabled, "ATR Length = %d",
+ phNxpEseProto7816_3_Var.atrInfo.len);
+ ALOGD_IF(ese_debug_enabled, "Vendor ID = 0x%.2x%.2x%.2x%.2x%.2x",
+ phNxpEseProto7816_3_Var.atrInfo.vendorID[0],
+ phNxpEseProto7816_3_Var.atrInfo.vendorID[1],
+ phNxpEseProto7816_3_Var.atrInfo.vendorID[2],
+ phNxpEseProto7816_3_Var.atrInfo.vendorID[3],
+ phNxpEseProto7816_3_Var.atrInfo.vendorID[4]);
+ ALOGD_IF(ese_debug_enabled, "DLL-IC = supports T%d",
+ phNxpEseProto7816_3_Var.atrInfo.dll_IC);
+ ALOGD_IF(ese_debug_enabled, "BGT = %d ms",
+ (phNxpEseProto7816_3_Var.atrInfo.bgt[0] << 8) |
+ (phNxpEseProto7816_3_Var.atrInfo.bgt[1]));
+ ALOGD_IF(ese_debug_enabled, "BWT = %d ms",
+ phNxpEseProto7816_3_Var.atrInfo.bwt[0] << 8 |
+ phNxpEseProto7816_3_Var.atrInfo.bwt[1]);
+ ALOGD_IF(ese_debug_enabled, "Max supported frequency = %d Hz",
+ phNxpEseProto7816_3_Var.atrInfo.maxFreq[0] << 8 |
+ phNxpEseProto7816_3_Var.atrInfo.maxFreq[1]);
+ ALOGD_IF(ese_debug_enabled, "Checksum LRC(0)/CRC(1) supports = 0x%x",
+ phNxpEseProto7816_3_Var.atrInfo.checksum);
+ ALOGD_IF(ese_debug_enabled, "DefaultIFSC = %d bytes",
+ phNxpEseProto7816_3_Var.atrInfo.defaultIFSC);
+ ALOGD_IF(ese_debug_enabled, "Max IFSC = %d bytes",
+ phNxpEseProto7816_3_Var.atrInfo.maxIFSC[0] << 8 |
+ phNxpEseProto7816_3_Var.atrInfo.maxIFSC[1]);
+ ALOGD_IF(ese_debug_enabled, "Capabilities = 0x%x",
+ phNxpEseProto7816_3_Var.atrInfo.capabilities[0] << 8 |
+ phNxpEseProto7816_3_Var.atrInfo.capabilities[1]);
+
+ if (phNxpEseProto7816_3_Var.atrInfo.vendorID[4] >= PH_SE_OS_VERSION_11) {
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.extndAtrInfo.channelNo,
+ &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] +
+ sizeof(phNxpEseProto7816_ATR_Info_t),
+ sizeof(phNxpEseProto7816_ATR_Info2_t));
+ ALOGD_IF(ese_debug_enabled, "Channel Number = 0x%x",
+ phNxpEseProto7816_3_Var.extndAtrInfo.channelNo);
+ ALOGD_IF(
+ ese_debug_enabled, "OS Type = %s",
+ (phNxpEseProto7816_3_Var.extndAtrInfo.osType == 0x01 ? "JCOP Mode"
+ : "OSU Mode"));
+ }
+ if (phNxpEseProto7816_3_Var.atrInfo.vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN -
+ 1] >= PH_SE_OS_VERSION_20) {
+ phNxpEse_setOsVersion(OS_VERSION_6_2);
+ } else if (phNxpEseProto7816_3_Var.atrInfo
+ .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] >=
+ PH_SE_OS_VERSION_11) {
+ phNxpEse_setOsVersion(OS_VERSION_5_2_2);
+ } else if (phNxpEseProto7816_3_Var.atrInfo
+ .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] ==
+ PH_SE_OS_VERSION_10) {
+ phNxpEse_setOsVersion(OS_VERSION_5_2);
+ } else if (phNxpEseProto7816_3_Var.atrInfo
+ .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] ==
+ PH_PROTO_7816_VALUE_ZERO) {
+ phNxpEse_setOsVersion(OS_VERSION_5_1);
+ }
+
+ ALOGD_IF(ese_debug_enabled, "======================");
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_DecodeSFrameData
+ *
+ * Description This internal function is to decode S-frame payload.
+ * Returns void
+ *
+ ******************************************************************************/
+static void phNxpEseProto7816_DecodeSFrameSecureTimerData(uint8_t* p_data) {
+ uint8_t maxSframeLen = 0, dataType = 0, frameOffset = 0;
+ frameOffset = PH_PROPTO_7816_FRAME_LENGTH_OFFSET;
+ maxSframeLen =
+ p_data[frameOffset] +
+ frameOffset; /* to be in sync with offset which starts from index 0 */
+
+ /* Secure Timer specific parser */
+ while (maxSframeLen > frameOffset) {
+ frameOffset += 1; /* To get the Type (TLV) */
+ dataType = p_data[frameOffset];
+ ALOGD_IF(ese_debug_enabled, "%s frameoffset=%d value=0x%x\n", __FUNCTION__,
+ frameOffset, p_data[frameOffset]);
+ switch (dataType) /* Type (TLV) */
+ {
+ case PH_PROPTO_7816_SFRAME_TIMER1:
+ phNxpEseProto7816_DecodeSecureTimer(
+ &frameOffset,
+ &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1, p_data);
+ break;
+ case PH_PROPTO_7816_SFRAME_TIMER2:
+ phNxpEseProto7816_DecodeSecureTimer(
+ &frameOffset,
+ &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2, p_data);
+ break;
+ case PH_PROPTO_7816_SFRAME_TIMER3:
+ phNxpEseProto7816_DecodeSecureTimer(
+ &frameOffset,
+ &phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3, p_data);
+ break;
+ default:
+ frameOffset +=
+ p_data[frameOffset + 1]; /* Goto the end of current marker */
+ break;
+ }
+ }
+ ALOGD_IF(ese_debug_enabled, "secure timer t1 = 0x%x t2 = 0x%x t3 = 0x%x",
+ phNxpEseProto7816_3_Var.secureTimerParams.secureTimer1,
+ phNxpEseProto7816_3_Var.secureTimerParams.secureTimer2,
+ phNxpEseProto7816_3_Var.secureTimerParams.secureTimer3);
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_DecodeFrame
+ *
+ * Description This internal function is used to
+ * 1. Identify the received frame
+ * 2. If the received frame is I-frame with expected sequence
+ number, store it or else send R-NACK
+ 3. If the received frame is R-frame,
+ 3.1 R-ACK with expected seq. number: Send the next
+ chained I-frame
+ 3.2 R-ACK with different sequence number: Sebd the R-Nack
+ 3.3 R-NACK: Re-send the last frame
+ 4. If the received frame is S-frame, send back the correct
+ S-frame response.
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_DecodeFrame(uint8_t* p_data,
+ uint32_t data_len) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ uint8_t pcb;
+ phNxpEseProto7816_PCB_bits_t pcb_bits;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ ALOGD_IF(ese_debug_enabled, "Retry Counter = %d\n",
+ phNxpEseProto7816_3_Var.recoveryCounter);
+ pcb = p_data[PH_PROPTO_7816_PCB_OFFSET];
+ // memset(&phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.rcvPcbBits, 0x00,
+ // sizeof(struct PCB_BITS));
+ phNxpEse_memset(&pcb_bits, 0x00, sizeof(phNxpEseProto7816_PCB_bits_t));
+ phNxpEse_memcpy(&pcb_bits, &pcb, sizeof(uint8_t));
+
+ if (0x00 == pcb_bits.msb) /* I-FRAME decoded should come here */
+ {
+ if (!phNxpEseProto7816_ResendLastSFrameReq()) {
+ ALOGD_IF(ese_debug_enabled, "%s I-Frame Received", __FUNCTION__);
+ phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = IFRAME;
+ if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo !=
+ pcb_bits.bit7) // != pcb_bits->bit7)
+ {
+ ALOGD_IF(ese_debug_enabled, "%s I-Frame lastRcvdIframeInfo.seqNo:0x%x",
+ __FUNCTION__, pcb_bits.bit7);
+ phNxpEseProto7816_ResetRecovery();
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo = 0x00;
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo |=
+ pcb_bits.bit7;
+
+ if (pcb_bits.bit6) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained =
+ true;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
+ NO_ERROR;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_ACK;
+ if (EXTENDED_FRAME_MARKER == p_data[2] &&
+ (data_len > 6)) /* Checking for extended frame prologue */
+ {
+ status = phNxpEseProto7816_SaveIframeData(&p_data[5], data_len - 6);
+ } else if (data_len > 4) {
+ status = phNxpEseProto7816_SaveIframeData(&p_data[3], data_len - 4);
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_NACK;
+ ALOGD_IF(ese_debug_enabled, "%s Invalid IframeData", __FUNCTION__);
+ }
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.isChained =
+ false;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ if (EXTENDED_FRAME_MARKER == p_data[2] &&
+ (data_len > 6)) /* Checking for extended frame prologue */
+ {
+ status = phNxpEseProto7816_SaveIframeData(&p_data[5], data_len - 6);
+ } else if (data_len > 4) {
+ status = phNxpEseProto7816_SaveIframeData(&p_data[3], data_len - 4);
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_NACK;
+ ALOGD_IF(ese_debug_enabled, "%s Invalid IframeData", __FUNCTION__);
+ }
+ }
+ } else {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ if (phNxpEseProto7816_3_Var.recoveryCounter < GET_FRAME_RETRY_COUNT()) {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
+ OTHER_ERROR;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_NACK;
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ } else {
+ phNxpEseProto7816_RecoverySteps();
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ }
+ }
+ }
+ } else if ((0x01 == pcb_bits.msb) &&
+ (0x00 == pcb_bits.bit7)) /* R-FRAME decoded should come here */
+ {
+ ALOGD_IF(ese_debug_enabled, "%s R-Frame Received", __FUNCTION__);
+ phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo =
+ 0; // = 0;
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo |=
+ pcb_bits.bit5;
+
+ if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x00)) {
+ if (!phNxpEseProto7816_ResendLastSFrameReq()) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
+ NO_ERROR;
+ phNxpEseProto7816_ResetRecovery();
+ if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.seqNo !=
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) {
+ status = phNxpEseProto7816_SetNextIframeContxt();
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_IFRAME;
+ } else {
+ // error handling.
+ }
+ }
+ } /* Error handling 1 : Parity error */
+ else if (((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x00)) ||
+ /* Error handling 2: Other indicated error */
+ ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) ||
+ /* Error handling 3 : Frame Missing error */
+ ((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x01))) {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
+ OTHER_ERROR;
+ } else if ((pcb_bits.lsb == 0x01) && (pcb_bits.bit2 == 0x00)) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
+ PARITY_ERROR;
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
+ SOF_MISSED_ERROR;
+ }
+ if (phNxpEseProto7816_3_Var.recoveryCounter < GET_FRAME_RETRY_COUNT()) {
+ if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == IFRAME) {
+ /*Only for R-NACK other issue re sync*/
+ if ((pcb_bits.lsb == 0x00) && (pcb_bits.bit2 == 0x01)) {
+ if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
+ .seqNo != phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx
+ .IframeInfo.seqNo &&
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo
+ .isChained == false) {
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_RSYNC;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo
+ .sFrameType = RESYNCH_REQ;
+ } else {
+ /*If R-NACK with sequence no matching then also reissue frame*/
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
+ }
+ } else {
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
+ }
+ } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
+ RFRAME) {
+ /* Usecase to reach the below case:
+ I-frame sent first, followed by R-NACK and we receive a R-NACK with
+ last sent I-frame sequence number*/
+ if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
+ .seqNo ==
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo) &&
+ (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == IFRAME)) {
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
+ }
+ /* Usecase to reach the below case:
+ R-frame sent first, followed by R-NACK and we receive a R-NACK with
+ next expected I-frame sequence number*/
+ else if ((phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
+ .seqNo != phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx
+ .IframeInfo.seqNo) &&
+ (phNxpEseProto7816_3_Var.lastSentNonErrorframeType ==
+ RFRAME)) {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
+ NO_ERROR;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_ACK;
+ }
+ /* Usecase to reach the below case:
+ I-frame sent first, followed by R-NACK and we receive a R-NACK with
+ next expected I-frame sequence number + all the other unexpected
+ scenarios */
+ else {
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
+ OTHER_ERROR;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_NACK;
+ }
+ } else if (phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType ==
+ SFRAME) {
+ /* Copy the last S frame sent */
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ }
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ } else {
+ phNxpEseProto7816_RecoverySteps();
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ }
+ // resend previously send I frame
+ } else /* Error handling 4 */
+ {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ if (phNxpEseProto7816_3_Var.recoveryCounter < GET_FRAME_RETRY_COUNT()) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
+ UNDEFINED_ERROR;
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ } else {
+ phNxpEseProto7816_RecoverySteps();
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ }
+ }
+ } else if ((0x01 == pcb_bits.msb) &&
+ (0x01 == pcb_bits.bit7)) /* S-FRAME decoded should come here */
+ {
+ ALOGD_IF(ese_debug_enabled, "%s S-Frame Received", __FUNCTION__);
+ int32_t frameType = (int32_t)(pcb & 0x3F); /*discard upper 2 bits */
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = SFRAME;
+ if (frameType != WTX_REQ) {
+ phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
+ }
+ phNxpEseProto7816_ResetRecovery();
+ switch (frameType) {
+ case RESYNCH_REQ:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ RESYNCH_REQ;
+ break;
+ case RESYNCH_RSP:
+ if (phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo
+ .errCode == OTHER_ERROR) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
+ .sFrameType = RESYNCH_RSP;
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdRframeInfo.errCode =
+ NO_ERROR;
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = IFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
+ PH_PROTO_7816_VALUE_ZERO;
+ /* Initialized the I-Frame sequence number as boot time,
+ as R-SYNCH has reset the Jcop seq number */
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
+ PH_PROTO_7816_VALUE_ONE;
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
+ .sFrameType = RESYNCH_RSP;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ }
+ break;
+ case IFS_REQ:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ IFS_REQ;
+ break;
+ case IFS_RES:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ IFS_RES;
+ if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
+ phNxpEseProto7816_DecodeSFrameIFSData(p_data);
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ case ABORT_REQ:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ ABORT_REQ;
+ break;
+ case ABORT_RES:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ ABORT_RES;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ case WTX_REQ:
+ phNxpEseProto7816_3_Var.wtx_counter++;
+ ALOGD_IF(ese_debug_enabled, "%s Wtx_counter value - %lu", __FUNCTION__,
+ phNxpEseProto7816_3_Var.wtx_counter);
+ ALOGD_IF(ese_debug_enabled, "%s Wtx_counter wtx_counter_limit - %lu",
+ __FUNCTION__, phNxpEseProto7816_3_Var.wtx_counter_limit);
+ /* Previous sent frame is some S-frame but not WTX response S-frame */
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0 &&
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType !=
+ WTX_RSP &&
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType == SFRAME) {
+ /* Goto recovery if it
+ keep coming here for more than recovery counter max. value */
+ if (phNxpEseProto7816_3_Var.recoveryCounter <
+ GET_FRAME_RETRY_COUNT()) { /* Re-transmitting the previous
+ sent S-frame */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ } else {
+ phNxpEseProto7816_RecoverySteps();
+ phNxpEseProto7816_3_Var.recoveryCounter++;
+ }
+ } else {
+ /* Checking for WTX counter with max. allowed WTX count */
+ if (phNxpEseProto7816_3_Var.wtx_counter ==
+ phNxpEseProto7816_3_Var.wtx_counter_limit) {
+ phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ALOGD_IF(ese_debug_enabled,
+ "%s Power cycle to eSE max "
+ "WTX received",
+ __FUNCTION__);
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ status = ESESTATUS_TRANSCEIVE_FAILED;
+ } else {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
+ .sFrameType = INTF_RESET_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo
+ .sFrameType = INTF_RESET_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_INTF_RST;
+ ALOGD_IF(ese_debug_enabled,
+ "%s Interface Reset to eSE wtx"
+ " count reached!!!",
+ __FUNCTION__);
+ }
+ } else {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo
+ .sFrameType = WTX_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ WTX_RSP;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_WTX_RSP;
+ }
+ }
+ break;
+ case WTX_RSP:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ WTX_RSP;
+ break;
+ case INTF_RESET_REQ:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ INTF_RESET_REQ;
+ break;
+ case INTF_RESET_RSP:
+ phNxpEseProto7816_ResetProtoParams();
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ INTF_RESET_RSP;
+ if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
+ phNxpEseProto7816_DecodeSFrameATRData(p_data);
+ } else {
+ phNxpEse_setOsVersion(OS_VERSION_4_0);
+ }
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ case PROP_END_APDU_REQ:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ PROP_END_APDU_REQ;
+ break;
+ case PROP_END_APDU_RSP:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ PROP_END_APDU_RSP;
+ if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0)
+ phNxpEseProto7816_DecodeSFrameSecureTimerData(p_data);
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ case HARD_RESET_REQ:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ HARD_RESET_REQ;
+ break;
+ case HARD_RESET_RSP:
+ // This is 4ms delay and delay of 1ms in also there in line 1401 before
+ // next Tx
+ phNxpEse_Sleep(HARD_RESET_RES_DELAY);
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ HARD_RESET_RSP;
+ if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
+ /*Response status either success/fail*/
+ if (!p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET + 1])
+ status = ESESTATUS_FAILED;
+ else
+ status = ESESTATUS_SUCCESS;
+ }
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ case ATR_RSP:
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdSframeInfo.sFrameType =
+ ATR_RSP;
+ if (p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET] > 0) {
+ phNxpEseProto7816_DecodeSFrameATRData(p_data);
+ phNxpEse_StoreDatainList(
+ p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET],
+ &p_data[PH_PROPTO_7816_FRAME_LENGTH_OFFSET + 1]);
+ } else {
+ phNxpEse_setOsVersion(OS_VERSION_4_0);
+ }
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = UNKNOWN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ default:
+ ALOGE("%s Wrong S-Frame Received", __FUNCTION__);
+ break;
+ }
+ /*After S-Frame Rx 1 msec delay before next Tx*/
+ if ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) &&
+ (frameType != PROP_END_APDU_RSP)) {
+ phNxpEse_Sleep(1000);
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled, "%s Wrong-Frame Received", __FUNCTION__);
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ProcessResponse
+ *
+ * Description This internal function is used to
+ * 1. Check the LRC
+ * 2. Initiate decoding of received frame of data.
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_ProcessResponse(void) {
+ uint32_t data_len = 0;
+ uint8_t* p_data = NULL;
+ ESESTATUS status = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ status = phNxpEseProto7816_GetRawFrame(&data_len, &p_data);
+ ALOGD_IF(ese_debug_enabled, "%s p_data ----> %p len ----> 0x%x", __FUNCTION__,
+ p_data, data_len);
+ if (ESESTATUS_SUCCESS == status) {
+ /* Resetting the timeout counter */
+ phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
+ /* LRC check followed */
+ status = phNxpEseProto7816_CheckLRC(data_len, p_data);
+ if (status == ESESTATUS_SUCCESS) {
+ /* Resetting the RNACK retry counter */
+ phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
+ status = phNxpEseProto7816_DecodeFrame(p_data, data_len);
+ } else {
+ ALOGE("%s LRC Check failed", __FUNCTION__);
+ if (phNxpEseProto7816_3_Var.rnack_retry_counter <
+ phNxpEseProto7816_3_Var.rnack_retry_limit) {
+ /*If Last sent Non-error frame is S-Frame*/
+ if (!phNxpEseProto7816_ResendLastSFrameReq()) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
+ PARITY_ERROR;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
+ (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo
+ .seqNo)
+ << 4;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_NACK;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ }
+ }
+ phNxpEseProto7816_3_Var.rnack_retry_counter++;
+ } else {
+ phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
+ /* Re-transmission failed completely, Going to exit */
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
+ }
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled, "%s phNxpEseProto7816_GetRawFrame failed",
+ __FUNCTION__);
+ if ((SFRAME == phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType) &&
+ ((WTX_RSP ==
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) ||
+ (RESYNCH_RSP ==
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType))) {
+ if (phNxpEseProto7816_3_Var.rnack_retry_counter <
+ phNxpEseProto7816_3_Var.rnack_retry_limit) {
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = RFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.errCode =
+ OTHER_ERROR;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.RframeInfo.seqNo =
+ (!phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo)
+ << 4;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_R_NACK;
+ phNxpEseProto7816_3_Var.rnack_retry_counter++;
+ } else {
+ phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
+ /* Re-transmission failed completely, Going to exit */
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
+ }
+ } else {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ /* re transmit the frame */
+ if (phNxpEseProto7816_3_Var.timeoutCounter <
+ PH_PROTO_7816_TIMEOUT_RETRY_COUNT) {
+ phNxpEseProto7816_3_Var.timeoutCounter++;
+ ALOGD_IF(ese_debug_enabled, "%s re-transmitting the previous frame",
+ __FUNCTION__);
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx =
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx;
+ } else {
+ /* Re-transmission failed completely, Going to exit */
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ status = ESESTATUS_FAILED;
+ }
+ phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
+ ALOGD_IF(ese_debug_enabled, "%s calling phNxpEse_StoreDatainList",
+ __FUNCTION__);
+ phNxpEse_StoreDatainList(data_len, p_data);
+ }
+ }
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
+ return status;
+}
+
+/******************************************************************************
+ * Function TransceiveProcess
+ *
+ * Description This internal function is used to
+ * 1. Send the raw data received from application after
+ *computing LRC
+ * 2. Receive the response data from ESE, decode, process
+ *and
+ * store the data.
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS TransceiveProcess(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ sFrameInfo_t sFrameInfo;
+ memset(&sFrameInfo, 0, sizeof(sFrameInfo_t));
+
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ while (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState !=
+ IDLE_STATE) {
+ ALOGD_IF(ese_debug_enabled, "%s nextTransceiveState %x", __FUNCTION__,
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState);
+ switch (phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState) {
+ case SEND_IFRAME:
+ status = phNxpEseProto7816_SendIframe(
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo);
+ break;
+ case SEND_R_ACK:
+ status = phNxpEseProto7816_sendRframe(RACK);
+ break;
+ case SEND_R_NACK:
+ status = phNxpEseProto7816_sendRframe(RNACK);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ phNxpEse_Sleep(GET_DELAY_ERROR_RECOVERY());
+ }
+ break;
+ case SEND_S_RSYNC:
+ sFrameInfo.sFrameType = RESYNCH_REQ;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ break;
+ case SEND_S_INTF_RST:
+ sFrameInfo.sFrameType = INTF_RESET_REQ;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ break;
+ case SEND_S_IFS_ADJ:
+ sFrameInfo.sFrameType = IFS_REQ;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ break;
+ case SEND_S_EOS:
+ sFrameInfo.sFrameType = PROP_END_APDU_REQ;
+ sFrameInfo.len =
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len;
+ sFrameInfo.p_data =
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.p_data;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ break;
+ case SEND_S_WTX_RSP:
+ sFrameInfo.sFrameType = WTX_RSP;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ phNxpEseProto7816_CheckAndNotifyWtx(WTX_ONGOING);
+ break;
+ case SEND_S_HRD_RST:
+ sFrameInfo.sFrameType = HARD_RESET_REQ;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ break;
+ case SEND_S_ATR_REQ:
+ sFrameInfo.sFrameType = ATR_REQ;
+ status = phNxpEseProto7816_SendSFrame(sFrameInfo);
+ break;
+ default:
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ break;
+ }
+ if (ESESTATUS_SUCCESS == status) {
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ status = phNxpEseProto7816_ProcessResponse();
+ } else {
+ ALOGE("%s Transceive send failed, going to recovery!", __FUNCTION__);
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ IDLE_STATE;
+ }
+ };
+ /*Timeout condition when previously WTX_ONGOING is notified
+ *WTX_END shall be notified from here */
+ phNxpEseProto7816_CheckAndNotifyWtx(WTX_END);
+ ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_CheckAndNotifyWtx
+ *
+ * Description This function is used to
+ * 1. Check any WTX received previously
+ *computing LRC
+ * 2. Check WTX_counter limit is reached wtx_ntf limit
+ *and
+ * 3. Notify if wtx counter is greater than wtx_ntf
+ *
+ * Returns None.
+ *
+ ******************************************************************************/
+static void phNxpEseProto7816_CheckAndNotifyWtx(phNxpEse_wtxState state) {
+ if (phNxpEseProto7816_3_Var.wtx_counter) {
+ if (state == WTX_END) {
+ if (phNxpEseProto7816_3_Var.wtx_counter >=
+ phNxpEseProto7816_3_Var.wtx_ntf_limit) {
+ phNxpEse_NotifySEWtxRequest(WTX_END);
+ }
+ phNxpEseProto7816_3_Var.wtx_counter = 0;
+ } else if (state == WTX_ONGOING) {
+ if (phNxpEseProto7816_3_Var.wtx_counter ==
+ phNxpEseProto7816_3_Var.wtx_ntf_limit) {
+ phNxpEse_NotifySEWtxRequest(WTX_ONGOING);
+ }
+ }
+ }
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_Transceive
+ *
+ * Description This function is used to
+ * 1. Send the raw data received from application after
+ *computing LRC
+ * 2. Receive the response data from ESE, decode, process
+ *and
+ * store the data.
+ * 3. Get the final complete data and sent back to application
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data* pCmd,
+ phNxpEse_data* pRsp) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ ESESTATUS wStatus = ESESTATUS_FAILED;
+ phNxpEse_data pRes;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ if ((NULL == pCmd) || (NULL == pRsp) ||
+ (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
+ PH_NXP_ESE_PROTO_7816_IDLE))
+ return status;
+ phNxpEse_memset(&pRes, 0x00, sizeof(phNxpEse_data));
+ /* Updating the transceive information to the protocol stack */
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = pCmd->p_data;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.totalDataLen =
+ pCmd->len;
+ ALOGD_IF(ese_debug_enabled, "Transceive data ptr 0x%p len:%d", pCmd->p_data,
+ pCmd->len);
+ status = phNxpEseProto7816_SetFirstIframeContxt();
+ status = TransceiveProcess();
+ if (ESESTATUS_FAILED == status || ESESTATUS_TRANSCEIVE_FAILED == status) {
+ /* ESE hard reset to be done */
+ ALOGE("Transceive failed, hard reset to proceed");
+ wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
+ if (ESESTATUS_SUCCESS == wStatus) {
+ ALOGD_IF(ese_debug_enabled,
+ "%s Data successfully received at 7816, packaging to "
+ "send upper layers: DataLen = %d",
+ __FUNCTION__, pRes.len);
+ }
+ } else {
+ // fetch the data info and report to upper layer.
+ wStatus = phNxpEse_GetData(&pRes.len, &pRes.p_data);
+ if (ESESTATUS_SUCCESS == wStatus) {
+ ALOGD_IF(ese_debug_enabled,
+ "%s Data successfully received at 7816, packaging to "
+ "send upper layers: DataLen = %d",
+ __FUNCTION__, pRes.len);
+ } else
+ status = ESESTATUS_FAILED;
+ }
+
+ /* Copy the data to be read by the upper layer via transceive api */
+ pRsp->len = pRes.len;
+ pRsp->p_data = pRes.p_data;
+
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ phNxpEseProto7816_3_Var.reset_type = RESET_TYPE_NONE;
+ ALOGD_IF(ese_debug_enabled, "Exit %s Status 0x%x", __FUNCTION__, status);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_RSync
+ *
+ * Description This function is used to send the RSync command
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_RSync(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
+ /* send the end of session s-frame */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ RESYNCH_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_RSYNC;
+ status = TransceiveProcess();
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_HardReset
+ *
+ * Description This function is used to send the spi hard reset command
+ *
+ * Returns On success return TRUE or else FALSE.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_HardReset(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
+ /* send the hard reset s-frame command*/
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ HARD_RESET_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_HRD_RST;
+ status = TransceiveProcess();
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ResetProtoParams
+ *
+ * Description This function is used to reset the 7816 protocol stack
+ *instance
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEseProto7816_ResetProtoParams(void) {
+ unsigned long int tmpWTXCountlimit = PH_PROTO_7816_VALUE_ZERO;
+ unsigned long int tmpRNACKCountlimit = PH_PROTO_7816_VALUE_ZERO;
+ unsigned long int tmpWtxNtfCountlimit = PH_PROTO_7816_VALUE_ZERO;
+ tmpWTXCountlimit = phNxpEseProto7816_3_Var.wtx_counter_limit;
+ tmpRNACKCountlimit = phNxpEseProto7816_3_Var.rnack_retry_limit;
+ tmpWtxNtfCountlimit = phNxpEseProto7816_3_Var.wtx_ntf_limit;
+ phNxpEse_memset(&phNxpEseProto7816_3_Var, PH_PROTO_7816_VALUE_ZERO,
+ sizeof(phNxpEseProto7816_t));
+ phNxpEseProto7816_3_Var.wtx_counter_limit = tmpWTXCountlimit;
+ phNxpEseProto7816_3_Var.rnack_retry_limit = tmpRNACKCountlimit;
+ phNxpEseProto7816_3_Var.wtx_ntf_limit = tmpWtxNtfCountlimit;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = IDLE_STATE;
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdFrameType = INVALID;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = INVALID;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
+ IFSC_SIZE_SEND;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.defaultDataLenIFSC =
+ IFSC_SIZE_SEND;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS =
+ IFSC_SIZE_SEND;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.p_data = NULL;
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.FrameType = INVALID;
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.maxDataLenIFSC =
+ IFSC_SIZE_SEND;
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.defaultDataLenIFSC =
+ IFSC_SIZE_SEND;
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.currentDataLenIFS =
+ IFSC_SIZE_SEND;
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.p_data = NULL;
+ /* Initialized with sequence number of the last I-frame sent */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.seqNo =
+ PH_PROTO_7816_VALUE_ONE;
+ /* Initialized with sequence number of the last I-frame received */
+ phNxpEseProto7816_3_Var.phNxpEseRx_Cntx.lastRcvdIframeInfo.seqNo =
+ PH_PROTO_7816_VALUE_ONE;
+ /* Initialized with sequence number of the last I-frame received */
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.IframeInfo.seqNo =
+ PH_PROTO_7816_VALUE_ONE;
+ phNxpEseProto7816_3_Var.recoveryCounter = PH_PROTO_7816_VALUE_ZERO;
+ phNxpEseProto7816_3_Var.timeoutCounter = PH_PROTO_7816_VALUE_ZERO;
+ phNxpEseProto7816_3_Var.wtx_counter = PH_PROTO_7816_VALUE_ZERO;
+ /* This update is helpful in-case a R-NACK is transmitted from the MW */
+ phNxpEseProto7816_3_Var.lastSentNonErrorframeType = UNKNOWN;
+ phNxpEseProto7816_3_Var.rnack_retry_counter = PH_PROTO_7816_VALUE_ZERO;
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_Reset
+ *
+ * Description This function is used to reset the 7816 protocol stack
+ *instance
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_Reset(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ /* Resetting host protocol instance */
+ phNxpEseProto7816_ResetProtoParams();
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ status = phNxpEseProto7816_HardReset();
+ if (status == ESESTATUS_SUCCESS) {
+ /* Updating the ATR information(IFS,..) to 7816 stack */
+ phNxpEse_data atrRsp;
+ phNxpEseProto7816_getAtr(&atrRsp);
+ phNxpEse_free(atrRsp.p_data);
+ }
+ } else {
+ /* Resynchronising ESE protocol instance */
+ status = phNxpEseProto7816_RSync();
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_Open
+ *
+ * Description This function is used to open the 7816 protocol stack
+ *instance
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ status = phNxpEseProto7816_ResetProtoParams();
+ ALOGD_IF(ese_debug_enabled, "%s: First open completed, Congratulations",
+ __FUNCTION__);
+ /* Update WTX max. limit */
+ phNxpEseProto7816_3_Var.wtx_counter_limit = initParam.wtx_counter_limit;
+ phNxpEseProto7816_3_Var.rnack_retry_limit = initParam.rnack_retry_limit;
+ phNxpEseProto7816_3_Var.wtx_ntf_limit = initParam.wtx_ntf_limit;
+ if (initParam.interfaceReset) /* Do interface reset */
+ {
+ status = phNxpEseProto7816_IntfReset(initParam.pSecureTimerParams);
+ if (ESESTATUS_SUCCESS == status) {
+ phNxpEse_memcpy(initParam.pSecureTimerParams,
+ &phNxpEseProto7816_3_Var.secureTimerParams,
+ sizeof(phNxpEseProto7816SecureTimer_t));
+ }
+ } else /* Initialisation condition to achieve usecases like JCOP download */
+ {
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ status = phNxpEseProto7816_HardReset();
+ /* Updating the ATR information (Eg: IFS,..) to 7816 stack */
+ if (status == ESESTATUS_SUCCESS) {
+ phNxpEse_data atrRsp;
+ phNxpEseProto7816_getAtr(&atrRsp);
+ phNxpEse_free(atrRsp.p_data);
+ }
+ } else {
+ status = phNxpEseProto7816_RSync();
+ }
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_Close
+ *
+ * Description This function is used to close the 7816 protocol stack
+ *instance
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_Close(
+ phNxpEseProto7816SecureTimer_t* pSecureTimerParams) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState !=
+ PH_NXP_ESE_PROTO_7816_IDLE)
+ return status;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_DEINIT;
+ phNxpEseProto7816_3_Var.recoveryCounter = 0;
+ phNxpEseProto7816_3_Var.wtx_counter = 0;
+ /* send the end of session s-frame */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ PROP_END_APDU_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len =
+ PH_PROTO_7816_VALUE_ZERO;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState = SEND_S_EOS;
+ status = TransceiveProcess();
+ if (ESESTATUS_SUCCESS != status) {
+ /* reset all the structures */
+ ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
+ if (status == ESESTATUS_TRANSCEIVE_FAILED &&
+ phNxpEseProto7816_3_Var.atrInfo.len > PH_PROTO_7816_VALUE_ZERO) {
+ if (phNxpEseProto7816_3_Var.atrInfo
+ .vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN - 1] <
+ PH_SE_OS_VERSION_10) {
+ ALOGD_IF(ese_debug_enabled, "%s shall trigger recovery", __FUNCTION__);
+ status = ESESTATUS_RESPONSE_TIMEOUT;
+ }
+ }
+ }
+ phNxpEse_memcpy(pSecureTimerParams,
+ &phNxpEseProto7816_3_Var.secureTimerParams,
+ sizeof(phNxpEseProto7816SecureTimer_t));
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_CloseAllSessions
+ *
+ * Description This function is used to close the 7816 protocol stack
+ *instance
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_CloseAllSessions(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ /*Note:- Below OS version check using ATR shall
+ * be removed while integrating with TEE/REE as ATR
+ * information is not available in REE case*/
+
+ if (phNxpEseProto7816_3_Var.atrInfo.vendorID[PH_PROTO_ATR_RSP_VENDOR_ID_LEN -
+ 1] >= PH_SE_OS_VERSION_10) {
+ uint8_t* buffer = (uint8_t*)phNxpEse_memalloc(sizeof(uint8_t));
+ if (buffer != NULL) {
+ buffer[PH_PROTO_7816_VALUE_ZERO] = PH_PROTO_CLOSE_ALL_SESSION_INF;
+ /* send the end of session s-frame */
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ PROP_END_APDU_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.p_data = buffer;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.len =
+ PH_PROTO_CLOSE_ALL_SESSION_LEN;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_EOS;
+ status = TransceiveProcess();
+ if (ESESTATUS_FAILED == status) {
+ /* reset all the structures */
+ ALOGD_IF(ese_debug_enabled, "%s EndOfSession failed ", __FUNCTION__);
+ }
+ phNxpEse_free(buffer);
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled, "%s Function not supported ", __FUNCTION__);
+ status = ESESTATUS_SUCCESS;
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_IntfReset
+ *
+ * Description This function is used to reset just the current interface
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_IntfReset(
+ phNxpEseProto7816SecureTimer_t* pSecureTimerParam) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType =
+ INTF_RESET_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_INTF_RST;
+ status = TransceiveProcess();
+ if (ESESTATUS_FAILED == status) {
+ /* reset all the structures */
+ ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
+ }
+ phNxpEse_memcpy(pSecureTimerParam, &phNxpEseProto7816_3_Var.secureTimerParams,
+ sizeof(phNxpEseProto7816SecureTimer_t));
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SetIfs
+ *
+ * Description This function is used to set IFSD value to card
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_SetIfs(uint16_t IFS_Size) {
+ // phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC =
+ // IFSC_Size;
+ ESESTATUS status = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ /* IFSD > IFSC not allowed, card will reject by R-NACK so not sending */
+ if (IFS_Size >
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC) {
+ phNxpEseProto7816_3_Var.currentIFSDSize =
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.maxDataLenIFSC;
+ /* IFSD is greater than IFSC , set max IFSC as IFSD*/
+ ALOGD_IF(ese_debug_enabled,
+ "%s : IFSD greater than IFSC , set max IFSC as IFSD ",
+ __FUNCTION__);
+ } else {
+ phNxpEseProto7816_3_Var.currentIFSDSize = IFS_Size;
+ }
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = IFS_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_IFS_ADJ;
+ status = TransceiveProcess();
+ if (ESESTATUS_FAILED == status) {
+ /* reset all the structures */
+ ALOGE("%s TransceiveProcess failed ", __FUNCTION__);
+ }
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_GetIfs
+ *
+ * Description This function is used to get current IFS adjusted value wrt
+ *card
+ *
+ * Returns On success return true or else false.
+ *
+ ******************************************************************************/
+uint16_t phNxpEseProto7816_GetIfs(void) {
+ ALOGD_IF(
+ ese_debug_enabled, "Enter %s current IFSC = %d", __FUNCTION__,
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo.currentDataLenIFS);
+ return phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.IframeInfo
+ .currentDataLenIFS;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_GetOsMode
+ *
+ * Description This function is used to get current OS Mode
+ *
+ * Returns 0x01 : JCOP_MODE
+ * 0x02 : OSU_MODE
+ *
+ ******************************************************************************/
+phNxpEseProto7816_OsType_t phNxpEseProto7816_GetOsMode(void) {
+ phNxpEseProto7816_OsType_t mode = UNKNOWN_MODE;
+ if (GET_CHIP_OS_VERSION() >= OS_VERSION_5_2_2) {
+ if (phNxpEseProto7816_3_Var.extndAtrInfo.osType == MODE_JCOP) {
+ ALOGD_IF(ese_debug_enabled, "Enter %s OS Mode = %s", __FUNCTION__,
+ "JCOP Mode");
+ mode = JCOP_MODE;
+ } else if (phNxpEseProto7816_3_Var.extndAtrInfo.osType == MODE_OSU) {
+ ALOGD_IF(ese_debug_enabled, "Enter %s OS Mode = %s", __FUNCTION__,
+ "OSU Mode");
+ mode = OSU_MODE;
+ } else {
+ ALOGD_IF(ese_debug_enabled, "Enter %s OS Mode = %s", __FUNCTION__,
+ "UNKNOWN Mode");
+ mode = UNKNOWN_MODE;
+ }
+ } else {
+ ALOGE("%s function not supported", __FUNCTION__);
+ }
+ return mode;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_getAtr
+ *
+ * Description This function is used to get the ATR data from ESE
+ *
+ * Returns On success return true or else false
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_getAtr(phNxpEse_data* pATRRsp) {
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE;
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.FrameType = SFRAME;
+
+ phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx.SframeInfo.sFrameType = ATR_REQ;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_nextTransceiveState =
+ SEND_S_ATR_REQ;
+ status = TransceiveProcess();
+ if (ESESTATUS_FAILED == status) {
+ /* reset all the structures */
+ ALOGD_IF(ese_debug_enabled, "%s TransceiveProcess failed ", __FUNCTION__);
+ }
+
+ status = phNxpEse_GetData(&(pATRRsp->len), &(pATRRsp->p_data));
+ if (ESESTATUS_SUCCESS == status) {
+ ALOGD_IF(ese_debug_enabled,
+ "%s Data successfully received at 7816, packaging to "
+ "send upper layers: DataLen = %d",
+ __FUNCTION__, pATRRsp->len);
+ } else
+ status = ESESTATUS_FAILED;
+ phNxpEseProto7816_3_Var.phNxpEseProto7816_CurrentState =
+ PH_NXP_ESE_PROTO_7816_IDLE;
+ ALOGD_IF(ese_debug_enabled, "Exit %s ", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_SetEndPoint
+ *
+ * Description This function is used to set end point protocol context
+ *
+ * Returns Always return TRUE (1).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (uEndPoint == END_POINT_ESE || uEndPoint == END_POINT_EUICC) {
+ phNxpEseProto7816_3_Var = phNxpEseProto7816_ptr[uEndPoint];
+ status = ESESTATUS_SUCCESS;
+ } else {
+ /*Do nothing return fail*/
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ResetEndPoint
+ *
+ * Description This function is used to set end point protocol context
+ *
+ * Returns Always return TRUE (1).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (uEndPoint == END_POINT_ESE || uEndPoint == END_POINT_EUICC) {
+ phNxpEseProto7816_ptr[uEndPoint] = phNxpEseProto7816_3_Var;
+ status = ESESTATUS_SUCCESS;
+ } else {
+ /*Do nothing return fail*/
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseProto7816_ResendLastSFrameReq
+ *
+ * Description This function is used to Resend S-Frame on receiving
+ * non S-Frame response
+ *
+ * Returns If last sent Frame is S-Frame
+ * return TRUE(S-Frame) otherwise FALSE(Non-S-Frame).
+ *
+ ******************************************************************************/
+static bool phNxpEseProto7816_ResendLastSFrameReq(void) {
+ bool isLastSFrameReq = false;
+ if (phNxpEseProto7816_3_Var.lastSentNonErrorframeType == SFRAME &&
+ WTX_RSP !=
+ phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx.SframeInfo.sFrameType) {
+ ALOGD_IF(ese_debug_enabled,
+ "%s Unexpected Frame, re-transmitting the previous S-frame",
+ __FUNCTION__);
+ phNxpEse_memcpy(&phNxpEseProto7816_3_Var.phNxpEseNextTx_Cntx,
+ &phNxpEseProto7816_3_Var.phNxpEseLastTx_Cntx,
+ sizeof(phNxpEseProto7816_NextTx_Info_t));
+ isLastSFrameReq = true;
+ }
+ return isLastSFrameReq;
+}
+
+/** @} */
diff --git a/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h
new file mode 100755
index 0000000..8a22daa
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEseProto7816_3.h
@@ -0,0 +1,623 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef _PHNXPESEPROTO7816_3_H_
+#define _PHNXPESEPROTO7816_3_H_
+#include <ese_config.h>
+#include <phNxpEseDataMgr.h>
+#include <phNxpEseFeatures.h>
+#include <phNxpEse_Internal.h>
+
+/**
+ * \addtogroup ISO7816-3_protocol_lib
+ * \brief 7816-3 PROTOCOL STACK
+ * @{ */
+
+/********************* Definitions and structures *****************************/
+
+/*!
+ * \brief S-Frame types used in 7816-3 protocol stack
+ */
+typedef enum sFrameTypes {
+ RESYNCH_REQ = 0x00, /*!< Re-synchronisation request between host and ESE */
+ RESYNCH_RSP = 0x20, /*!< Re-synchronisation response between host and ESE */
+ IFS_REQ = 0x01, /*!< IFSC size request */
+ IFS_RES = 0x21, /*!< IFSC size response */
+ ABORT_REQ = 0x02, /*!< Abort request */
+ ABORT_RES = 0x22, /*!< Abort response */
+ WTX_REQ = 0x03, /*!< WTX request */
+ WTX_RSP = 0x23, /*!< WTX response */
+ INTF_RESET_REQ = 0x04, /*!< Interface reset request */
+ INTF_RESET_RSP = 0x24, /*!< Interface reset response */
+ PROP_END_APDU_REQ = 0x05, /*!< Proprietary Enf of APDU request */
+ PROP_END_APDU_RSP = 0x25, /*!< Proprietary Enf of APDU response */
+ HARD_RESET_REQ = 0x06, /*!< Chip reset request */
+ HARD_RESET_RSP = 0x26, /*!< Chip reset request */
+ ATR_REQ = 0x07, /*!< ATR request */
+ ATR_RSP = 0x27, /*!< ATR response */
+ INVALID_REQ_RES /*!< Invalid request */
+} sFrameTypes_t;
+
+/*!
+ * \brief R-Frame types used in 7816-3 protocol stack
+ */
+typedef enum rFrameTypes {
+ RACK = 0x01, /*!< R-frame Acknowledgement frame indicator */
+ RNACK = 0x02 /*!< R-frame Negative-Acknowledgement frame indicator */
+} rFrameTypes_t;
+
+/*!
+ * \brief R-Frame error types used 7816-3 protocol stack
+ */
+typedef enum rFrameErrorTypes {
+ NO_ERROR, /*!< R-frame received with success */
+ PARITY_ERROR, /*!< R-frame received with parity error */
+ OTHER_ERROR, /*!< R-frame received with Other error */
+ SOF_MISSED_ERROR, /*!< R-frame received with frame missing error */
+ UNDEFINED_ERROR /*!< R-frame received with some undefined error */
+} rFrameErrorTypes_t;
+
+/*!
+ * \brief Frame types used in 7816-3 protocol stack
+ */
+typedef enum phNxpEseProto7816_FrameTypes {
+ IFRAME, /*!< Frame type: I-frame */
+ SFRAME, /*!< Frame type: S-frame */
+ RFRAME, /*!< Frame type: R-frame */
+ INVALID, /*!< Frame type: Invalid */
+ UNKNOWN /*!< Frame type: Unknown */
+} phNxpEseProto7816_FrameTypes_t;
+
+/*!
+ * \brief 7816-3 protocol stack states
+ */
+typedef enum phNxpEseProto7816_State {
+ PH_NXP_ESE_PROTO_7816_IDLE, /*!< 7816-3 protocol state: IDLE */
+ PH_NXP_ESE_PROTO_7816_TRANSCEIVE, /*!< 7816-3 protocol state: TRANSCEIVE going
+ on */
+ PH_NXP_ESE_PROTO_7816_DEINIT /*!< 7816-3 protocol state: DeInit going on */
+} phNxpEseProto7816_State_t;
+
+/*!
+ * \brief 7816-3 protocol transceive states
+ */
+typedef enum phNxpEseProto7816_TransceiveStates {
+ IDLE_STATE, /*!< 7816-3 protocol transceive state: IDLE */
+ SEND_IFRAME, /*!< 7816-3 protocol transceive state: I-frame to be sent */
+ SEND_R_NACK, /*!< 7816-3 protocol transceive state: R-NACK frame to be sent */
+ SEND_R_ACK, /*!< 7816-3 protocol transceive state: R-ACK frame to be sent */
+ SEND_S_RSYNC, /*!< 7816-3 protocol transceive state: S-frame
+ re-synchronisation command to be sent */
+ SEND_S_INTF_RST, /*!< 7816-3 protocol transceive state: S-frame interface
+ reset command to be sent */
+ SEND_S_EOS, /*!< 7816-3 protocol transceive state: S-frame end of session
+ command to be sent */
+ SEND_S_HRD_RST, /*!< 7816-3 protocol transceive state: S-frame
+ chip/hard reset command to be sent */
+ SEND_S_WTX_REQ, /*!< 7816-3 protocol transceive state: S-frame WTX command to
+ be sent */
+ SEND_S_WTX_RSP, /*!< 7816-3 protocol transceive state: S-frame WTX response to
+ be sent */
+ SEND_S_IFS_ADJ, /*!< 7816-3 protocol transceive state: S-frame IFS adjustment
+ */
+ SEND_S_ATR_REQ, /*!< 7816-3 protocol transceive state: S-frame ATR request */
+} phNxpEseProto7816_TransceiveStates_t;
+
+/*!
+ * \brief I-frame information structure for ISO 7816-3
+ *
+ * This structure holds the information of I-frame used for sending
+ * and receiving the frame packet.
+ *
+ */
+typedef struct iFrameInfo {
+ bool isChained; /*!< I-frame: Indicates if more frames to follow in the same
+ data packet or not */
+ uint8_t* p_data; /*!< I-frame: Actual data (Information field (INF)) */
+
+ uint8_t seqNo; /*!< I-frame: Sequence number of the I-frame */
+
+ uint32_t maxDataLenIFSC; /*!< I-frame: Maximum data length to be allowed in a
+ single I-frame */
+ uint32_t defaultDataLenIFSC; /*!< I-frame: Maximum data length to be allowed
+ in a single I-frame */
+ uint32_t currentDataLenIFS; /*!< I-frame: Current data length agreed
+ between PCD and Card to be allowed in a
+ single I-frame */
+
+ uint32_t dataOffset; /*!< I-frame: Offset to the actual data(INF) for the
+ current frame of the packet */
+ uint32_t totalDataLen; /*!< I-frame: Total data left in the packet, used to
+ set the chained flag/calculating offset */
+ uint32_t sendDataLen; /*!< I-frame: the length of the I-frame actual data */
+} iFrameInfo_t;
+
+/*!
+ * \brief S-frame information structure for ISO 7816-3
+ *
+ * This structure holds the information of S-frame used for sending
+ * and receiving the frame packet.
+ *
+ */
+typedef struct sFrameInfo {
+ sFrameTypes_t sFrameType; /*!< S-frame: Type of S-frame cmd/rsp */
+ uint8_t* p_data; /*!< S-frame: Actual data (Information field (INF)) */
+ uint8_t len; /*!< S-frame: the length of the I-frame actual data */
+} sFrameInfo_t;
+
+/*!
+ * \brief R-frame information structure for ISO 7816-3
+ *
+ * This structure holds the information of R-frame used for sending
+ * and receiving the frame packet.
+ *
+ */
+typedef struct rFrameInfo {
+ uint8_t seqNo; /*!< R-frame: Sequence number of the expected I-frame */
+ rFrameErrorTypes_t errCode; /*!< R-frame: Error type */
+} rFrameInfo_t;
+
+/*!
+ * \brief ATRInfo: ISO7816 ATR Information bytes
+ *
+ * This structure holds ATR information bytes
+ *
+ */
+typedef struct phNxpEseProto7816_ATR_Info {
+ uint8_t len; /*!< ATR: ATR length in bytes */
+ uint8_t vendorID[5]; /*!< ATR: VendorID according to ISO7816-5 */
+ uint8_t dll_IC; /*!< ATR: Data Link Layer - Interface Character */
+ uint8_t bgt[2]; /*!< ATR: Minimum guard time in milliseconds for
+ T=1 blocks sent in opposite directions */
+ uint8_t
+ bwt[2]; /*!< ATR: Maximum allowed command processing
+ time in milliseconds before card has sent either
+ command response or S(WTX) requesting processing time extension */
+ uint8_t maxFreq[2]; /*!< ATR: Max supported clock frequency in kHz */
+ uint8_t checksum; /*!< ATR: Checksum (0 = LRC / 1 = CRC) */
+ uint8_t defaultIFSC; /*!< ATR: Default IFS size */
+ 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
+ */
+} phNxpEseProto7816_ATR_Info_t;
+
+typedef struct phNxpEseProto7816_ATR_Info2 {
+ uint8_t channelNo; /*!< ATR: Current ongoing channel no */
+ uint8_t osType; /*!< ATR: Indicates OS Type
+ JCOP_OS = 0x01
+ UPDATER_OS = 0x02 */
+} phNxpEseProto7816_ATR_Info2_t;
+
+/*!
+ * \brief Next/Last Tx information structure holding transceive data
+ *
+ * This structure holds the information of the next/last sent
+ * I-frame/R-frame/S-frame depending on the frame type
+ *
+ */
+typedef struct phNxpEseProto7816_NextTx_Info {
+ iFrameInfo_t
+ IframeInfo; /*!< Information of the I-frame to be send next or the last
+ sent I-frame depending on the frame type */
+ rFrameInfo_t
+ RframeInfo; /*!< Information of the R-frame to be send next or the last
+ sent R-frame depending on the frame type */
+ sFrameInfo_t
+ SframeInfo; /*!< Information of the S-frame to be send next or the last
+ sent S-frame depending on the frame type */
+ phNxpEseProto7816_FrameTypes_t
+ FrameType; /*!< Frame (I/R/S frames) type to be sent next */
+} phNxpEseProto7816_NextTx_Info_t;
+
+/*!
+ * \brief Last sent Tx ransceive data
+ *
+ * This structure holds the information of the last sent
+ * I-frame/R-frame/S-frame
+ *
+ */
+typedef phNxpEseProto7816_NextTx_Info_t phNxpEseProto7816_LastTx_Info_t;
+
+/*!
+ * \brief Last Rx information structure holding transceive data
+ *
+ * This structure holds the information of the next/last sent
+ * I-frame/R-frame/S-frame
+ *
+ */
+typedef struct phNxpEseRx_Cntx {
+ iFrameInfo_t lastRcvdIframeInfo; /*!< I-frame: Last received frame */
+ rFrameInfo_t lastRcvdRframeInfo; /*!< R-frame: Last received frame */
+ sFrameInfo_t lastRcvdSframeInfo; /*!< S-frame: Last received frame */
+ phNxpEseProto7816_FrameTypes_t
+ lastRcvdFrameType; /*!< Last received frame type */
+} phNxpEseRx_Cntx_t;
+
+/*!
+ * \brief Proprietery: Secure timer value updates
+ *
+ * This structure holds the secure timer value
+ *
+ */
+typedef struct phNxpEseProto7816SecureTimer {
+ unsigned int secureTimer1;
+ unsigned int secureTimer2;
+ unsigned int secureTimer3;
+} phNxpEseProto7816SecureTimer_t;
+
+/*!
+ * \brief structure to hold the interface reset parameters
+ * secure timer(only for PN8xT products) and atr info.
+ *
+ */
+typedef struct phNxpEseProto7816_IntfResetParams {
+ phNxpEseProto7816SecureTimer_t* pSecureTimerParam;
+ phNxpEse_data* pAtrData;
+} phNxpEseProto7816_IntfResetParams_t;
+/*!
+ * \brief 7816-3 protocol stack context structure
+ *
+ * This structure holds the complete information of the
+ * 7816-3 protocol stack context
+ *
+ */
+typedef struct phNxpEseProto7816 {
+ phNxpEseProto7816_LastTx_Info_t
+ phNxpEseLastTx_Cntx; /*!< Last transmitted frame information */
+ phNxpEseProto7816_NextTx_Info_t
+ phNxpEseNextTx_Cntx; /*!< Next frame to be transmitted */
+ phNxpEseRx_Cntx_t phNxpEseRx_Cntx; /*!< Last received frame information */
+ phNxpEseProto7816_TransceiveStates_t
+ phNxpEseProto7816_nextTransceiveState; /*!< Next Transceive state. It
+ determines the next
+ action to be done from host */
+ phNxpEseProto7816_State_t
+ phNxpEseProto7816_CurrentState; /*!< Current protocol stack state */
+ uint8_t recoveryCounter; /*!< Keeps track of number of error recovery done.
+ Stack exits after it reaches max. count */
+ unsigned long int wtx_counter_limit; /*!< Max. WTX counter limit */
+ unsigned long int wtx_counter; /*!< WTX count tracker */
+ uint8_t timeoutCounter; /*!< Keeps track of number of timeout happened. Stack
+ exits after it reaches max. count */
+ phNxpEseProto7816_FrameTypes_t
+ lastSentNonErrorframeType; /*!< Copy of the last sent non-error frame
+ type: R-ACK, S-frame, I-frame */
+ unsigned long int rnack_retry_limit;
+ unsigned long int rnack_retry_counter;
+ unsigned long int
+ wtx_ntf_limit; /*!< Wtx count interval to notify service registered*/
+ phNxpEseProto7816SecureTimer_t secureTimerParams;
+ unsigned long int reset_type;
+ uint32_t currentIFSDSize;
+ phNxpEseProto7816_ATR_Info_t atrInfo;
+ phNxpEseProto7816_ATR_Info2_t extndAtrInfo;
+} phNxpEseProto7816_t;
+
+/*!
+ * \brief 7816-3 protocol stack init params
+ *
+ * This structure holds the parameters to be passed to open 7816-3 protocl stack
+ *instance
+ *
+ */
+typedef struct phNxpEseProto7816InitParam {
+ unsigned long int wtx_counter_limit; /*!< WTX count limit */
+ bool interfaceReset; /*!< INTF reset required or not>*/
+ unsigned long int rnack_retry_limit;
+ phNxpEseProto7816SecureTimer_t*
+ pSecureTimerParams; /*!< Secure timer value updated here >*/
+ unsigned long int
+ wtx_ntf_limit; /*!< Wtx count interval to notify service registered*/
+} phNxpEseProto7816InitParam_t;
+
+/*!
+ * \brief 7816-3 protocol PCB bit level structure
+ *
+ * This structure holds the bit level information of PCB byte
+ * as per 7816-3 protocol
+ *
+ */
+typedef struct phNxpEseProto7816_PCB_bits {
+ uint8_t lsb : 1; /*!< PCB: lsb */
+ uint8_t bit2 : 1; /*!< PCB: bit2 */
+ uint8_t bit3 : 1; /*!< PCB: bit3 */
+ uint8_t bit4 : 1; /*!< PCB: bit4 */
+ uint8_t bit5 : 1; /*!< PCB: bit5 */
+ uint8_t bit6 : 1; /*!< PCB: bit6 */
+ uint8_t bit7 : 1; /*!< PCB: bit7 */
+ uint8_t msb : 1; /*!< PCB: msb */
+} phNxpEseProto7816_PCB_bits_t;
+
+/*!
+ * \brief Max. size of the frame that can be sent
+ */
+#define IFSC_SIZE_SEND 254
+/*!
+ * \brief Delay to be used before sending the next frame, after error reported
+ * by ESE
+ */
+#define DELAY_ERROR_RECOVERY_1_MS 1000
+
+#define GET_DELAY_ERROR_RECOVERY() \
+ ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) \
+ ? (10 * DELAY_ERROR_RECOVERY_1_MS) \
+ : (3.5 * DELAY_ERROR_RECOVERY_1_MS))
+/*!
+ * \brief 7816-3 protocol frame
+ * header length
+ */
+#define PH_PROTO_7816_HEADER_LEN 0x03
+/*!
+ * \brief 7816-3 protocol ext.frame header length
+ */
+#define PH_PROTO_7816_EXT_HEADER_LEN 0x05
+/*!
+ * \brief 7816-3 protocol frame CRC length
+ */
+#define PH_PROTO_7816_CRC_LEN 0x01
+/*!
+ * \brief 7816-3 Chaining flag bit for masking
+ */
+#define PH_PROTO_7816_CHAINING 0x20
+/*!
+ * \brief 7816-3 PCB byte offset
+ */
+#define PH_PROPTO_7816_PCB_OFFSET 0x01
+/*!
+ * \brief 7816-3 frame length offset
+ */
+#define PH_PROPTO_7816_FRAME_LENGTH_OFFSET 0x02
+/*!
+ * \brief 7816-3 S-frame timer 1
+ */
+#define PH_PROPTO_7816_SFRAME_TIMER1 0xF1
+/*!
+ * \brief 7816-3 S-frame timer 2
+ */
+#define PH_PROPTO_7816_SFRAME_TIMER2 0xF2
+/*!
+ * \brief 7816-3 S-frame timer 3
+ */
+#define PH_PROPTO_7816_SFRAME_TIMER3 0xF3
+
+/*!
+ * \brief 7816-3 S-block request command mask
+ */
+#define PH_PROTO_7816_S_BLOCK_REQ 0xC0
+/*!
+ * \brief 7816-3 S-block response mask
+ */
+#define PH_PROTO_7816_S_BLOCK_RSP 0xE0
+/*!
+ * \brief 7816-3 S-block reset command mask
+ */
+#define PH_PROTO_7816_S_RESET 0x04
+/*!
+ * \brief 7816-3 S-block End of APDU cmd mask
+ */
+#define PH_PROTO_7816_S_END_OF_APDU 0x05
+/*!
+ * \brief 7816-3 S-block WTX mask
+ */
+#define PH_PROTO_7816_S_WTX 0x03
+/*!
+ * \brief 7816-3 S-block re-sync mask
+ */
+#define PH_PROTO_7816_S_RESYNCH 0x00
+/*!
+ * \brief 7816-3 S-block hard reset cmd mask
+ */
+#define PH_PROTO_7816_S_HRD_RST_CMD 0x06
+/*!
+ * \brief 7816-3 protocol max. error retry counter
+ */
+#define PH_PROTO_7816_FRAME_RETRY 01
+/*!
+ * \brief 7816-3 protocol max. error retry counter based on OS version
+ */
+#define GET_FRAME_RETRY_COUNT() \
+ ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) \
+ ? (3 * PH_PROTO_7816_FRAME_RETRY) \
+ : (10 * PH_PROTO_7816_FRAME_RETRY))
+
+/*!
+ * \brief 7816-3 protocol max. WTX default count
+ */
+#define PH_PROTO_WTX_DEFAULT_COUNT 500
+/*!
+ * \brief 7816-3 protocol max. timeout retry count
+ */
+#define PH_PROTO_7816_TIMEOUT_RETRY_COUNT 1
+/*!
+ * \brief 7816-3 to represent magic number zero
+ */
+#define PH_PROTO_7816_VALUE_ZERO 0x00
+/*!
+ * \brief 7816-3 to represent magic number one
+ */
+#define PH_PROTO_7816_VALUE_ONE 0x01
+/*!
+ * \brief 7816-3 for max retry for CRC error
+ */
+#define MAX_RNACK_RETRY_LIMIT 0x02
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define RESET_TYPE_NONE 0x00
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define EXTENDED_FRAME_MARKER 0xFF
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define PH_PROTO_CLOSE_ALL_SESSION_INF 0x01
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define PH_PROTO_CLOSE_ALL_SESSION_LEN 0x01
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define PH_PROTO_ATR_RSP_VENDOR_ID_LEN 0x05
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define PH_SE_OS_VERSION_10 0x10
+/*!
+ * \brief APIs exposed from the 7816-3 protocol layer
+ */
+#define PH_SE_OS_VERSION_11 0x11
+/*!
+ * \brief OS version on SE for SN220
+ */
+#define PH_SE_OS_VERSION_20 0x20
+/*!
+ * \brief Default wait extension notification interval
+ */
+#define PH_DEFAULT_WTX_NTF_LIMIT 0x03
+/*!
+ * \delay for hard reset response
+ */
+#define HARD_RESET_RES_DELAY 4000
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to reset just the current interface
+ *
+ * \param[in] secureTimerParams - secure timer instance
+ *
+ */
+ESESTATUS phNxpEseProto7816_IntfReset(
+ phNxpEseProto7816SecureTimer_t* secureTimerParams);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to close the 7816 protocol stack instance
+ *
+ * \param[in] secureTimerParams - secure timer instance
+ *
+ */
+ESESTATUS phNxpEseProto7816_Close(
+ phNxpEseProto7816SecureTimer_t* secureTimerParams);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to open the 7816 protocol stack instance
+ *
+ * \param[in] initParam: Initialization params
+ *
+ */
+ESESTATUS phNxpEseProto7816_Open(phNxpEseProto7816InitParam_t initParam);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to
+ * 1. Send the raw data received from application after
+ *computing LRC
+ * 2. Receive the response data from ESE, decode, process
+ *and
+ * store the data.
+ * 3. Get the final complete data and sent back to application
+ *
+ * \param[in] pCmd: Command to ESE
+ * \param[out] pRsp: Response from ESE
+ *
+ *
+ */
+ESESTATUS phNxpEseProto7816_Transceive(phNxpEse_data* pCmd,
+ phNxpEse_data* pRsp);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to reset the 7816 protocol stack instance
+ *
+ *
+ *
+ */
+ESESTATUS phNxpEseProto7816_Reset(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to set the max T=1 data send size
+ *
+ * \param[in] IFS_Size: Max. size of the I-frame
+ *
+ */
+ESESTATUS phNxpEseProto7816_SetIfs(uint16_t IFS_Size);
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to set the endpoint
+ *
+ * \param[in] uEndPoint: END_POINT_ESE = 0 (eSE services), END_POINT_EUICC
+ * =1(UICC services)
+ *
+ */
+ESESTATUS phNxpEseProto7816_SetEndPoint(uint8_t uEndPoint);
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to reset the endpoint
+ *
+ * \param[in] uEndPoint: END_POINT_ESE = 0 (eSE services), END_POINT_EUICC
+ * =1(UICC services)
+ *
+ */
+ESESTATUS phNxpEseProto7816_ResetEndPoint(uint8_t uEndPoint);
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to get ATR bytes for the application
+ *
+ * \param[out] pATRRsp: Response ATR bytes from ESE
+ *
+ */
+ESESTATUS phNxpEseProto7816_getAtr(phNxpEse_data* pATRRsp);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to get the max T=1 data send size
+ *
+ * \retval Current IFS adjusted value wrt card.
+ *
+ */
+uint16_t phNxpEseProto7816_GetIfs(void);
+
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to get OS mode(JCOP/OSU)
+ *
+ * \retval OS mode(JCOP/OSU).
+ *
+ */
+phNxpEseProto7816_OsType_t phNxpEseProto7816_GetOsMode(void);
+/**
+ * \ingroup ISO7816-3_protocol_lib
+ * \brief This function is used to check eSE is alive/responding
+ *
+ *
+ *
+ */
+ESESTATUS phNxpEseProto7816_CloseAllSessions(void);
+/** @} */
+#endif /* _PHNXPESEPROTO7816_3_H_ */
diff --git a/snxxx/libese-spi/p73/lib/phNxpEse_Apdu_Api.cpp b/snxxx/libese-spi/p73/lib/phNxpEse_Apdu_Api.cpp
new file mode 100755
index 0000000..9a01370
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEse_Apdu_Api.cpp
@@ -0,0 +1,270 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019,2021 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+/**
+ * \addtogroup ISO7816-4_application_protocol_implementation
+ *
+ * @{ */
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+#include <phNxpEse_Apdu_Api.h>
+#include <phNxpEse_Api.h>
+
+static ESESTATUS phNxpEse_7816_FrameCmd(pphNxpEse_7816_cpdu_t pCmd,
+ uint8_t** pcmd_data, uint32_t* cmd_len);
+
+/******************************************************************************
+ * Function phNxpEse_7816_Transceive
+ *
+ * Description This function prepares C-APDU and sends to p61 and receives
+ * response from the p61. also it parses all required fields of
+ * the response PDU.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_7816_Transceive(pphNxpEse_7816_cpdu_t pCmd,
+ pphNxpEse_7816_rpdu_t pRsp) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, " %s Enter \n", __FUNCTION__);
+
+ uint32_t cmd_len = 0;
+ uint8_t* pCmd_data = NULL;
+ phNxpEse_data pCmdTrans;
+ phNxpEse_data pRspTrans;
+ phNxpEse_memset(&pCmdTrans, 0x00, sizeof(phNxpEse_data));
+ phNxpEse_memset(&pRspTrans, 0x00, sizeof(phNxpEse_data));
+
+ if (NULL == pCmd || NULL == pRsp) {
+ ALOGE(" %s Invalid prameter \n", __FUNCTION__);
+ status = ESESTATUS_INVALID_PARAMETER;
+ } else if (pCmd->cpdu_type > 1) {
+ ALOGE(" %s Invalid cpdu type \n", __FUNCTION__);
+ status = ESESTATUS_INVALID_CPDU_TYPE;
+ } else if (0 < pCmd->le_type && NULL == pRsp->pdata) {
+ /* if response is requested, but no valid res buffer
+ * provided by application */
+ ALOGE(" %s Invalid response buffer \n", __FUNCTION__);
+ status = ESESTATUS_INVALID_BUFFER;
+ } else {
+ status = phNxpEse_7816_FrameCmd(pCmd, &pCmd_data, &cmd_len);
+ if (ESESTATUS_SUCCESS == status) {
+ pCmdTrans.len = cmd_len;
+ pCmdTrans.p_data = pCmd_data;
+ status = phNxpEse_Transceive(&pCmdTrans, &pRspTrans);
+ if (ESESTATUS_SUCCESS != status) {
+ ALOGE(" %s phNxpEse_Transceive Failed \n", __FUNCTION__);
+ if ((pRspTrans.len > 0) && (pRspTrans.p_data != NULL)) {
+ pRsp->sw2 = *(pRspTrans.p_data + (pRspTrans.len - 1));
+ pRspTrans.len--;
+ pRsp->sw1 = *(pRspTrans.p_data + (pRspTrans.len - 1));
+ pRspTrans.len--;
+ pRsp->len = pRspTrans.len;
+ }
+ } else {
+ if ((pRspTrans.len > 0) && (pRspTrans.p_data != NULL)) {
+ pRsp->sw2 = *(pRspTrans.p_data + (pRspTrans.len - 1));
+ pRspTrans.len--;
+ pRsp->sw1 = *(pRspTrans.p_data + (pRspTrans.len - 1));
+ pRspTrans.len--;
+ pRsp->len = pRspTrans.len;
+ ALOGD_IF(ese_debug_enabled, "pRsp->len %d", pRsp->len);
+ if (pRspTrans.len > 0 && NULL != pRsp->pdata) {
+ phNxpEse_memcpy(pRsp->pdata, pRspTrans.p_data, pRspTrans.len);
+ status = ESESTATUS_SUCCESS;
+ } else if (pRspTrans.len == 0) {
+ status = ESESTATUS_SUCCESS;
+ } else {
+ /* if application response buffer is null and data is present */
+ ALOGE("Invalid Res buffer");
+ status = ESESTATUS_FAILED;
+ }
+ ALOGD_IF(ese_debug_enabled, "Freeing memory pRspTrans.p_data ");
+ phNxpEse_free(pRspTrans.p_data);
+ pRspTrans.p_data = NULL;
+ pRspTrans.len = 0;
+ } else {
+ ALOGE("pRspTrans.len error = %d", pRspTrans.len);
+ status = ESESTATUS_FAILED;
+ }
+ }
+ if (pCmd_data != NULL) {
+ ALOGD_IF(ese_debug_enabled, "Freeing memory pCmd_data");
+ phNxpEse_free(pCmd_data);
+ }
+ }
+ }
+ ALOGD_IF(ese_debug_enabled, " %s Exit status 0x%x \n", __FUNCTION__, status);
+ return status;
+}
+
+/**
+ * \ingroup ISO7816-4_application_protocol_implementation
+ * \brief Frames ISO7816-4 command.
+ * pCmd: 7816 command structure.
+ * pcmd_data: command buffer pointer.
+ *
+ * \param[in] pCmd- Structure pointer passed from
+ *application
+ * \param[in] **pcmd_data - Hold the allocated memory buffer for
+ *command.
+ * \param[in] *cmd_len - Hold the buffer length, update by this
+ *function
+ *
+ * \retval ESESTATUS_SUCCESS on Success else proper error code
+ *
+ */
+
+static ESESTATUS phNxpEse_7816_FrameCmd(pphNxpEse_7816_cpdu_t pCmd,
+ uint8_t** pcmd_data,
+ uint32_t* cmd_len) {
+ uint32_t cmd_total_len = MIN_HEADER_LEN; /* header is always 4 bytes */
+ uint8_t* pbuff = NULL;
+ uint32_t index = 0;
+ uint8_t lc_len = 0;
+ uint8_t le_len = 0;
+
+ ALOGD_IF(ese_debug_enabled, "%s pCmd->lc = %d, pCmd->le_type = %d",
+ __FUNCTION__, pCmd->lc, pCmd->le_type);
+ /* calculate the total buffer length */
+ if (pCmd->lc > 0) {
+ if (pCmd->cpdu_type == 0) {
+ cmd_total_len += 1; /* 1 byte LC */
+ lc_len = 1;
+ } else {
+ cmd_total_len += 3; /* 3 byte LC */
+ lc_len = 3;
+ }
+
+ cmd_total_len += pCmd->lc; /* add data length */
+ if (pCmd->pdata == NULL) {
+ ALOGE("%s Invalide data buffer from application ", __FUNCTION__);
+ return ESESTATUS_INVALID_BUFFER;
+ }
+ } else {
+ lc_len = 0;
+ ALOGD_IF(ese_debug_enabled, "%s lc (data) field is not present %d",
+ __FUNCTION__, pCmd->lc);
+ }
+
+ if (pCmd->le_type > 0) {
+ if (pCmd->le_type == 1) {
+ cmd_total_len += 1; /* 1 byte LE */
+ le_len = 1;
+ } else if ((pCmd->le_type == 2 || pCmd->le_type == 3)) {
+ /* extended le */
+ if ((pCmd->le_type == 3) && (lc_len == 0)) {
+ /* if data field not present, than only LE would be three bytes */
+ cmd_total_len += 3; /* 3 byte LE */
+ le_len = 3;
+ } else if ((pCmd->le_type == 2) && (lc_len != 0)) {
+ /* if data field present, LE would be two bytes */
+ cmd_total_len += 2; /* 2 byte LE */
+ le_len = 2;
+ } else {
+ ALOGE("%s wrong LE type %d", __FUNCTION__, pCmd->le_type);
+ cmd_total_len += pCmd->le_type;
+ le_len = pCmd->le_type;
+ }
+ } else {
+ ALOGE("%s wrong cpdu_type value %d", __FUNCTION__, pCmd->cpdu_type);
+ return ESESTATUS_INVALID_CPDU_TYPE;
+ }
+ } else {
+ le_len = 0;
+ ALOGD_IF(ese_debug_enabled, "%s le field is not present", __FUNCTION__);
+ }
+ ALOGD_IF(ese_debug_enabled, "%s cmd_total_len = %d, le_len = %d, lc_len = %d",
+ __FUNCTION__, cmd_total_len, le_len, lc_len);
+
+ pbuff = (uint8_t*)phNxpEse_calloc(cmd_total_len, sizeof(uint8_t));
+ if (pbuff == NULL) {
+ ALOGE("%s Error allocating memory", __FUNCTION__);
+ return ESESTATUS_INSUFFICIENT_RESOURCES;
+ }
+ *cmd_len = cmd_total_len;
+ *pcmd_data = pbuff;
+ index = 0;
+
+ *(pbuff + index) = pCmd->cla;
+ index++;
+
+ *(pbuff + index) = pCmd->ins;
+ index++;
+
+ *(pbuff + index) = pCmd->p1;
+ index++;
+
+ *(pbuff + index) = pCmd->p2;
+ index++;
+
+ /* lc_len can be 0, 1 or 3 bytes */
+ if (lc_len > 0) {
+ if (lc_len == 1) {
+ *(pbuff + index) = pCmd->lc;
+ index++;
+ } else {
+ /* extended cmd buffer*/
+ *(pbuff + index) = 0x00; /* three byte lc */
+ index++;
+ *(pbuff + index) = ((pCmd->lc & 0xFF00) >> 8);
+ index++;
+ *(pbuff + index) = (pCmd->lc & 0x00FF);
+ index++;
+ }
+ /* copy the lc bytes data */
+ phNxpEse_memcpy((pbuff + index), pCmd->pdata, pCmd->lc);
+ index += pCmd->lc;
+ }
+ /* le_len can be 0, 1, 2 or 3 bytes */
+ if (le_len > 0) {
+ if (le_len == 1) {
+ if (pCmd->le == 256) {
+ /* if le is 256 assign max value*/
+ *(pbuff + index) = 0x00;
+ } else {
+ *(pbuff + index) = (uint8_t)pCmd->le;
+ }
+ index++;
+ } else {
+ if (pCmd->le == 65536) {
+ if (le_len == 3) {
+ /* assign max value */
+ *(pbuff + index) = 0x00; /* three byte le */
+ index++;
+ }
+ *(pbuff + index) = 0x00;
+ index++;
+ *(pbuff + index) = 0x00;
+ index++;
+ } else {
+ if (le_len == 3) {
+ *(pbuff + index) = 0x00; /* three byte le */
+ index++;
+ }
+ *(pbuff + index) = ((pCmd->le & 0x0000FF00) >> 8);
+ index++;
+ *(pbuff + index) = (pCmd->le & 0x000000FF);
+ index++;
+ }
+ }
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s cmd_total_len = %d, index = %d",
+ __FUNCTION__, index, cmd_total_len);
+ return ESESTATUS_SUCCESS;
+}
+/** @} */
diff --git a/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp b/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp
new file mode 100755
index 0000000..a5b63d7
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEse_Api.cpp
@@ -0,0 +1,1950 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+
+#include <EseTransport.h>
+#include <cutils/properties.h>
+#include <ese_config.h>
+#include <phNxpEseFeatures.h>
+#include <phNxpEsePal.h>
+#include <phNxpEseProto7816_3.h>
+#include <phNxpEse_Internal.h>
+
+#define RECEIVE_PACKET_SOF 0xA5
+#define CHAINED_PACKET_WITHSEQN 0x60
+#define CHAINED_PACKET_WITHOUTSEQN 0x20
+#define PH_PAL_ESE_PRINT_PACKET_TX(data, len) \
+ ({ phPalEse_print_packet("SEND", data, len); })
+#define PH_PAL_ESE_PRINT_PACKET_RX(data, len) \
+ ({ phPalEse_print_packet("RECV", data, len); })
+/* 32K(0x8000) Datasize + 10(0xA) Byte Max Header Size + 1 byte negative
+ * testcase support */
+#define MAX_SUPPORTED_DATA_SIZE 0x800B
+static int phNxpEse_readPacket(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToRead);
+static int phNxpEse_readPacket_legacy(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToRead);
+
+static ESESTATUS phNxpEse_checkJcopDwnldState(void);
+static ESESTATUS phNxpEse_setJcopDwnldState(phNxpEse_JcopDwnldState state);
+static ESESTATUS phNxpEse_checkFWDwnldStatus(void);
+static void phNxpEse_GetMaxTimer(unsigned long* pMaxTimer);
+static unsigned char* phNxpEse_GgetTimerTlvBuffer(unsigned char* timer_buffer,
+ unsigned int value);
+static __inline bool phNxpEse_isColdResetRequired(phNxpEse_initMode mode,
+ ESESTATUS status);
+static int poll_sof_chained_delay = 0;
+static phNxpEse_OsVersion_t sOsVersion = INVALID_OS_VERSION;
+/* To Overwrite the value of wtx_counter_limit from config file*/
+static unsigned long int app_wtx_cnt = RESET_APP_WTX_COUNT;
+
+/*********************** Global Variables *************************************/
+
+/* ESE Context structure */
+phNxpEse_Context_t nxpese_ctxt;
+bool ese_debug_enabled = false;
+
+/******************************************************************************
+ * Function phNxpEse_SetEndPoint_Cntxt
+ *
+ * Description This function is called set the SE endpoint
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+
+ESESTATUS phNxpEse_SetEndPoint_Cntxt(uint8_t uEndPoint) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ status = phNxpEseProto7816_SetEndPoint(uEndPoint);
+ if (status == ESESTATUS_SUCCESS) {
+ nxpese_ctxt.nadInfo.nadRx = nadInfoRx_ptr[uEndPoint];
+ nxpese_ctxt.nadInfo.nadTx = nadInfoTx_ptr[uEndPoint];
+ nxpese_ctxt.endPointInfo = uEndPoint;
+ }
+ ALOGD_IF(ese_debug_enabled, "%s: Enpoint=%d", __FUNCTION__, uEndPoint);
+ } else {
+ ALOGE("%s- Function not supported", __FUNCTION__);
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_ResetEndPoint_Cntxt
+ *
+ * Description This function is called to reset the SE endpoint
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_ResetEndPoint_Cntxt(uint8_t uEndPoint) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ status = phNxpEseProto7816_ResetEndPoint(uEndPoint);
+ } else {
+ ALOGE("%s- Function not supported", __FUNCTION__);
+ }
+ return status;
+}
+/******************************************************************************
+ * Function phNxpLog_InitializeLogLevel
+ *
+ * Description This function is called during phNxpEse_init to initialize
+ * debug log level.
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+
+void phNxpLog_InitializeLogLevel() {
+ ese_debug_enabled =
+ (EseConfig::getUnsigned(NAME_SE_DEBUG_ENABLED, 0) != 0) ? true : false;
+
+ char valueStr[PROPERTY_VALUE_MAX] = {0};
+ int len = property_get("vendor.ese.debug_enabled", valueStr, "");
+ if (len > 0) {
+ // let Android property override .conf variable
+ unsigned debug_enabled = 0;
+ sscanf(valueStr, "%u", &debug_enabled);
+ ese_debug_enabled = (debug_enabled == 0) ? false : true;
+ }
+
+ ALOGD_IF(ese_debug_enabled, "%s: level=%u", __func__, ese_debug_enabled);
+}
+
+/******************************************************************************
+ * Function phNxpEse_init
+ *
+ * Description This function is called by Jni/phNxpEse_open during the
+ * initialization of the ESE. It initializes protocol stack
+ *instance variable
+ *
+ * Returns This function return ESESTATUS_SUCCESS (0) in case of
+ *success In case of failure returns other failure value.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_init(phNxpEse_initParams initParams) {
+ ESESTATUS wConfigStatus = ESESTATUS_FAILED;
+ unsigned long int num, ifsd_value = 0;
+ unsigned long maxTimer = 0;
+ uint8_t retry = 0;
+ phNxpEseProto7816InitParam_t protoInitParam;
+ phNxpEse_memset(&protoInitParam, 0x00, sizeof(phNxpEseProto7816InitParam_t));
+ /* STATUS_OPEN */
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_OPEN;
+
+ if (app_wtx_cnt > RESET_APP_WTX_COUNT) {
+ protoInitParam.wtx_counter_limit = app_wtx_cnt;
+ ALOGD_IF(ese_debug_enabled, "Wtx_counter limit from app setting - %lu",
+ protoInitParam.wtx_counter_limit);
+ } else {
+ protoInitParam.wtx_counter_limit = EseConfig::getUnsigned(
+ NAME_NXP_WTX_COUNT_VALUE, PH_PROTO_WTX_DEFAULT_COUNT);
+ ALOGD_IF(ese_debug_enabled, "Wtx_counter read from config file - %lu",
+ protoInitParam.wtx_counter_limit);
+ }
+ if (EseConfig::hasKey(NAME_RNACK_RETRY_DELAY)) {
+ num = EseConfig::getUnsigned(NAME_RNACK_RETRY_DELAY);
+ nxpese_ctxt.invalidFrame_Rnack_Delay = num;
+ ALOGD_IF(ese_debug_enabled, "Rnack retry_delay read from config file - %lu",
+ num);
+ } else {
+ nxpese_ctxt.invalidFrame_Rnack_Delay = 7000;
+ }
+ if (EseConfig::hasKey(NAME_NXP_MAX_RNACK_RETRY)) {
+ protoInitParam.rnack_retry_limit =
+ EseConfig::getUnsigned(NAME_NXP_MAX_RNACK_RETRY);
+ } else {
+ protoInitParam.rnack_retry_limit = MAX_RNACK_RETRY_LIMIT;
+ }
+ if (ESE_MODE_NORMAL ==
+ initParams.initMode) /* TZ/Normal wired mode should come here*/
+ {
+ if (EseConfig::hasKey(NAME_NXP_SPI_INTF_RST_ENABLE)) {
+ protoInitParam.interfaceReset =
+ (EseConfig::getUnsigned(NAME_NXP_SPI_INTF_RST_ENABLE) == 1) ? true
+ : false;
+ } else {
+ protoInitParam.interfaceReset = true;
+ }
+ } else /* OSU mode, no interface reset is required */
+ {
+ if (phNxpEse_doResetProtection(true)) {
+ ALOGE("%s Reset Potection failed. returning...", __FUNCTION__);
+ return ESESTATUS_FAILED;
+ }
+ protoInitParam.interfaceReset = false;
+ }
+ if (EseConfig::hasKey(NAME_NXP_WTX_NTF_COUNT)) {
+ num = EseConfig::getUnsigned(NAME_NXP_WTX_NTF_COUNT);
+ protoInitParam.wtx_ntf_limit = num;
+ ALOGD_IF(ese_debug_enabled, "Wtx_ntf limit from config file - %lu",
+ protoInitParam.wtx_ntf_limit);
+ } else {
+ protoInitParam.wtx_ntf_limit = PH_DEFAULT_WTX_NTF_LIMIT;
+ }
+ nxpese_ctxt.fPtr_WtxNtf = initParams.fPtr_WtxNtf;
+ /* Sharing lib context for fetching secure timer values */
+ protoInitParam.pSecureTimerParams =
+ (phNxpEseProto7816SecureTimer_t*)&nxpese_ctxt.secureTimerParams;
+
+ ALOGD_IF(ese_debug_enabled,
+ "%s secureTimer1 0x%x secureTimer2 0x%x secureTimer3 0x%x",
+ __FUNCTION__, nxpese_ctxt.secureTimerParams.secureTimer1,
+ nxpese_ctxt.secureTimerParams.secureTimer2,
+ nxpese_ctxt.secureTimerParams.secureTimer3);
+
+ phNxpEse_GetMaxTimer(&maxTimer);
+#ifdef SPM_INTEGRATED
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ wConfigStatus = phNxpEse_SPM_DisablePwrControl(maxTimer);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("%s phNxpEse_SPM_DisablePwrControl: failed", __FUNCTION__);
+ }
+ }
+#endif
+ do {
+ /* T=1 Protocol layer open */
+ wConfigStatus = phNxpEseProto7816_Open(protoInitParam);
+ if (phNxpEse_isColdResetRequired(initParams.initMode, wConfigStatus))
+ phNxpEse_SPM_ConfigPwr(SPM_RECOVERY_RESET);
+ } while (phNxpEse_isColdResetRequired(initParams.initMode, wConfigStatus) &&
+ retry++ < 1);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ if (ESESTATUS_TRANSCEIVE_FAILED == wConfigStatus ||
+ ESESTATUS_FAILED == wConfigStatus) {
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_RECOVERY;
+ }
+ }
+
+ if (ESESTATUS_SUCCESS == wConfigStatus) {
+ ALOGD_IF(ese_debug_enabled, "phNxpEseProto7816_Open completed >>>>>");
+ /* Retrieving the IFS-D value configured in the config file and applying to
+ * Card */
+ if ((nxpese_ctxt.endPointInfo == END_POINT_ESE) &&
+ (EseConfig::hasKey(NAME_NXP_ESE_IFSD_VALUE))) {
+ ifsd_value = EseConfig::getUnsigned(NAME_NXP_ESE_IFSD_VALUE);
+ if ((0xFFFF > ifsd_value) && (ifsd_value > 0)) {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEseProto7816_SetIFS IFS adjustment requested with %ld",
+ ifsd_value);
+ phNxpEse_setIfs(ifsd_value);
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEseProto7816_SetIFS IFS adjustment argument invalid");
+ }
+ } else if ((nxpese_ctxt.endPointInfo == END_POINT_EUICC) &&
+ (EseConfig::hasKey(NAME_NXP_EUICC_IFSD_VALUE))) {
+ ifsd_value = EseConfig::getUnsigned(NAME_NXP_EUICC_IFSD_VALUE);
+ if ((0xFFFF > ifsd_value) && (ifsd_value > 0)) {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEseProto7816_SetIFS IFS adjustment requested with %ld",
+ ifsd_value);
+ phNxpEse_setIfs(ifsd_value);
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEseProto7816_SetIFS IFS adjustment argument invalid");
+ }
+ }
+ } else {
+ ALOGE("phNxpEseProto7816_Open failed with status = %x", wConfigStatus);
+ }
+
+ return wConfigStatus;
+}
+
+/******************************************************************************
+ * Function phNxpEse_open
+ *
+ * Description This function is called by Jni during the
+ * initialization of the ESE. It opens the physical connection
+ * with ESE and creates required NAME_NXP_MAX_RNACK_RETRYclient
+ * 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;
+ ESESTATUS wConfigStatus = ESESTATUS_SUCCESS;
+ unsigned long int num = 0, tpm_enable = 0;
+ char ese_dev_node[64];
+ std::string ese_node;
+#ifdef SPM_INTEGRATED
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+#endif
+ /* initialize trace level */
+ phNxpLog_InitializeLogLevel();
+
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_open Enter");
+ /*When spi channel is already opened return status as FAILED*/
+ if (nxpese_ctxt.EseLibStatus != ESE_STATUS_CLOSE) {
+ ALOGD_IF(ese_debug_enabled, "already opened\n");
+ return ESESTATUS_BUSY;
+ }
+
+ phNxpEse_memset(&nxpese_ctxt, 0x00, sizeof(nxpese_ctxt));
+ phNxpEse_memset(&tPalConfig, 0x00, sizeof(tPalConfig));
+
+ ALOGD_IF(ese_debug_enabled, "MW SEAccessKit Version");
+ ALOGD_IF(ese_debug_enabled, "Android Version:0x%x", NXP_ANDROID_VER);
+ ALOGD_IF(ese_debug_enabled, "Major Version:0x%x", ESELIB_MW_VERSION_MAJ);
+ ALOGD_IF(ese_debug_enabled, "Minor Version:0x%x", ESELIB_MW_VERSION_MIN);
+
+ if (EseConfig::hasKey(NAME_NXP_OS_VERSION)) {
+ num = EseConfig::getUnsigned(NAME_NXP_OS_VERSION);
+ ALOGD_IF(ese_debug_enabled, "Chip type read from config file - %lu", num);
+ sOsVersion = (num == 1) ? OS_VERSION_4_0
+ : ((num == 2) ? OS_VERSION_5_1 : OS_VERSION_5_2);
+ } else {
+ sOsVersion = OS_VERSION_5_2;
+ ALOGD_IF(ese_debug_enabled,
+ "Chip type not defined in config file osVersion- %d", sOsVersion);
+ }
+ if (EseConfig::hasKey(NAME_NXP_TP_MEASUREMENT)) {
+ tpm_enable = EseConfig::getUnsigned(NAME_NXP_TP_MEASUREMENT);
+ ALOGD_IF(
+ ese_debug_enabled,
+ "SPI Throughput measurement enable/disable read from config file - %lu",
+ tpm_enable);
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "SPI Throughput not defined in config file - %lu", tpm_enable);
+ }
+#if (NXP_POWER_SCHEME_SUPPORT == true)
+ if (EseConfig::hasKey(NAME_NXP_POWER_SCHEME)) {
+ num = EseConfig::getUnsigned(NAME_NXP_POWER_SCHEME);
+ nxpese_ctxt.pwr_scheme = num;
+ ALOGD_IF(ese_debug_enabled, "Power scheme read from config file - %lu",
+ num);
+ } else {
+ nxpese_ctxt.pwr_scheme = PN67T_POWER_SCHEME;
+ ALOGD_IF(ese_debug_enabled, "Power scheme not defined in config file - %lu",
+ num);
+ }
+#else
+ nxpese_ctxt.pwr_scheme = PN67T_POWER_SCHEME;
+ tpm_enable = 0x00;
+#endif
+
+ if (EseConfig::hasKey(NAME_NXP_NAD_POLL_RETRY_TIME)) {
+ num = EseConfig::getUnsigned(NAME_NXP_NAD_POLL_RETRY_TIME);
+ nxpese_ctxt.nadPollingRetryTime = num;
+ } else {
+ nxpese_ctxt.nadPollingRetryTime = 5;
+ }
+
+ ALOGD_IF(ese_debug_enabled, "Nad poll retry time in us - %lu us",
+ nxpese_ctxt.nadPollingRetryTime * GET_WAKE_UP_DELAY() *
+ NAD_POLLING_SCALER);
+
+ /*Read device node path*/
+ ese_node = EseConfig::getString(NAME_NXP_ESE_DEV_NODE, "/dev/pn81a");
+ strlcpy(ese_dev_node, ese_node.c_str(), sizeof(ese_dev_node));
+ tPalConfig.pDevName = (int8_t*)ese_dev_node;
+
+ /* Initialize PAL layer */
+ wConfigStatus = phPalEse_open_and_configure(&tPalConfig);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_Init Failed");
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ if (ESESTATUS_DRIVER_BUSY == wConfigStatus)
+ ALOGE("Ese Driver is Busy!!!");
+ }
+ goto clean_and_return;
+ }
+ /* Copying device handle to ESE Lib context*/
+ nxpese_ctxt.pDevHandle = tPalConfig.pDevHandle;
+ if (ESE_PROTOCOL_MEDIA_SPI == initParams.mediaType) {
+ ALOGD_IF(ese_debug_enabled,
+ "Inform eSE about the starting of trusted Mode");
+ wConfigStatus =
+ phPalEse_ioctl(phPalEse_e_SetSecureMode, tPalConfig.pDevHandle, 0x01);
+ if (ESESTATUS_SUCCESS != wConfigStatus) goto clean_and_return_2;
+ }
+#ifdef SPM_INTEGRATED
+ /* Get the Access of ESE*/
+ wSpmStatus = phNxpEse_SPM_Init(nxpese_ctxt.pDevHandle);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_Init Failed");
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_2;
+ }
+ wSpmStatus = phNxpEse_SPM_SetPwrScheme(nxpese_ctxt.pwr_scheme);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_SetPwrScheme Failed", __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ wConfigStatus = phNxpEse_checkFWDwnldStatus();
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("Failed to open SPI due to VEN pin used by FW download \n");
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ }
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ } else {
+ if (((current_spm_state & SPM_STATE_SPI) |
+ (current_spm_state & SPM_STATE_SPI_PRIO)) &&
+ !(current_spm_state & SPM_STATE_SPI_FAILED)) {
+ ALOGE(" %s : SPI is already opened...second instance not allowed",
+ __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ }
+ if (current_spm_state & SPM_STATE_JCOP_DWNLD) {
+ ALOGE(" %s : Denying to open JCOP Download in progress", __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ phNxpEse_memcpy(&nxpese_ctxt.initParams, &initParams,
+ sizeof(phNxpEse_initParams));
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ /* Updating ESE power state based on the init mode */
+ if (ESE_MODE_OSU == nxpese_ctxt.initParams.initMode) {
+ ALOGD_IF(ese_debug_enabled, "%s Init mode ---->OSU", __FUNCTION__);
+ wConfigStatus = phNxpEse_checkJcopDwnldState();
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_checkJcopDwnldState failed");
+ goto clean_and_return_1;
+ }
+ }
+ }
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_POWER_ENABLE);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: enabling power Failed");
+ if (wSpmStatus == ESESTATUS_BUSY) {
+ wConfigStatus = ESESTATUS_BUSY;
+ } else if (wSpmStatus == ESESTATUS_DWNLD_BUSY) {
+ wConfigStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wConfigStatus = ESESTATUS_FAILED;
+ }
+ goto clean_and_return;
+ } else {
+ ALOGD_IF(ese_debug_enabled, "nxpese_ctxt.spm_power_state true");
+ nxpese_ctxt.spm_power_state = true;
+ }
+#endif
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ if (tpm_enable) {
+ wConfigStatus = phPalEse_ioctl(phPalEse_e_EnableThroughputMeasurement,
+ nxpese_ctxt.pDevHandle, 0);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_IoCtl Failed");
+ goto clean_and_return;
+ }
+ }
+ }
+ ALOGD_IF(ese_debug_enabled, "wConfigStatus %x", wConfigStatus);
+ return wConfigStatus;
+
+clean_and_return:
+#ifdef SPM_INTEGRATED
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_POWER_DISABLE);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: disabling power Failed");
+ }
+clean_and_return_1:
+ phNxpEse_SPM_DeInit();
+clean_and_return_2:
+#endif
+ if (NULL != nxpese_ctxt.pDevHandle) {
+ phPalEse_close(nxpese_ctxt.pDevHandle);
+ phNxpEse_memset(&nxpese_ctxt, 0x00, sizeof(nxpese_ctxt));
+ }
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_CLOSE;
+ nxpese_ctxt.spm_power_state = false;
+ return ESESTATUS_FAILED;
+}
+
+/******************************************************************************
+ * \ingroup spi_libese
+ *
+ * \brief Check if libese has opened
+ *
+ * \retval return false if it is close, otherwise true.
+ **
+ ******************************************************************************/
+bool phNxpEse_isOpen() { return nxpese_ctxt.EseLibStatus != ESE_STATUS_CLOSE; }
+
+/******************************************************************************
+ * Function phNxpEse_openPrioSession
+ *
+ * Description This function is called by Jni during the
+ * initialization of the ESE. It opens the physical connection
+ * with ESE () and creates required client thread for
+ * operation. This will get priority access to ESE for timeout
+ duration.
+
+ * Returns This function return ESESTATUS_SUCCESS (0) in case of
+ success
+ * In case of failure returns other failure value.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_openPrioSession(phNxpEse_initParams initParams) {
+ phPalEse_Config_t tPalConfig;
+ ESESTATUS wConfigStatus = ESESTATUS_SUCCESS;
+ unsigned long int num = 0, tpm_enable = 0;
+
+ /* initialize trace level */
+ phNxpLog_InitializeLogLevel();
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_openPrioSession Enter");
+#ifdef SPM_INTEGRATED
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+#endif
+ phNxpEse_memset(&nxpese_ctxt, 0x00, sizeof(nxpese_ctxt));
+ phNxpEse_memset(&tPalConfig, 0x00, sizeof(tPalConfig));
+
+ ALOGD_IF(ese_debug_enabled, "MW SEAccessKit Version");
+ ALOGD_IF(ese_debug_enabled, "Android Version:0x%x", NXP_ANDROID_VER);
+ ALOGD_IF(ese_debug_enabled, "Major Version:0x%x", ESELIB_MW_VERSION_MAJ);
+ ALOGD_IF(ese_debug_enabled, "Minor Version:0x%x", ESELIB_MW_VERSION_MIN);
+
+#if (NXP_POWER_SCHEME_SUPPORT == true)
+ if (EseConfig::hasKey(NAME_NXP_POWER_SCHEME)) {
+ num = EseConfig::getUnsigned(NAME_NXP_POWER_SCHEME);
+ nxpese_ctxt.pwr_scheme = num;
+ ALOGD_IF(ese_debug_enabled, "Power scheme read from config file - %lu",
+ num);
+ } else
+#endif
+ {
+ nxpese_ctxt.pwr_scheme = PN67T_POWER_SCHEME;
+ ALOGD_IF(ese_debug_enabled, "Power scheme not defined in config file - %lu",
+ num);
+ }
+ if (EseConfig::hasKey(NAME_NXP_TP_MEASUREMENT)) {
+ tpm_enable = EseConfig::getUnsigned(NAME_NXP_TP_MEASUREMENT);
+ ALOGD_IF(
+ ese_debug_enabled,
+ "SPI Throughput measurement enable/disable read from config file - %lu",
+ tpm_enable);
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "SPI Throughput not defined in config file - %lu", num);
+ }
+
+ tPalConfig.pDevName = (int8_t*)"/dev/p73";
+
+ /* Initialize PAL layer */
+ wConfigStatus = phPalEse_open_and_configure(&tPalConfig);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_Init Failed");
+ goto clean_and_return;
+ }
+ /* Copying device handle to hal context*/
+ nxpese_ctxt.pDevHandle = tPalConfig.pDevHandle;
+
+#ifdef SPM_INTEGRATED
+ /* Get the Access of ESE*/
+ wSpmStatus = phNxpEse_SPM_Init(nxpese_ctxt.pDevHandle);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_Init Failed");
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_2;
+ }
+ wSpmStatus = phNxpEse_SPM_SetPwrScheme(nxpese_ctxt.pwr_scheme);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_SetPwrScheme Failed", __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ } else {
+ if ((current_spm_state & SPM_STATE_SPI) |
+ (current_spm_state & SPM_STATE_SPI_PRIO)) {
+ ALOGE(" %s : SPI is already opened...second instance not allowed",
+ __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ if (current_spm_state & SPM_STATE_JCOP_DWNLD) {
+ ALOGE(" %s : Denying to open JCOP Download in progress", __FUNCTION__);
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ wConfigStatus = phNxpEse_checkFWDwnldStatus();
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGD_IF(ese_debug_enabled,
+ "Failed to open SPI due to VEN pin used by FW download \n");
+ wConfigStatus = ESESTATUS_FAILED;
+ goto clean_and_return_1;
+ }
+ }
+ }
+ phNxpEse_memcpy(&nxpese_ctxt.initParams, &initParams.initMode,
+ sizeof(phNxpEse_initParams));
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ /* Updating ESE power state based on the init mode */
+ if (ESE_MODE_OSU == nxpese_ctxt.initParams.initMode) {
+ wConfigStatus = phNxpEse_checkJcopDwnldState();
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_checkJcopDwnldState failed");
+ goto clean_and_return_1;
+ }
+ }
+ }
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_POWER_PRIO_ENABLE);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: enabling power for spi prio Failed");
+ if (wSpmStatus == ESESTATUS_BUSY) {
+ wConfigStatus = ESESTATUS_BUSY;
+ } else if (wSpmStatus == ESESTATUS_DWNLD_BUSY) {
+ wConfigStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wConfigStatus = ESESTATUS_FAILED;
+ }
+ goto clean_and_return;
+ } else {
+ ALOGE("nxpese_ctxt.spm_power_state true");
+ nxpese_ctxt.spm_power_state = true;
+ }
+#endif
+
+#ifndef SPM_INTEGRATED
+ wConfigStatus =
+ phPalEse_ioctl(phPalEse_e_ResetDevice, nxpese_ctxt.pDevHandle, 2);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_IoCtl Failed");
+ goto clean_and_return;
+ }
+#endif
+ wConfigStatus =
+ phPalEse_ioctl(phPalEse_e_EnableLog, nxpese_ctxt.pDevHandle, 0);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_IoCtl Failed");
+ goto clean_and_return;
+ }
+ wConfigStatus =
+ phPalEse_ioctl(phPalEse_e_EnablePollMode, nxpese_ctxt.pDevHandle, 1);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_IoCtl Failed");
+ goto clean_and_return;
+ }
+ ALOGD_IF(ese_debug_enabled, "wConfigStatus %x", wConfigStatus);
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ if (tpm_enable) {
+ wConfigStatus = phPalEse_ioctl(phPalEse_e_EnableThroughputMeasurement,
+ nxpese_ctxt.pDevHandle, 0);
+ if (wConfigStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phPalEse_IoCtl Failed");
+ goto clean_and_return;
+ }
+ }
+ }
+ return wConfigStatus;
+
+clean_and_return:
+#ifdef SPM_INTEGRATED
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_POWER_DISABLE);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: disabling power Failed");
+ }
+clean_and_return_1:
+ phNxpEse_SPM_DeInit();
+clean_and_return_2:
+#endif
+ if (NULL != nxpese_ctxt.pDevHandle) {
+ phPalEse_close(nxpese_ctxt.pDevHandle);
+ phNxpEse_memset(&nxpese_ctxt, 0x00, sizeof(nxpese_ctxt));
+ }
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_CLOSE;
+ nxpese_ctxt.spm_power_state = false;
+ return ESESTATUS_FAILED;
+}
+
+/******************************************************************************
+ * Function phNxpEse_setJcopDwnldState
+ *
+ * Description This function is used to check whether JCOP OS
+ * download can be started or not.
+ *
+ * Returns returns ESESTATUS_SUCCESS or ESESTATUS_FAILED
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEse_setJcopDwnldState(phNxpEse_JcopDwnldState state) {
+ ESESTATUS wConfigStatus = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_setJcopDwnldState Enter");
+
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ wConfigStatus = phNxpEse_SPM_SetJcopDwnldState(state);
+ } else {
+ ALOGE("%s function not supported", __FUNCTION__);
+ }
+ return wConfigStatus;
+}
+
+/******************************************************************************
+ * Function phNxpEse_checkJcopDwnldState
+ *
+ * Description This function is used to check whether JCOP OS
+ * download can be started or not.
+ *
+ * Returns returns ESESTATUS_SUCCESS or ESESTATUS_BUSY
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEse_checkJcopDwnldState(void) {
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_checkJcopDwnld Enter");
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+ uint8_t ese_dwnld_retry = 0x00;
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus == ESESTATUS_SUCCESS) {
+ /* Check current_spm_state and update config/Spm status*/
+ if ((current_spm_state & SPM_STATE_JCOP_DWNLD) ||
+ (current_spm_state & SPM_STATE_WIRED))
+ return ESESTATUS_BUSY;
+
+ status = phNxpEse_setJcopDwnldState(JCP_DWNLD_INIT);
+ if (status == ESESTATUS_SUCCESS) {
+ while (ese_dwnld_retry < ESE_JCOP_OS_DWNLD_RETRY_CNT) {
+ ALOGD_IF(ese_debug_enabled, "ESE_JCOP_OS_DWNLD_RETRY_CNT retry count");
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus == ESESTATUS_SUCCESS) {
+ if ((current_spm_state & SPM_STATE_JCOP_DWNLD)) {
+ status = ESESTATUS_SUCCESS;
+ break;
+ }
+ } else {
+ status = ESESTATUS_FAILED;
+ break;
+ }
+ phNxpEse_Sleep(
+ 200000); /*sleep for 200 ms checking for jcop dwnld status*/
+ ese_dwnld_retry++;
+ }
+ }
+ }
+
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_checkJcopDwnldState status %x", status);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_Transceive
+ *
+ * Description This function update the len and provided buffer
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_Transceive(phNxpEse_data* pCmd, phNxpEse_data* pRsp) {
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ if ((NULL == pCmd) || (NULL == pRsp)) return ESESTATUS_INVALID_PARAMETER;
+
+ if ((pCmd->len == 0) || pCmd->p_data == NULL) {
+ ALOGE(" phNxpEse_Transceive - Invalid Parameter no data\n");
+ return ESESTATUS_INVALID_PARAMETER;
+ } else if (pCmd->len > MAX_SUPPORTED_DATA_SIZE) {
+ ALOGE(" phNxpEse_Transceive - Invalid data size \n");
+ return ESESTATUS_INVALID_RECEIVE_LENGTH;
+ } else if ((ESE_STATUS_CLOSE == nxpese_ctxt.EseLibStatus)) {
+ ALOGE(" %s ESE Not Initialized \n", __FUNCTION__);
+ return ESESTATUS_NOT_INITIALISED;
+ } else if ((ESE_STATUS_BUSY == nxpese_ctxt.EseLibStatus)) {
+ ALOGE(" %s ESE - BUSY \n", __FUNCTION__);
+ return ESESTATUS_BUSY;
+ } else if ((ESE_STATUS_RECOVERY == nxpese_ctxt.EseLibStatus)) {
+ ALOGE(" %s ESE - RECOVERY \n", __FUNCTION__);
+ return ESESTATUS_RECOVERY_STARTED;
+ } else {
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_BUSY;
+ status = phNxpEseProto7816_Transceive((phNxpEse_data*)pCmd,
+ (phNxpEse_data*)pRsp);
+ if (ESESTATUS_SUCCESS != status) {
+ ALOGE(" %s phNxpEseProto7816_Transceive- Failed \n", __FUNCTION__);
+ if (ESESTATUS_TRANSCEIVE_FAILED == status) {
+ /*MAX WTX reached*/
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_RECOVERY;
+ } else {
+ /*Timeout/ No response*/
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_IDLE;
+ }
+ } else {
+ nxpese_ctxt.EseLibStatus = ESE_STATUS_IDLE;
+ }
+ nxpese_ctxt.rnack_sent = false;
+
+ ALOGD_IF(ese_debug_enabled, " %s Exit status 0x%x \n", __FUNCTION__,
+ status);
+ return status;
+ }
+}
+/******************************************************************************
+ * Function phNxpEse_coldReset
+ *
+ * Description This function power cycles the ESE
+ * (cold reset by prop. FW command) interface by
+ * talking to NFC HAL
+ *
+ * Note:
+ * After cold reset, phNxpEse_init need to be called to
+ * reset the host AP T=1 stack parameters
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if the operation is
+ *successful else
+ * ESESTATUS_FAILED(1)
+ ******************************************************************************/
+ESESTATUS phNxpEse_coldReset(void) {
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ ALOGD_IF(ese_debug_enabled, " %s Enter \n", __FUNCTION__);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_RECOVERY_RESET);
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ ALOGE(" %s Function not supported \n", __FUNCTION__);
+ }
+ ALOGD_IF(ese_debug_enabled, " %s Exit status 0x%x \n", __FUNCTION__,
+ wSpmStatus);
+ return wSpmStatus;
+}
+
+/******************************************************************************
+ * Function phNxpEse_reset
+ *
+ * Description This function reset the ESE interface and free all
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if the operation is
+ *successful else
+ * ESESTATUS_FAILED(1)
+ ******************************************************************************/
+ESESTATUS phNxpEse_reset(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ unsigned long maxTimer = 0;
+#ifdef SPM_INTEGRATED
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+#endif
+
+ /* TBD : Call the ioctl to reset the ESE */
+ ALOGD_IF(ese_debug_enabled, " %s Enter \n", __FUNCTION__);
+ /* Do an interface reset, don't wait to see if JCOP went through a full power
+ * cycle or not */
+ status = phNxpEseProto7816_IntfReset(
+ (phNxpEseProto7816SecureTimer_t*)&nxpese_ctxt.secureTimerParams);
+ if (status) {
+ ALOGE("%s Ese status Failed", __FUNCTION__);
+ }
+
+ ALOGD_IF(ese_debug_enabled,
+ "%s secureTimer1 0x%x secureTimer2 0x%x secureTimer3 0x%x",
+ __FUNCTION__, nxpese_ctxt.secureTimerParams.secureTimer1,
+ nxpese_ctxt.secureTimerParams.secureTimer2,
+ nxpese_ctxt.secureTimerParams.secureTimer3);
+ phNxpEse_GetMaxTimer(&maxTimer);
+#ifdef SPM_INTEGRATED
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ status = phNxpEse_SPM_DisablePwrControl(maxTimer);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("%s phNxpEse_SPM_DisablePwrControl: failed", __FUNCTION__);
+ }
+ }
+ if ((nxpese_ctxt.pwr_scheme == PN67T_POWER_SCHEME) ||
+ (nxpese_ctxt.pwr_scheme == PN80T_LEGACY_SCHEME)) {
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_POWER_RESET);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: reset Failed");
+ }
+ }
+#else
+ /* if arg ==2 (hard reset)
+ * if arg ==1 (soft reset)
+ */
+ status = phPalEse_ioctl(phPalEse_e_ResetDevice, nxpese_ctxt.pDevHandle, 2);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_reset Failed");
+ }
+#endif
+ ALOGD_IF(ese_debug_enabled, " %s Exit \n", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_resetJcopUpdate
+ *
+ * Description This function reset the ESE interface during JCOP Update
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if the operation is
+ *successful else
+ * ESESTATUS_FAILED(1)
+ ******************************************************************************/
+ESESTATUS phNxpEse_resetJcopUpdate(void) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ uint8_t retry = 0;
+#ifdef SPM_INTEGRATED
+ unsigned long int num = 0;
+#endif
+
+ /* TBD : Call the ioctl to reset the */
+ ALOGD_IF(ese_debug_enabled, " %s Enter \n", __FUNCTION__);
+
+ /* Reset interface after every reset irrespective of
+ whether JCOP did a full power cycle or not. */
+ do {
+ status = phNxpEseProto7816_Reset();
+ if (status != ESESTATUS_SUCCESS) phNxpEse_SPM_ConfigPwr(SPM_RECOVERY_RESET);
+ } while (status != ESESTATUS_SUCCESS && retry++ < 1);
+
+ /* Retrieving the IFS-D value configured in the config file and applying to
+ * Card */
+ if (EseConfig::hasKey(NAME_NXP_ESE_IFSD_VALUE)) {
+ unsigned long int ifsd_value = 0;
+ ifsd_value = EseConfig::getUnsigned(NAME_NXP_ESE_IFSD_VALUE);
+ if ((0xFFFF > ifsd_value) && (ifsd_value > 0)) {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEseProto7816_SetIFS IFS adjustment requested with %ld",
+ ifsd_value);
+ phNxpEse_setIfs(ifsd_value);
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEseProto7816_SetIFS IFS adjustment argument invalid");
+ }
+ }
+#ifdef SPM_INTEGRATED
+#if (NXP_POWER_SCHEME_SUPPORT == true)
+ if (EseConfig::hasKey(NAME_NXP_POWER_SCHEME)) {
+ num = EseConfig::getUnsigned(NAME_NXP_POWER_SCHEME);
+ if ((num == 1) || (num == 2)) {
+ ALOGD_IF(ese_debug_enabled, " %s Call Config Pwr Reset \n", __FUNCTION__);
+ status = phNxpEse_SPM_ConfigPwr(SPM_POWER_RESET);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_resetJcopUpdate: reset Failed");
+ status = ESESTATUS_FAILED;
+ }
+ } else if (num == 3) {
+ ALOGD_IF(ese_debug_enabled, " %s Call eSE Chip Reset \n", __FUNCTION__);
+ status = phNxpEse_chipReset();
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_resetJcopUpdate: chip reset Failed");
+ status = ESESTATUS_FAILED;
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled, " %s Invalid Power scheme \n", __FUNCTION__);
+ }
+ }
+#else
+ {
+ status = phNxpEse_SPM_ConfigPwr(SPM_POWER_RESET);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: reset Failed");
+ status = ESESTATUS_FAILED;
+ }
+ }
+#endif
+#else
+ /* if arg ==2 (hard reset)
+ * if arg ==1 (soft reset)
+ */
+ status = phPalEse_ioctl(phPalEse_e_ResetDevice, nxpese_ctxt.pDevHandle, 2);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_resetJcopUpdate Failed");
+ }
+#endif
+
+ ALOGD_IF(ese_debug_enabled, " %s Exit \n", __FUNCTION__);
+ return status;
+}
+/******************************************************************************
+ * Function phNxpEse_EndOfApdu
+ *
+ * Description This function is used to send S-frame to indicate
+ *END_OF_APDU
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if the operation is
+ *successful else
+ * ESESTATUS_FAILED(1)
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_EndOfApdu(void) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+#if (NXP_ESE_END_OF_SESSION == true)
+ status = phNxpEseProto7816_Close(
+ (phNxpEseProto7816SecureTimer_t*)&nxpese_ctxt.secureTimerParams);
+#endif
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_chipReset
+ *
+ * Description This function is used to reset the ESE.
+ *
+ * Returns Always return ESESTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_chipReset(void) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ ESESTATUS bStatus = ESESTATUS_FAILED;
+ if (nxpese_ctxt.pwr_scheme == PN80T_EXT_PMU_SCHEME) {
+ bStatus = phNxpEseProto7816_Reset();
+ if (!bStatus) {
+ ALOGE("Inside phNxpEse_chipReset, phNxpEseProto7816_Reset Failed");
+ }
+ status = phPalEse_ioctl(phPalEse_e_ChipRst, nxpese_ctxt.pDevHandle, 6);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_chipReset Failed");
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEse_chipReset is not supported in legacy power scheme");
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_GetOsMode
+ *
+ * Description This function is used to get OS mode(JCOP/OSU)
+ *
+ * Returns 0x01 : JCOP_MODE
+ * 0x02 : OSU_MODE
+ *
+ ******************************************************************************/
+phNxpEseProto7816_OsType_t phNxpEse_GetOsMode(void) {
+ return phNxpEseProto7816_GetOsMode();
+}
+
+/******************************************************************************
+ * Function phNxpEse_isColdResetRequired
+ *
+ * Description This function determines whether hard reset recovery is
+ * required or not on protocol recovery failure.
+ * Returns TRUE(required)/FALSE(not required).
+ *
+ ******************************************************************************/
+static __inline bool phNxpEse_isColdResetRequired(phNxpEse_initMode mode,
+ ESESTATUS status) {
+ return (mode == ESE_MODE_OSU && status != ESESTATUS_SUCCESS);
+}
+
+/******************************************************************************
+ * Function phNxpEse_doResetProtection
+ *
+ * Description This function enables/disables reset protection
+ *
+ * Returns SUCCESS(0)/FAIL(-1).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_doResetProtection(bool flag) {
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ ALOGD_IF(ese_debug_enabled, " %s Enter \n", __FUNCTION__);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ wSpmStatus = phPalEse_ioctl(phPalEse_e_ResetProtection,
+ nxpese_ctxt.pDevHandle, flag);
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ ALOGE(" %s Function not supported \n", __FUNCTION__);
+ }
+ ALOGD_IF(ese_debug_enabled, " %s Exit status 0x%x \n", __FUNCTION__,
+ wSpmStatus);
+ return wSpmStatus;
+}
+
+/******************************************************************************
+ * Function phNxpEse_deInit
+ *
+ * Description This function de-initializes all the ESE protocol params
+ *
+ * Returns Always return ESESTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_deInit(void) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ unsigned long maxTimer = 0;
+ unsigned long num = 0;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0 &&
+ (ESE_STATUS_RECOVERY == nxpese_ctxt.EseLibStatus) &&
+ ESE_PROTOCOL_MEDIA_SPI != nxpese_ctxt.initParams.mediaType) {
+ return status;
+ }
+ if (nxpese_ctxt.initParams.initMode == ESE_MODE_OSU) {
+ phNxpEse_doResetProtection(false);
+ }
+ /*TODO : to be removed after JCOP fix*/
+ if (EseConfig::hasKey(NAME_NXP_VISO_DPD_ENABLED)) {
+ num = EseConfig::getUnsigned(NAME_NXP_VISO_DPD_ENABLED);
+ }
+ if (num == 0 && nxpese_ctxt.nadInfo.nadRx == EUICC_NAD_RX) {
+ // do nothing
+ } else {
+ status = phNxpEseProto7816_Close(
+ (phNxpEseProto7816SecureTimer_t*)&nxpese_ctxt.secureTimerParams);
+ if (status == ESESTATUS_SUCCESS) {
+ ALOGD_IF(ese_debug_enabled,
+ "%s secureTimer1 0x%x secureTimer2 0x%x secureTimer3 0x%x",
+ __FUNCTION__, nxpese_ctxt.secureTimerParams.secureTimer1,
+ nxpese_ctxt.secureTimerParams.secureTimer2,
+ nxpese_ctxt.secureTimerParams.secureTimer3);
+ phNxpEse_GetMaxTimer(&maxTimer);
+#ifdef SPM_INTEGRATED
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ status = phNxpEse_SPM_DisablePwrControl(maxTimer);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("%s phNxpEseP61_DisablePwrCntrl: failed", __FUNCTION__);
+ }
+ } else {
+ ALOGD_IF(ese_debug_enabled, "Interface reset for DPD");
+ status = phNxpEseProto7816_IntfReset(
+ (phNxpEseProto7816SecureTimer_t*)&nxpese_ctxt.secureTimerParams);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("%s IntfReset Failed ", __FUNCTION__);
+ }
+ }
+#endif
+ }
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_close
+ *
+ * Description This function close the ESE interface and free all
+ * resources.
+ *
+ * Returns Always return ESESTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_close(ESESTATUS deInitStatus) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_close Enter");
+ if ((ESE_STATUS_CLOSE == nxpese_ctxt.EseLibStatus)) {
+ ALOGE(" %s ESE Not Initialized \n", __FUNCTION__);
+ return ESESTATUS_NOT_INITIALISED;
+ }
+
+#ifdef SPM_INTEGRATED
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+#endif
+
+#ifdef SPM_INTEGRATED
+ /* Release the Access of */
+ wSpmStatus = phNxpEse_SPM_ConfigPwr(SPM_POWER_DISABLE);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_ConfigPwr: disabling power Failed");
+ } else {
+ nxpese_ctxt.spm_power_state = false;
+ }
+
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ if (ESE_MODE_OSU == nxpese_ctxt.initParams.initMode) {
+ status = phNxpEse_setJcopDwnldState(JCP_SPI_DWNLD_COMPLETE);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("%s: phNxpEse_setJcopDwnldState failed", __FUNCTION__);
+ }
+ }
+ } else {
+ if (NULL != nxpese_ctxt.pDevHandle) {
+ if (ESE_PROTOCOL_MEDIA_SPI == nxpese_ctxt.initParams.mediaType) {
+ ALOGD_IF(ese_debug_enabled, "Inform eSE that trusted Mode is over");
+ status = phPalEse_ioctl(phPalEse_e_SetSecureMode,
+ nxpese_ctxt.pDevHandle, 0x00);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("%s: phPalEse_e_SetSecureMode failed", __FUNCTION__);
+ }
+ if (ESESTATUS_SUCCESS != phNxpEseProto7816_CloseAllSessions()) {
+ ALOGD_IF(ese_debug_enabled, "eSE not responding perform hard reset");
+ phNxpEse_SPM_ConfigPwr(SPM_RECOVERY_RESET);
+ }
+ } else {
+ if (nxpese_ctxt.EseLibStatus == ESE_STATUS_RECOVERY ||
+ (deInitStatus == ESESTATUS_RESPONSE_TIMEOUT) ||
+ ESESTATUS_SUCCESS != phNxpEseProto7816_CloseAllSessions()) {
+ ALOGD_IF(ese_debug_enabled, "eSE not responding perform hard reset");
+ phNxpEse_SPM_ConfigPwr(SPM_RECOVERY_RESET);
+ }
+ }
+ ALOGD_IF(ese_debug_enabled, "Interface reset for DPD");
+ status = phNxpEseProto7816_IntfReset(
+ (phNxpEseProto7816SecureTimer_t*)&nxpese_ctxt.secureTimerParams);
+ if (status == ESESTATUS_TRANSCEIVE_FAILED || status == ESESTATUS_FAILED) {
+ ALOGE("%s IntfReset Failed, perform hard reset", __FUNCTION__);
+ // max wtx or no response of interface reset after protocol recovery
+ phNxpEse_SPM_ConfigPwr(SPM_RECOVERY_RESET);
+ }
+ }
+ }
+
+ wSpmStatus = phNxpEse_SPM_DeInit();
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE("phNxpEse_SPM_DeInit Failed");
+ }
+#endif
+ if (NULL != nxpese_ctxt.pDevHandle) {
+ phPalEse_close(nxpese_ctxt.pDevHandle);
+ phNxpEse_memset(&nxpese_ctxt, 0x00, sizeof(nxpese_ctxt));
+ ALOGD_IF(ese_debug_enabled,
+ "phNxpEse_close - ESE Context deinit completed");
+ }
+ /* Return success always */
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_read
+ *
+ * Description This function write the data to ESE through physical
+ * interface (e.g. I2C) using the driver interface.
+ * Before sending the data to ESE, phNxpEse_write_ext
+ * is called to check if there is any extension processing
+ * is required for the SPI packet being sent out.
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if read successful else
+ * ESESTATUS_FAILED(1)
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_read(uint32_t* data_len, uint8_t** pp_data) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ int ret = -1;
+
+ ALOGD_IF(ese_debug_enabled, "%s Enter ..", __FUNCTION__);
+
+ ret = phNxpEse_readPacket(nxpese_ctxt.pDevHandle, nxpese_ctxt.p_read_buff,
+ MAX_DATA_LEN);
+ if (ret < 0) {
+ ALOGE("PAL Read status error status = %x", status);
+ *data_len = 2;
+ *pp_data = nxpese_ctxt.p_read_buff;
+ status = ESESTATUS_FAILED;
+ } else {
+ PH_PAL_ESE_PRINT_PACKET_RX(nxpese_ctxt.p_read_buff, (uint16_t)ret);
+ *data_len = ret;
+ *pp_data = nxpese_ctxt.p_read_buff;
+ status = ESESTATUS_SUCCESS;
+ }
+
+ ALOGD_IF(ese_debug_enabled, "%s Exit", __FUNCTION__);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_readPacket
+ *
+ * Description This function Reads requested number of bytes from
+ * pn547 device into given buffer.
+ *
+ * Returns nNbBytesToRead- number of successfully read bytes
+ * -1 - read operation failure
+ *
+ ******************************************************************************/
+static int phNxpEse_readPacket(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToRead) {
+ bool flushData = false;
+ int ret = -1;
+ int sof_counter = 0; /* one read may take 1 ms*/
+ int total_count = 0, numBytesToRead = 0, headerIndex = 0;
+
+ ALOGD_IF(ese_debug_enabled, "%s Enter", __FUNCTION__);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ int max_sof_counter = 0;
+ /*Max retry to get SOF in case of chaining*/
+ if (poll_sof_chained_delay == 1) {
+ /*Wait Max for 1.3 sec before retry/recvoery*/
+ /*(max_sof_counter(1300) * 10 us) = 1.3 sec */
+ max_sof_counter = ESE_POLL_TIMEOUT * 10;
+ }
+ /*Max retry to get SOF in case of Non-chaining*/
+ else {
+ /*wait based on config option */
+ /*(nadPollingRetryTime * WAKE_UP_DELAY_SN1xx * NAD_POLLING_SCALER_SN1xx)*/
+ max_sof_counter = ((ESE_POLL_TIMEOUT * 1000) /
+ (nxpese_ctxt.nadPollingRetryTime *
+ GET_WAKE_UP_DELAY() * NAD_POLLING_SCALER));
+ }
+ if (nxpese_ctxt.rnack_sent) {
+ phPalEse_sleep(nxpese_ctxt.invalidFrame_Rnack_Delay);
+ }
+ ALOGD_IF(ese_debug_enabled,
+ "read() max_sof_counter: "
+ "%X ESE_POLL_TIMEOUT %2X",
+ max_sof_counter, ESE_POLL_TIMEOUT);
+ do {
+ ret = -1;
+ ret = phPalEse_read(pDevHandle, pBuffer, 2);
+ if (ret < 0) {
+ /*Polling for read on spi, hence Debug log*/
+ ALOGD_IF(ese_debug_enabled, "_spi_read() [HDR]errno : %x ret : %X",
+ errno, ret);
+ } else {
+ if ((pBuffer[0] == nxpese_ctxt.nadInfo.nadRx) ||
+ (pBuffer[0] == RECEIVE_PACKET_SOF)) {
+ /* Read the HEADR of one byte*/
+ ALOGD_IF(ese_debug_enabled, "%s Read HDR SOF + PCB", __FUNCTION__);
+ numBytesToRead = 1; /*Read only INF LEN*/
+ headerIndex = 1;
+ break;
+ } else if (((pBuffer[0] == 0x00) || (pBuffer[0] == 0xFF)) &&
+ ((pBuffer[1] == nxpese_ctxt.nadInfo.nadRx) ||
+ (pBuffer[1] == RECEIVE_PACKET_SOF))) {
+ /* Read the HEADR of Two bytes*/
+ ALOGD_IF(ese_debug_enabled, "%s Read HDR only SOF", __FUNCTION__);
+ pBuffer[0] = pBuffer[1];
+ numBytesToRead = 2; /*Read PCB + INF LEN*/
+ headerIndex = 0;
+ break;
+ } else if (((pBuffer[0] == 0x00) && (pBuffer[1] == 0x00)) ||
+ ((pBuffer[0] == 0xFF) && (pBuffer[1] == 0xFF))) {
+ // LOG(ERROR) << StringPrintf("_spi_read() Buf[0]: %X Buf[1]: %X",
+ // pBuffer[0], pBuffer[1]);
+ } else if (ret >= 0) { /* Corruption happened during the receipt from
+ Card, go flush out the data */
+ ALOGE("_spi_read() Corruption Buf[0]: %X Buf[1]: %X ..len=%d",
+ pBuffer[0], pBuffer[1], ret);
+ break;
+ }
+ }
+ /*If it is Chained packet wait for 100 usec*/
+ if (poll_sof_chained_delay == 1) {
+ ALOGD_IF(ese_debug_enabled, "%s Chained Pkt, delay read %dus",
+ __FUNCTION__, GET_WAKE_UP_DELAY() * CHAINED_PKT_SCALER);
+ phPalEse_sleep(GET_WAKE_UP_DELAY() * CHAINED_PKT_SCALER);
+ } else {
+ /*DLOG_IF(INFO, ese_debug_enabled)
+ << StringPrintf("%s Normal Pkt, delay read %dus", __FUNCTION__,
+ WAKE_UP_DELAY_SN1xx * NAD_POLLING_SCALER_SN1xx);*/
+ phPalEse_sleep(nxpese_ctxt.nadPollingRetryTime * GET_WAKE_UP_DELAY() *
+ NAD_POLLING_SCALER);
+ }
+ sof_counter++;
+ } while (sof_counter < max_sof_counter);
+
+ /*SOF Read timeout happened, go for frame retransmission*/
+ if (sof_counter == max_sof_counter) {
+ ret = -1;
+ }
+ if (ret < 0) {
+ /*In case of IO Error*/
+ ret = -2;
+ pBuffer[0] = 0x64;
+ pBuffer[1] = 0xFF;
+ } else if ((pBuffer[0] == nxpese_ctxt.nadInfo.nadRx) ||
+ (pBuffer[0] == RECEIVE_PACKET_SOF)) {
+ ALOGD_IF(ese_debug_enabled, "%s SOF FOUND", __FUNCTION__);
+ /* Read the HEADR of one/Two bytes based on how two bytes read A5 PCB or
+ * 00 A5*/
+ ret =
+ phPalEse_read(pDevHandle, &pBuffer[1 + headerIndex], numBytesToRead);
+ if (ret < 0) {
+ ALOGE("_spi_read() [HDR]errno : %x ret : %X", errno, ret);
+ flushData = true;
+ } else {
+ if ((pBuffer[1] == CHAINED_PACKET_WITHOUTSEQN) ||
+ (pBuffer[1] == CHAINED_PACKET_WITHSEQN)) {
+ poll_sof_chained_delay = 1;
+ ALOGD_IF(ese_debug_enabled, "poll_sof_chained_delay value is %d ",
+ poll_sof_chained_delay);
+ } else {
+ poll_sof_chained_delay = 0;
+ ALOGD_IF(ese_debug_enabled, "poll_sof_chained_delay value is %d ",
+ poll_sof_chained_delay);
+ }
+ total_count = 3;
+ uint8_t pcb;
+ phNxpEseProto7816_PCB_bits_t pcb_bits;
+ pcb = pBuffer[PH_PROPTO_7816_PCB_OFFSET];
+
+ phNxpEse_memset(&pcb_bits, 0x00, sizeof(phNxpEseProto7816_PCB_bits_t));
+ phNxpEse_memcpy(&pcb_bits, &pcb, sizeof(uint8_t));
+
+ /*For I-Frame Only*/
+ if (0 == pcb_bits.msb) {
+ if (pBuffer[2] != EXTENDED_FRAME_MARKER) {
+ nNbBytesToRead = pBuffer[2];
+ headerIndex = 3;
+ } else {
+ ret = phPalEse_read(pDevHandle, &pBuffer[3], 2);
+ if (ret < 0) {
+ ALOGE("_spi_read() [HDR]errno : %x ret : %X", errno, ret);
+ flushData = true;
+ } else {
+ nNbBytesToRead = (pBuffer[3] << 8);
+ nNbBytesToRead = nNbBytesToRead | pBuffer[4];
+ /*If I-Frame received with invalid length respond with RNACK*/
+ if ((nNbBytesToRead == 0) || (nNbBytesToRead > MAX_DATA_LEN) ||
+ (nNbBytesToRead > phNxpEseProto7816_GetIfs())) {
+ ALOGD_IF(ese_debug_enabled, "I-Frame with invalid len == %d",
+ nNbBytesToRead);
+ flushData = true;
+ } else {
+ ALOGE("_spi_read() [HDR]EXTENDED_FRAME_MARKER, ret=%d", ret);
+ total_count += 2;
+ headerIndex = 5;
+ }
+ }
+ }
+ } else {
+ /*For Non-IFrame*/
+ nNbBytesToRead = (int)pBuffer[2];
+ headerIndex = 3;
+ }
+ if (!flushData) {
+ /* Read the Complete data + one byte CRC*/
+ ret = phPalEse_read(pDevHandle, &pBuffer[headerIndex],
+ (nNbBytesToRead + 1));
+ if (ret < 0) {
+ ALOGE("_spi_read() [HDR]errno : %x ret : %X", errno, ret);
+ ret = -1;
+ } else {
+ ret = (total_count + (nNbBytesToRead + 1));
+ }
+ nxpese_ctxt.rnack_sent = false;
+ }
+ }
+ } else {
+ flushData = true;
+ }
+ if (flushData) {
+ /* Received corrupted frame:
+ Flushing out data in the Rx buffer so that Card can switch the mode */
+ uint16_t ifsd_size = phNxpEseProto7816_GetIfs();
+ uint32_t total_frame_size = 0;
+ ALOGE("_spi_read() corrupted, IFSD size=%d flushing it out!!", ifsd_size);
+ /* If a non-zero byte is received while polling for NAD byte and the byte
+ is not a valid NAD byte (0xA5 or 0xB4): 1) Read & discard (without
+ de-asserting SPI CS line) : a. Max IFSD size + 5 (remaining four
+ prologue + one LRC bytes) bytes from eSE if max IFS size is greater
+ than 254 bytes OR b. Max IFSD size + 3 (remaining two prologue + one
+ LRC bytes) bytes from eSE if max IFS size is less than 255 bytes.
+ 2) Send R-NACK to request eSE to re-transmit the frame*/
+ if (ifsd_size > IFSC_SIZE_SEND) {
+ total_frame_size = ifsd_size + 4;
+ } else {
+ total_frame_size = ifsd_size + 2;
+ }
+ nxpese_ctxt.rnack_sent = true;
+ phPalEse_sleep(nxpese_ctxt.invalidFrame_Rnack_Delay);
+ ret = phPalEse_read(pDevHandle, &pBuffer[2], total_frame_size);
+ if (ret < 0) {
+ ALOGE("_spi_read() [HDR]errno : %x ret : %X", errno, ret);
+ } else { /* LRC fail expected for this frame to send R-NACK*/
+ ALOGD_IF(
+ ese_debug_enabled,
+ "_spi_read() SUCCESS ret : %X LRC fail excpected for this frame",
+ ret);
+ PH_PAL_ESE_PRINT_PACKET_RX(pBuffer, ret);
+ }
+ pBuffer[0] = 0x90;
+ pBuffer[1] = RECEIVE_PACKET_SOF;
+ ret = 0x02;
+ phPalEse_sleep(nxpese_ctxt.invalidFrame_Rnack_Delay);
+ }
+ } else {
+ ret = phNxpEse_readPacket_legacy(pDevHandle, pBuffer, nNbBytesToRead);
+ }
+ ALOGD_IF(ese_debug_enabled, "%s Exit ret = %d", __FUNCTION__, ret);
+ return ret;
+}
+
+/******************************************************************************
+ * Function phNxpEse_readPacket_legacy
+ *
+ * Description This function Reads requested number of bytes from
+ * pn547 device into given buffer.
+ *
+ * Returns nNbBytesToRead- number of successfully read bytes
+ * -1 - read operation failure
+ *
+ ******************************************************************************/
+static int phNxpEse_readPacket_legacy(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToRead) {
+ int ret = -1;
+ int sof_counter = 0; /* one read may take 1 ms*/
+ int total_count = 0, numBytesToRead = 0, headerIndex = 0;
+ do {
+ sof_counter++;
+ ret = -1;
+ ret = phPalEse_read(pDevHandle, pBuffer, 2);
+ if (ret < 0) {
+ /*Polling for read on spi, hence Debug log*/
+ ALOGD_IF(ese_debug_enabled, "_spi_read() [HDR]errno : %x ret : %X", errno,
+ ret);
+ }
+ if (pBuffer[0] == RECEIVE_PACKET_SOF) {
+ /* Read the HEADR of one byte*/
+ ALOGD_IF(ese_debug_enabled, "%s Read HDR", __FUNCTION__);
+ numBytesToRead = 1;
+ headerIndex = 1;
+ break;
+ } else if (pBuffer[1] == RECEIVE_PACKET_SOF) {
+ /* Read the HEADR of Two bytes*/
+ ALOGD_IF(ese_debug_enabled, "%s Read HDR", __FUNCTION__);
+ pBuffer[0] = RECEIVE_PACKET_SOF;
+ numBytesToRead = 2;
+ headerIndex = 0;
+ break;
+ }
+ /*If it is Chained packet wait for 100 usec*/
+ if (poll_sof_chained_delay == 1) {
+ ALOGD_IF(ese_debug_enabled, "%s Chained Pkt, delay read %dus",
+ __FUNCTION__, GET_WAKE_UP_DELAY() * CHAINED_PKT_SCALER);
+ phPalEse_sleep(GET_WAKE_UP_DELAY() * CHAINED_PKT_SCALER);
+ } else {
+ ALOGD_IF(ese_debug_enabled, "%s Normal Pkt, delay read %dus",
+ __FUNCTION__, GET_WAKE_UP_DELAY() * NAD_POLLING_SCALER);
+ phPalEse_sleep(GET_WAKE_UP_DELAY() * NAD_POLLING_SCALER);
+ }
+ } while (sof_counter < ESE_NAD_POLLING_MAX);
+ if (pBuffer[0] == RECEIVE_PACKET_SOF) {
+ ALOGD_IF(ese_debug_enabled, "%s SOF FOUND", __FUNCTION__);
+ /* Read the HEADR of one/Two bytes based on how two bytes read A5 PCB or
+ * 00 A5*/
+ ret = phPalEse_read(pDevHandle, &pBuffer[1 + headerIndex], numBytesToRead);
+ if (ret < 0) {
+ ALOGE("_spi_read() [HDR]errno : %x ret : %X", errno, ret);
+ }
+ if ((pBuffer[1] == CHAINED_PACKET_WITHOUTSEQN) ||
+ (pBuffer[1] == CHAINED_PACKET_WITHSEQN)) {
+ poll_sof_chained_delay = 1;
+ ALOGD_IF(ese_debug_enabled, "poll_sof_chained_delay value is %d ",
+ poll_sof_chained_delay);
+ } else {
+ poll_sof_chained_delay = 0;
+ ALOGD_IF(ese_debug_enabled, "poll_sof_chained_delay value is %d ",
+ poll_sof_chained_delay);
+ }
+ total_count = 3;
+ nNbBytesToRead = (int)pBuffer[2];
+ /* Read the Complete data + one byte CRC*/
+ ret = phPalEse_read(pDevHandle, &pBuffer[3], (nNbBytesToRead + 1));
+ if (ret < 0) {
+ ALOGE("_spi_read() [HDR]errno : %x ret : %X", errno, ret);
+ ret = -1;
+ } else {
+ ret = (total_count + (nNbBytesToRead + 1));
+ }
+ } else if (ret < 0) {
+ /*In case of IO Error*/
+ ret = -2;
+ pBuffer[0] = 0x64;
+ pBuffer[1] = 0xFF;
+ } else {
+ ret = -1;
+ }
+ return ret;
+}
+
+/******************************************************************************
+ * Function phNxpEse_WriteFrame
+ *
+ * Description This is the actual function which is being called by
+ * phNxpEse_write. This function writes the data to ESE.
+ * It waits till write callback provide the result of write
+ * process.
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if write successful else
+ * ESESTATUS_FAILED(1)
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_WriteFrame(uint32_t data_len, uint8_t* p_data) {
+ ESESTATUS status = ESESTATUS_INVALID_PARAMETER;
+ int32_t dwNoBytesWrRd = 0;
+ ALOGD_IF(ese_debug_enabled, "Enter %s ", __FUNCTION__);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ /* TODO where to set the nad id */
+ p_data[0] = nxpese_ctxt.nadInfo.nadTx;
+ } else {
+ p_data[0] = ESE_NAD_TX;
+ }
+ /* Create local copy of cmd_data */
+ phNxpEse_memcpy(nxpese_ctxt.p_cmd_data, p_data, data_len);
+ nxpese_ctxt.cmd_len = data_len;
+
+ dwNoBytesWrRd = phPalEse_write(nxpese_ctxt.pDevHandle, nxpese_ctxt.p_cmd_data,
+ nxpese_ctxt.cmd_len);
+ if (-1 == dwNoBytesWrRd) {
+ ALOGE(" - Error in SPI Write.....%d\n", errno);
+ status = ESESTATUS_FAILED;
+ } else {
+ status = ESESTATUS_SUCCESS;
+ PH_PAL_ESE_PRINT_PACKET_TX(nxpese_ctxt.p_cmd_data, nxpese_ctxt.cmd_len);
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit %s status %x\n", __FUNCTION__, status);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_getAtr
+ *
+ * Description This function retrieves ATR bytes from 7816-3 layer
+ *Update.
+ *
+ * Returns It returns ESESTATUS_SUCCESS (0) if write successful else
+ * ESESTATUS_FAILED(1
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_getAtr(phNxpEse_data* pATR) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ status = phNxpEseProto7816_getAtr(pATR);
+ } else {
+ ALOGE(" %s - Function not supported\n", __FUNCTION__);
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_setIfs
+ *
+ * Description This function sets the IFS size to 240/254 support JCOP OS
+ *Update.
+ *
+ * Returns Always return ESESTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_setIfs(uint16_t IFS_Size) {
+ phNxpEseProto7816_SetIfs(IFS_Size);
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEse_Sleep
+ *
+ * Description This function suspends execution of the calling thread for
+ * (at least) usec microseconds
+ *
+ * Returns Always return ESESTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_Sleep(uint32_t usec) {
+ phPalEse_sleep(usec);
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEse_memset
+ *
+ * Description This function updates destination buffer with val
+ * data in len size
+ *
+ * Returns Always return ESESTATUS_SUCCESS (0).
+ *
+ ******************************************************************************/
+void* phNxpEse_memset(void* buff, int val, size_t len) {
+ return phPalEse_memset(buff, val, len);
+}
+
+/******************************************************************************
+ * Function phNxpEse_memcpy
+ *
+ * Description This function copies source buffer to destination buffer
+ * data in len size
+ *
+ * Returns Return pointer to allocated memory location.
+ *
+ ******************************************************************************/
+void* phNxpEse_memcpy(void* dest, const void* src, size_t len) {
+ return phPalEse_memcpy(dest, src, len);
+}
+
+/******************************************************************************
+ * Function phNxpEse_Memalloc
+ *
+ * Description This function allocation memory
+ *
+ * Returns Return pointer to allocated memory or NULL.
+ *
+ ******************************************************************************/
+void* phNxpEse_memalloc(uint32_t size) {
+ return phPalEse_memalloc(size);
+ ;
+}
+
+/******************************************************************************
+ * Function phNxpEse_calloc
+ *
+ * Description This is utility function for runtime heap memory allocation
+ *
+ * Returns Return pointer to allocated memory or NULL.
+ *
+ ******************************************************************************/
+void* phNxpEse_calloc(size_t datatype, size_t size) {
+ return phPalEse_calloc(datatype, size);
+}
+
+/******************************************************************************
+ * Function phNxpEse_free
+ *
+ * Description This function de-allocation memory
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+void phNxpEse_free(void* ptr) { return phPalEse_free(ptr); }
+
+/******************************************************************************
+ * Function phNxpEse_GetMaxTimer
+ *
+ * Description This function finds out the max. timer value returned from
+ *JCOP
+ *
+ * Returns void.
+ *
+ ******************************************************************************/
+static void phNxpEse_GetMaxTimer(unsigned long* pMaxTimer) {
+ /* Finding the max. of the timer value */
+ *pMaxTimer = nxpese_ctxt.secureTimerParams.secureTimer1;
+ if (*pMaxTimer < nxpese_ctxt.secureTimerParams.secureTimer2)
+ *pMaxTimer = nxpese_ctxt.secureTimerParams.secureTimer2;
+ *pMaxTimer = (*pMaxTimer < nxpese_ctxt.secureTimerParams.secureTimer3)
+ ? (nxpese_ctxt.secureTimerParams.secureTimer3)
+ : *pMaxTimer;
+
+ /* Converting timer to millisecond from sec */
+ *pMaxTimer = SECOND_TO_MILLISECOND(*pMaxTimer);
+ /* Add extra 5% to the timer */
+ *pMaxTimer +=
+ CONVERT_TO_PERCENTAGE(*pMaxTimer, ADDITIONAL_SECURE_TIME_PERCENTAGE);
+ ALOGD_IF(ese_debug_enabled, "%s Max timer value = %lu", __FUNCTION__,
+ *pMaxTimer);
+ return;
+}
+
+/******************************************************************************
+ * Function phNxpEseP61_DisablePwrCntrl
+ *
+ * Description This function disables eSE GPIO power off/on control
+ * when enabled
+ *
+ * Returns SUCCESS/FAIL.
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_DisablePwrCntrl(void) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ unsigned long maxTimer = 0;
+ ALOGE("%s Enter", __FUNCTION__);
+ phNxpEse_GetMaxTimer(&maxTimer);
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ status = phNxpEse_SPM_DisablePwrControl(maxTimer);
+ if (status != ESESTATUS_SUCCESS) {
+ ALOGE("%s phNxpEseP61_DisablePwrCntrl: failed", __FUNCTION__);
+ }
+ } else {
+ ALOGE("%s phNxpEseP61_DisablePwrCntrl: not supported", __FUNCTION__);
+ status = ESESTATUS_FAILED;
+ }
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_getOsVersion
+ *
+ * Description This function returns OS version from config file &
+ * runtime from ATR response
+ *
+ * Returns SUCCESS/FAIL.
+ *
+ ******************************************************************************/
+phNxpEse_OsVersion_t phNxpEse_getOsVersion() { return sOsVersion; }
+
+/******************************************************************************
+ * Function phNxpEse_setOsVersion
+ *
+ * Description This function sets chip type based on ATR response
+ *
+ * Returns None.
+ *
+ ******************************************************************************/
+void phNxpEse_setOsVersion(phNxpEse_OsVersion_t chipType) {
+ sOsVersion = chipType;
+}
+
+/******************************************************************************
+ * Function phNxpEse_checkFWDwnldStatus
+ *
+ * Description This function is used to check whether FW download
+ * is completed or not.
+ *
+ * Returns returns ESESTATUS_SUCCESS or ESESTATUS_BUSY
+ *
+ ******************************************************************************/
+static ESESTATUS phNxpEse_checkFWDwnldStatus(void) {
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_checkFWDwnldStatus Enter");
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+ uint8_t ese_dwnld_retry = 0x00;
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus == ESESTATUS_SUCCESS) {
+ /* Check current_spm_state and update config/Spm status*/
+ while (ese_dwnld_retry < ESE_FW_DWNLD_RETRY_CNT) {
+ ALOGD_IF(ese_debug_enabled, "ESE_FW_DWNLD_RETRY_CNT retry count");
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus == ESESTATUS_SUCCESS) {
+ if ((current_spm_state & SPM_STATE_DWNLD)) {
+ status = ESESTATUS_FAILED;
+ } else {
+ ALOGE("Exit polling no FW Download ..");
+ status = ESESTATUS_SUCCESS;
+ break;
+ }
+ } else {
+ status = ESESTATUS_FAILED;
+ break;
+ }
+ phNxpEse_Sleep(500000); /*sleep for 500 ms checking for fw dwnld status*/
+ ese_dwnld_retry++;
+ }
+ }
+
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_checkFWDwnldStatus status %x", status);
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_GetEseStatus(unsigned char *timer_buffer)
+ *
+ * Description This function returns the all three timer
+ * Timeout buffer length should be minimum 18 bytes. Response will be in below
+ format:
+ * <0xF1><Len><Timer Value><0xF2><Len><Timer Value><0xF3><Len><Timer Value>
+ *
+ * Returns SUCCESS/FAIL.
+ * ESESTATUS_SUCCESS if 0xF1 or 0xF2 tag timeout >= 0 & 0xF3 == 0
+ * ESESTATUS_BUSY if 0xF3 tag timeout > 0
+ * ESESTATUS_FAILED if any other error
+
+ ******************************************************************************/
+ESESTATUS phNxpEse_GetEseStatus(phNxpEse_data* timer_buffer) {
+ ESESTATUS status = ESESTATUS_FAILED;
+
+ phNxpEse_SecureTimer_t secureTimerParams;
+ uint8_t* temp_timer_buffer = NULL;
+ ALOGD_IF(ese_debug_enabled, "%s Enter", __FUNCTION__);
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ALOGE("%s function not supported", __FUNCTION__);
+ return status;
+ }
+ if (timer_buffer != NULL) {
+ timer_buffer->len =
+ (sizeof(secureTimerParams.secureTimer1) +
+ sizeof(secureTimerParams.secureTimer2) +
+ sizeof(secureTimerParams.secureTimer3)) +
+ PH_PROPTO_7816_FRAME_LENGTH_OFFSET * PH_PROPTO_7816_FRAME_LENGTH_OFFSET;
+ temp_timer_buffer = (uint8_t*)phNxpEse_memalloc(timer_buffer->len);
+ timer_buffer->p_data = temp_timer_buffer;
+
+ phNxpEse_memcpy(&secureTimerParams, &nxpese_ctxt.secureTimerParams,
+ sizeof(phNxpEse_SecureTimer_t));
+
+ ALOGD_IF(
+ ese_debug_enabled,
+ "%s secureTimer1 0x%x secureTimer2 0x%x secureTimer3 0x%x len = %d",
+ __FUNCTION__, secureTimerParams.secureTimer1,
+ secureTimerParams.secureTimer2, secureTimerParams.secureTimer3,
+ timer_buffer->len);
+
+ *temp_timer_buffer++ = PH_PROPTO_7816_SFRAME_TIMER1;
+ *temp_timer_buffer++ = sizeof(secureTimerParams.secureTimer1);
+ temp_timer_buffer = phNxpEse_GgetTimerTlvBuffer(
+ temp_timer_buffer, secureTimerParams.secureTimer1);
+ if (temp_timer_buffer != NULL) {
+ *temp_timer_buffer++ = PH_PROPTO_7816_SFRAME_TIMER2;
+ *temp_timer_buffer++ = sizeof(secureTimerParams.secureTimer2);
+ temp_timer_buffer = phNxpEse_GgetTimerTlvBuffer(
+ temp_timer_buffer, secureTimerParams.secureTimer2);
+ if (temp_timer_buffer != NULL) {
+ *temp_timer_buffer++ = PH_PROPTO_7816_SFRAME_TIMER3;
+ *temp_timer_buffer++ = sizeof(secureTimerParams.secureTimer3);
+ temp_timer_buffer = phNxpEse_GgetTimerTlvBuffer(
+ temp_timer_buffer, secureTimerParams.secureTimer3);
+ if (temp_timer_buffer != NULL) {
+ if (secureTimerParams.secureTimer3 > 0) {
+ status = ESESTATUS_BUSY;
+ } else {
+ status = ESESTATUS_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ ALOGE("%s Invalid timer buffer ", __FUNCTION__);
+ }
+
+ ALOGD_IF(ese_debug_enabled, "%s Exit status = 0x%x", __FUNCTION__, status);
+ return status;
+}
+
+static unsigned char* phNxpEse_GgetTimerTlvBuffer(uint8_t* timer_buffer,
+ unsigned int value) {
+ short int count = 0, shift = 3;
+ unsigned int mask = 0x000000FF;
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ALOGE("%s function not supported", __FUNCTION__);
+ } else {
+ ALOGD_IF(ese_debug_enabled, "value = %x \n", value);
+ for (count = 0; count < 4; count++) {
+ if (timer_buffer != NULL) {
+ *timer_buffer = (value >> (shift * 8) & mask);
+ ALOGD_IF(ese_debug_enabled, "*timer_buffer=0x%x shift=0x%x",
+ *timer_buffer, shift);
+ timer_buffer++;
+ shift--;
+ } else {
+ break;
+ }
+ }
+ }
+ return timer_buffer;
+}
+
+/******************************************************************************
+ * Function phNxpEse_NotifySEWtxRequest
+ *
+ * Description This function notifies SE hal service if it registers
+ * about WTX ongoing & end status
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+void phNxpEse_NotifySEWtxRequest(phNxpEse_wtxState state) {
+ if (nxpese_ctxt.fPtr_WtxNtf) {
+ (nxpese_ctxt.fPtr_WtxNtf)(state);
+ } else {
+ ALOGE("%s function not supported", __FUNCTION__);
+ }
+}
+
+/******************************************************************************
+ * Function phNxpEse_setWtxCountLimit
+ *
+ * Description This function sets the counter limit for wtx
+ *
+ * Returns None
+ *
+ ******************************************************************************/
+void phNxpEse_setWtxCountLimit(unsigned long int wtxCount) {
+ app_wtx_cnt = wtxCount;
+}
diff --git a/snxxx/libese-spi/p73/lib/phNxpEse_Internal.h b/snxxx/libese-spi/p73/lib/phNxpEse_Internal.h
new file mode 100644
index 0000000..83e5667
--- /dev/null
+++ b/snxxx/libese-spi/p73/lib/phNxpEse_Internal.h
@@ -0,0 +1,142 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#ifndef _PHNXPSPILIB_H_
+#define _PHNXPSPILIB_H_
+
+#include <phNxpEse_Api.h>
+
+/* Macro to enable SPM Module */
+#define SPM_INTEGRATED
+//#undef SPM_INTEGRATED
+#ifdef SPM_INTEGRATED
+#include "../spm/phNxpEse_Spm.h"
+#endif
+
+/********************* Definitions and structures *****************************/
+
+typedef enum {
+ ESE_STATUS_CLOSE = 0x00,
+ ESE_STATUS_BUSY,
+ ESE_STATUS_RECOVERY,
+ ESE_STATUS_IDLE,
+ ESE_STATUS_OPEN,
+} phNxpEse_LibStatus;
+
+typedef enum {
+ PN67T_POWER_SCHEME = 0x01,
+ PN80T_LEGACY_SCHEME,
+ PN80T_EXT_PMU_SCHEME,
+} phNxpEse_PowerScheme;
+
+typedef enum {
+ END_POINT_ESE = 0, /*!< eSE services */
+ END_POINT_EUICC, /*!< UICC services*/
+ MAX_END_POINTS
+} phNxpEse_EndPoint;
+
+/* Macros definition */
+#define MAX_DATA_LEN 780
+#define SECOND_TO_MILLISECOND(X) X * 1000
+#define CONVERT_TO_PERCENTAGE(X, Y) X* Y / 100
+#define ADDITIONAL_SECURE_TIME_PERCENTAGE 5
+#define ESE_JCOP_OS_DWNLD_RETRY_CNT \
+ 10 /* Maximum retry count for ESE JCOP OS Dwonload*/
+#define ESE_FW_DWNLD_RETRY_CNT 10 /* Maximum retry count for FW Dwonload*/
+
+/*!
+ * \brief Secure timer values F1, F2, F3
+ *
+ *
+ */
+typedef struct phNxpEse_SecureTimer {
+ unsigned int secureTimer1; /*!< Secure timer 1 value */
+ unsigned int secureTimer2; /*!< Secure timer 2 value */
+ unsigned int secureTimer3; /*!< Secure timer 3 value */
+} phNxpEse_SecureTimer_t;
+
+typedef enum nadInfoTx {
+ ESE_NAD_TX = 0x5A, /*!< R-frame Acknowledgement frame indicator */
+ EUICC_NAD_TX = 0x4B /*!< R-frame Negative-Acknowledgement frame indicator */
+} nadInfoTx_t;
+
+/*!
+ * \brief R-Frame types used in 7816-3 protocol stack
+ */
+typedef enum nadInfoRx {
+ ESE_NAD_RX = 0xA5, /*!< R-frame Acknowledgement frame indicator */
+ EUICC_NAD_RX = 0xB4 /*!< R-frame Negative-Acknowledgement frame indicator */
+} nadInfoRx_t;
+
+/*!
+ * \brief Node address Info structure
+ *
+ *
+ */
+typedef struct phNxpEseNadInfo {
+ nadInfoTx_t nadTx; /*!< nod address for tx */
+ nadInfoRx_t nadRx; /*!< nod address for rx */
+} phNxpEseNadInfo_t;
+
+/* JCOP download states */
+typedef enum jcop_dwnld_state {
+ JCP_DWNLD_IDLE = SPM_STATE_JCOP_DWNLD, /* jcop dwnld is not ongoing*/
+ JCP_DWNLD_INIT = 0x8010, /* jcop dwonload init state*/
+ JCP_DWNLD_START = 0x8020, /* download started */
+ JCP_SPI_DWNLD_COMPLETE = 0x8040, /* jcop download complete in spi interface*/
+ JCP_DWP_DWNLD_COMPLETE = 0x8080, /* jcop download complete */
+} phNxpEse_JcopDwnldState;
+
+/*!
+ * \brief SPI Control structure
+ *
+ *
+ */
+typedef struct phNxpEse_Context {
+ void* pDevHandle; /*!<device handle */
+ long nadPollingRetryTime; /*!<polling retry for nod address */
+ long invalidFrame_Rnack_Delay; /*!<delay before retrying when rnack is
+ received */
+ phNxpEse_LibStatus EseLibStatus; /*!<Indicate if Ese Lib is open or closed */
+ phNxpEse_initParams initParams; /*!<init params */
+ phNxpEse_SecureTimer_t secureTimerParams; /*!<secure timer params */
+ phNxpEseNadInfo_t nadInfo; /*!<nad info */
+ uint8_t p_read_buff[MAX_DATA_LEN]; /*!<read buffer */
+ uint8_t p_cmd_data[MAX_DATA_LEN]; /*!<cmd buffer */
+ uint16_t cmd_len; /*!<cmd buffer length */
+ uint8_t pwr_scheme; /*!<eSE power scheme */
+ uint8_t endPointInfo; /*!<info end point*/
+ bool rnack_sent; /*!<rnack send info */
+ bool spm_power_state; /*!<spm_power_state */
+ NotifyWtxReq* fPtr_WtxNtf; /*!< Wait extension callback notification*/
+} phNxpEse_Context_t;
+
+/* Timeout value to wait for response from
+ Note: Timeout value updated from 1000 to 2000 to fix the JCOP delay (WTX)*/
+#define HAL_EXTNS_WRITE_RSP_TIMEOUT (2000)
+
+#define SPILIB_CMD_CODE_LEN_BYTE_OFFSET (2U)
+#define SPILIB_CMD_CODE_BYTE_LEN (3U)
+
+static nadInfoTx_t nadInfoTx_ptr[MAX_END_POINTS] = {ESE_NAD_TX, EUICC_NAD_TX};
+
+static nadInfoRx_t nadInfoRx_ptr[MAX_END_POINTS] = {ESE_NAD_RX, EUICC_NAD_RX};
+ESESTATUS phNxpEse_WriteFrame(uint32_t data_len, uint8_t* p_data);
+ESESTATUS phNxpEse_read(uint32_t* data_len, uint8_t** pp_data);
+void phNxpEse_setOsVersion(phNxpEse_OsVersion_t chipType);
+
+#endif /* _PHNXPSPILIB_H_ */
diff --git a/snxxx/libese-spi/p73/pal/EseTransport.h b/snxxx/libese-spi/p73/pal/EseTransport.h
new file mode 100644
index 0000000..2929374
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/EseTransport.h
@@ -0,0 +1,139 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+#pragma once
+
+/* Basic type definitions */
+#include <phNxpEsePal.h>
+
+/*!
+ * \brief Start of frame marker
+ */
+#define SEND_PACKET_SOF 0x5A
+/*!
+ * \brief ESE Poll timeout (max 2 seconds)
+ */
+#define ESE_POLL_TIMEOUT (2 * 1000)
+/*!
+ * \brief ESE Max Poll retry count
+ */
+
+#define ESE_NAD_POLLING_MAX (2000)
+
+/*!
+ * \brief ESE wakeup delay in case of write error retry
+ */
+
+#define WAKE_UP_DELAY_USECS 100
+
+#define GET_WAKE_UP_DELAY() \
+ ((GET_CHIP_OS_VERSION() != OS_VERSION_4_0) ? (WAKE_UP_DELAY_USECS) \
+ : (10 * WAKE_UP_DELAY_USECS))
+
+/*!
+ * \brief ESE wakeup delay in case of write error retry
+ */
+
+#define NAD_POLLING_SCALER 1
+
+/*!
+ * \brief ESE wakeup delay in case of write error retry
+ */
+#define CHAINED_PKT_SCALER 1
+/*!
+ * \brief Magic type specific to the ESE device driver
+ */
+#define P61_MAGIC 0xEA
+
+/*!
+ * \brief IOCTL number to set ESE PWR
+ */
+#define P61_SET_PWR _IOW(P61_MAGIC, 0x01, long)
+/*!
+ * \brief IOCTL number to set debug state
+ */
+#define P61_SET_DBG _IOW(P61_MAGIC, 0x02, long)
+/*!
+ * \brief IOCTL number to enable poll mode
+ */
+#define P61_SET_POLL _IOW(P61_MAGIC, 0x03, long)
+/*!
+ * \brief SPI Request NFCC to enable p61 power, only in param
+ * Only for SPI
+ * level 1 = Enable power
+ * level 0 = Disable power
+ */
+#define P61_SET_SPM_PWR _IOW(P61_MAGIC, 0x04, long)
+
+/*!
+ * \brief SPI or DWP can call this ioctl to get the current
+ * power state of P61
+ *
+ */
+#define P61_GET_SPM_STATUS _IOR(P61_MAGIC, 0x05, long)
+/*!
+ * \brief IOCTL to add throughput measurement source code in device driver
+ *
+ */
+#define P61_SET_THROUGHPUT _IOW(P61_MAGIC, 0x06, long)
+/*!
+ * \brief IOCTL to get the ESE access
+ *
+ */
+#define P61_GET_ESE_ACCESS _IOW(P61_MAGIC, 0x07, long)
+/*!
+ * \brief IOCTL to set the power scheme
+ *
+ */
+#define P61_SET_POWER_SCHEME _IOW(P61_MAGIC, 0x08, long)
+/*!
+ * \brief This function is used to set the ESE jcop
+ * download state.
+ */
+#define P61_SET_DWNLD_STATUS _IOW(P61_MAGIC, 0x09, long)
+
+/*!
+ * \brief This function is used to set disable ESE GPIO
+ * state On&Off
+ */
+#define P61_INHIBIT_PWR_CNTRL _IOW(P61_MAGIC, 0x0A, long)
+/*!
+ * \brief IOCTL to set the GPIO for the eSE to distinguish
+ * the logical interface
+ */
+#define ESE_SET_TRUSTED_ACCESS _IOW(P61_MAGIC, 0x0B, long)
+
+/*!
+ * \brief IOCTL to perform the eSE COLD_RESET via NFC driver.
+ */
+#define ESE_PERFORM_COLD_RESET _IOW(P61_MAGIC, 0x0C, long)
+/*!
+ * \brief IOCTL to enable/disable GPIO/COLD reset protection.
+ */
+#define PERFORM_RESET_PROTECTION _IOW(P61_MAGIC, 0x0D, long)
+
+class EseTransport {
+ public:
+ virtual void Close(void* pDevHandle) = 0;
+ virtual ESESTATUS OpenAndConfigure(pphPalEse_Config_t pConfig) = 0;
+ virtual int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) = 0;
+ virtual int Write(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToWrite) = 0;
+ virtual ESESTATUS Ioctl(phPalEse_ControlCode_t eControlCode, void* pDevHandle,
+ long level) = 0;
+ virtual ~EseTransport(){};
+};
diff --git a/snxxx/libese-spi/p73/pal/EseTransportFactory.cpp b/snxxx/libese-spi/p73/pal/EseTransportFactory.cpp
new file mode 100644
index 0000000..d76d987
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/EseTransportFactory.cpp
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright 2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include <EseSpiTransport.h>
+#include <EseTransportFactory.h>
+
+EseTransportFactory::EseTransportFactory() {}
+
+EseTransportFactory& EseTransportFactory::getInstance() {
+ static EseTransportFactory mTransprtFactoryInstance;
+ return mTransprtFactoryInstance;
+}
+
+spTransport EseTransportFactory::getTransport(transportIntf transportType) {
+ spTransport mspTransportInterface;
+ switch (transportType) {
+ case SPI:
+ case UNKNOWN:
+ mspTransportInterface = std::make_shared<EseSpiTransport>();
+ break;
+ default:
+ mspTransportInterface = std::make_shared<EseSpiTransport>();
+ break;
+ }
+ return mspTransportInterface;
+}
diff --git a/snxxx/libese-spi/p73/pal/EseTransportFactory.h b/snxxx/libese-spi/p73/pal/EseTransportFactory.h
new file mode 100644
index 0000000..0a9a876
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/EseTransportFactory.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ *
+ * Copyright 2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include <EseTransport.h>
+#include <memory>
+
+#define transportFactory (EseTransportFactory::getInstance())
+typedef std::shared_ptr<EseTransport> spTransport;
+enum transportIntf { SPI, UNKNOWN };
+
+extern spTransport gpTransportObj;
+class EseTransportFactory {
+ /*****************************************************************************
+ **
+ ** Function EseTransportFactory
+ **
+ ** Description Constructor for transportFactory. This will be private to
+ ** support singleton
+ **
+ ** Parameters none
+ **
+ ** Returns none
+ ****************************************************************************/
+ EseTransportFactory();
+
+ public:
+ /*****************************************************************************
+ **
+ ** Function getInstance
+ **
+ ** Description returns the static instance of TransportFactory
+ **
+ ** Parameters none
+ **
+ ** Returns TransportFactory instance
+ ****************************************************************************/
+ static EseTransportFactory& getInstance();
+
+ /*****************************************************************************
+ **
+ ** Function getTransport
+ **
+ ** Description selects and returns transport channel based on the input
+ ** parameter
+ **
+ ** Parameters Required transport Type
+ **
+ ** Returns Selected transport channel
+ ****************************************************************************/
+ spTransport getTransport(transportIntf transportType);
+};
diff --git a/snxxx/libese-spi/p73/pal/phNxpEsePal.cpp b/snxxx/libese-spi/p73/pal/phNxpEsePal.cpp
new file mode 100755
index 0000000..7e23305
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/phNxpEsePal.cpp
@@ -0,0 +1,314 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * DAL spi port implementation for linux
+ *
+ * Project: Trusted ESE Linux
+ *
+ */
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <EseTransportFactory.h>
+#include <ese_config.h>
+#include <phEseStatus.h>
+#include <string.h>
+
+/*!
+ * \brief Normal mode header length
+ */
+#define NORMAL_MODE_HEADER_LEN 3
+/*!
+ * \brief Normal mode header offset
+ */
+#define NORMAL_MODE_LEN_OFFSET 2
+/*!
+ * \brief Start of frame marker
+ */
+#define SEND_PACKET_SOF 0x5A
+/*!
+ * \brief To enable SPI interface for ESE communication
+ */
+#define SPI_ENABLED 1
+
+spTransport gpTransportObj;
+
+/*******************************************************************************
+**
+** Function phPalEse_close
+**
+** Description Closes PN547 device
+**
+** Parameters pDevHandle - device handle
+**
+** Returns None
+**
+*******************************************************************************/
+void phPalEse_close(void* pDevHandle) {
+ if (NULL != pDevHandle) {
+ gpTransportObj->Close(pDevHandle);
+ }
+ gpTransportObj = NULL;
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_open_and_configure
+**
+** Description Open and configure ESE device
+**
+** Parameters pConfig - hardware information
+**
+** Returns ESE status:
+** ESESTATUS_SUCCESS - open_and_configure operation
+*success
+** ESESTATUS_INVALID_DEVICE - device open operation failure
+**
+*******************************************************************************/
+ESESTATUS phPalEse_open_and_configure(pphPalEse_Config_t pConfig) {
+ ESESTATUS status = ESESTATUS_FAILED;
+ if (ESESTATUS_SUCCESS != phPalEse_ConfigTransport()) return ESESTATUS_FAILED;
+ status = gpTransportObj->OpenAndConfigure(pConfig);
+ return status;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_ConfigTransport
+**
+** Description Configure Transport channel based on transport type provided
+** in config file
+**
+** Returns ESESTATUS_SUCCESS If transport channel is configured
+** ESESTATUS_FAILED If transport channel configuration failed
+**
+*******************************************************************************/
+ESESTATUS phPalEse_ConfigTransport() {
+ unsigned long transportType = UNKNOWN;
+
+ transportType = EseConfig::getUnsigned(NAME_NXP_TRANSPORT, UNKNOWN);
+ ALOGD("phPalEse_ConfigTransport transport type %ld", transportType);
+ gpTransportObj = transportFactory.getTransport((transportIntf)transportType);
+ if (gpTransportObj == nullptr) {
+ return ESESTATUS_FAILED;
+ }
+ return ESESTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_read
+**
+** Description Reads requested number of bytes from pn547 device into given
+*buffer
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToRead - number of bytes requested to be read
+**
+** Returns numRead - number of successfully read bytes
+** -1 - read operation failure
+**
+*******************************************************************************/
+int phPalEse_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead) {
+ int ret = -1;
+ ret = gpTransportObj->Read(pDevHandle, pBuffer, nNbBytesToRead);
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_write
+**
+** Description Writes requested number of bytes from given buffer into
+*pn547 device
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToWrite - number of bytes requested to be written
+**
+** Returns numWrote - number of successfully written bytes
+** -1 - write operation failure
+**
+*******************************************************************************/
+int phPalEse_write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite) {
+ int numWrote = 0;
+
+ if (NULL == pDevHandle) {
+ return -1;
+ }
+ numWrote = gpTransportObj->Write(pDevHandle, pBuffer, nNbBytesToWrite);
+ return numWrote;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_ioctl
+**
+** Description Exposed ioctl by p61 spi driver
+**
+** Parameters pDevHandle - valid device handle
+** level - reset level
+**
+** Returns 0 - ioctl operation success
+** -1 - ioctl operation failure
+**
+*******************************************************************************/
+ESESTATUS phPalEse_ioctl(phPalEse_ControlCode_t eControlCode, void* pDevHandle,
+ long level) {
+ ESESTATUS ret = ESESTATUS_FAILED;
+ ALOGD_IF(ese_debug_enabled, "phPalEse_spi_ioctl(), ioctl %x , level %lx",
+ eControlCode, level);
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ if (NULL == pDevHandle) {
+ return ESESTATUS_IOCTL_FAILED;
+ }
+ }
+ if (pDevHandle == NULL) {
+ phPalEse_ConfigTransport();
+ }
+ ret = gpTransportObj->Ioctl(eControlCode, pDevHandle, level);
+ if (pDevHandle == NULL) {
+ phPalEse_close(pDevHandle);
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_print_packet
+**
+** Description Print packet
+**
+** Returns None
+**
+*******************************************************************************/
+void phPalEse_print_packet(const char* pString, const uint8_t* p_data,
+ uint16_t len) {
+ uint32_t i;
+ char print_buffer[len * 3 + 1];
+
+ memset(print_buffer, 0, sizeof(print_buffer));
+ for (i = 0; i < len; i++) {
+ snprintf(&print_buffer[i * 2], 3, "%02X", p_data[i]);
+ }
+ if (0 == memcmp(pString, "SEND", 0x04)) {
+ ALOGD_IF(ese_debug_enabled, "NxpEseDataX len = %3d > %s", len,
+ print_buffer);
+ } else if (0 == memcmp(pString, "RECV", 0x04)) {
+ ALOGD_IF(ese_debug_enabled, "NxpEseDataR len = %3d > %s", len,
+ print_buffer);
+ }
+
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_sleep
+**
+** Description This function suspends execution of the calling thread for
+** (at least) usec microseconds
+**
+** Returns None
+**
+*******************************************************************************/
+void phPalEse_sleep(long usec) {
+ usleep(usec);
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_memset
+**
+** Description
+**
+** Returns None
+**
+*******************************************************************************/
+
+void* phPalEse_memset(void* buff, int val, size_t len) {
+ return memset(buff, val, len);
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_memcpy
+**
+** Description
+**
+** Returns None
+**
+*******************************************************************************/
+
+void* phPalEse_memcpy(void* dest, const void* src, size_t len) {
+ return memcpy(dest, src, len);
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_memalloc
+**
+** Description
+**
+** Returns None
+**
+*******************************************************************************/
+
+void* phPalEse_memalloc(uint32_t size) { return malloc(size); }
+
+/*******************************************************************************
+**
+** Function phPalEse_calloc
+**
+** Description
+**
+** Returns None
+**
+*******************************************************************************/
+
+void* phPalEse_calloc(size_t datatype, size_t size) {
+ return calloc(datatype, size);
+}
+
+/*******************************************************************************
+**
+** Function phPalEse_free
+**
+** Description
+**
+** Returns None
+**
+*******************************************************************************/
+void phPalEse_free(void* ptr) {
+ if (ptr != NULL) {
+ free(ptr);
+ ptr = NULL;
+ }
+ return;
+}
diff --git a/snxxx/libese-spi/p73/pal/phNxpEsePal.h b/snxxx/libese-spi/p73/pal/phNxpEsePal.h
new file mode 100644
index 0000000..d6d06cf
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/phNxpEsePal.h
@@ -0,0 +1,247 @@
+/******************************************************************************
+ *
+ * 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.
+ * 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.
+ *
+ ******************************************************************************/
+
+/**
+ * \addtogroup eSe_PAL
+ * \brief PAL implementation
+ * @{ */
+
+#ifndef _PHNXPESE_PAL_H
+#define _PHNXPESE_PAL_H
+
+/* Basic type definitions */
+#include <errno.h>
+#include <phEseStatus.h>
+#include <phNxpEseFeatures.h>
+#include <stdint.h>
+/*!
+ * \brief Value indicates to reset device
+ */
+#define PH_PALESE_RESETDEVICE (0x00008001)
+
+/*!
+ * \ingroup eSe_PAL
+ *
+ * \brief Enum definition contains supported ioctl control codes.
+ *
+ * phPalEse_IoCtl
+ */
+typedef enum {
+ phPalEse_e_Invalid = 0, /*!< Invalid control code */
+ phPalEse_e_ResetDevice = PH_PALESE_RESETDEVICE, /*!< Reset the device */
+ phPalEse_e_EnableLog, /*!< Enable the spi driver logs */
+ phPalEse_e_EnablePollMode, /*!< Enable the polling for SPI */
+ phPalEse_e_GetEseAccess, /*!< get the bus access in specified timeout */
+ phPalEse_e_ChipRst, /*!< eSE Chip reset using ISO RST pin*/
+ phPalEse_e_EnableThroughputMeasurement, /*!< Enable throughput measurement */
+ phPalEse_e_SetPowerScheme, /*!< Set power scheme */
+ phPalEse_e_GetSPMStatus, /*!< Get SPM(power mgt) status */
+ phPalEse_e_DisablePwrCntrl,
+ phPalEse_e_SetJcopDwnldState, /*!< Set Jcop Download state */
+ phPalEse_e_SetClientUpdateState, /*!< Set Jcop Download state */
+ phPalEse_e_SetSecureMode, /*!< Set the Trusted SE Mode */
+ phPalEse_e_ResetProtection,
+} phPalEse_ControlCode_t; /*!< Control code for IOCTL call */
+
+/*!
+ * \ingroup eSe_PAL
+ *
+ * \brief PAL Configuration exposed to upper layer.
+ */
+typedef struct phPalEse_Config {
+ int8_t* pDevName;
+ /*!< Port name connected to ESE
+ *
+ * Platform specific canonical device name to which ESE is connected.
+ *
+ * e.g. On Linux based systems this would be /dev/p73
+ */
+
+ uint32_t dwBaudRate;
+ /*!< Communication speed between DH and ESE
+ *
+ * This is the baudrate of the bus for communication between DH and ESE
+ */
+
+ void* pDevHandle;
+ /*!< Device handle output */
+} phPalEse_Config_t, *pphPalEse_Config_t; /* pointer to phPalEse_Config_t */
+
+/* Function declarations */
+/**
+ * \ingroup eSe_PAL
+ * \brief This function is used to close the ESE device
+ *
+ * \retval None
+ *
+ */
+void phPalEse_close(void* pDevHandle);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief Open and configure ESE device
+ *
+ * \param[in] pConfig: Config to open the device
+ *
+ * \retval ESESTATUS On Success ESESTATUS_SUCCESS else proper error code
+ *
+ */
+ESESTATUS phPalEse_open_and_configure(pphPalEse_Config_t pConfig);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief ConfigTransport to get SPI terminal
+ *
+ * \retval ESESTATUS On Success ESESTATUS_SUCCESS else proper error code
+ *
+ */
+ESESTATUS phPalEse_ConfigTransport();
+
+/**
+ * \ingroup eSe_PAL
+ * \brief Reads requested number of bytes from ESE into given buffer
+ *
+ * \param[in] pDevHandle - valid device handle
+ **\param[in] pBuffer - buffer for read data
+ **\param[in] nNbBytesToRead - number of bytes requested to be read
+ *
+ * \retval numRead - number of successfully read bytes.
+ * \retval -1 - read operation failure
+ *
+ */
+int phPalEse_read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief Writes requested number of bytes from given buffer into pn547 device
+ *
+ * \param[in] pDevHandle - valid device handle
+ * \param[in] pBuffer - buffer to write
+ * \param[in] nNbBytesToWrite - number of bytes to write
+ *
+ * \retval numWrote - number of successfully written bytes
+ * \retval -1 - write operation failure
+ *
+ */
+int phPalEse_write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief Exposed ioctl by ESE driver
+ *
+ * \param[in] eControlCode - phPalEse_ControlCode_t for the respective
+ *configs
+ * \param[in] pDevHandle - valid device handle
+ * \param[in] level - reset level
+ *
+ * \retval 0 - ioctl operation success
+ * \retval -1 - ioctl operation failure
+ *
+ */
+ESESTATUS phPalEse_ioctl(phPalEse_ControlCode_t eControlCode, void* pDevHandle,
+ long level);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief Print packet data
+ *
+ * \param[in] pString - String to be printed
+ * \param[in] p_data - data to be printed
+ * \param[in] len - Length of data to be printed
+ *
+ * \retval void
+ *
+ */
+void phPalEse_print_packet(const char* pString, const uint8_t* p_data,
+ uint16_t len);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief This function suspends execution of the calling thread for
+ * (at least) usec microseconds
+ *
+ * \param[in] usec - number of micro seconds to sleep
+ *
+ * \retval void
+ *
+ */
+void phPalEse_sleep(long usec);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief This function updates destination buffer with val
+ * data in len size
+ *
+ * \param[in] buff - Array to be updated
+ * \param[in] val - value to be updated
+ * \param[in] len - length of array to be updated
+ *
+ * \retval void
+ *
+ */
+void* phPalEse_memset(void* buff, int val, size_t len);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief This function copies source buffer to destination buffer
+ * data in len size
+ *
+ * \param[in] dest - Destination array to be updated
+ * \param[in] src - Source array to be updated
+ * \param[in] len - length of array to be updated
+ *
+ * \retval void
+ *
+ */
+void* phPalEse_memcpy(void* dest, const void* src, size_t len);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief This is utility function for runtime heap memory allocation
+ *
+ * \param[in] size - number of bytes to be allocated
+ *
+ * \retval void
+ *
+ */
+void* phPalEse_memalloc(uint32_t size);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief This is utility function for runtime heap memory allocation
+ *
+ * \param[in] dataType - type of data
+ * \param[in] size - number of bytes to be allocated
+ * \retval void
+ *
+ */
+void* phPalEse_calloc(size_t dataType, size_t size);
+
+/**
+ * \ingroup eSe_PAL
+ * \brief This is utility function for freeeing heap memory allocated
+ *
+ * \param[in] ptr - Address pointer to previous allocation
+ *
+ * \retval void
+ *
+ */
+void phPalEse_free(void* ptr);
+
+/** @} */
+#endif /* _PHNXPESE_PAL_H */
diff --git a/snxxx/libese-spi/p73/pal/spi/EseSpiTransport.cpp b/snxxx/libese-spi/p73/pal/spi/EseSpiTransport.cpp
new file mode 100644
index 0000000..859298e
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/spi/EseSpiTransport.cpp
@@ -0,0 +1,503 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * DAL spi port implementation for linux
+ *
+ * Project: Trusted ESE Linux
+ *
+ */
+
+#include "EseSpiTransport.h"
+
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#include <ese_config.h>
+#include <hardware/nfc.h>
+#include <phEseStatus.h>
+#include <phNxpEsePal.h>
+#include <string.h>
+#include "NfcAdaptation.h"
+#include "hal_nxpese.h"
+#include "phNxpEse_Api.h"
+
+#define MAX_RETRY_CNT 10
+#define HAL_NFC_SPI_DWP_SYNC 21
+
+extern int omapi_status;
+
+static int rf_status;
+#if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
+eseIoctlData_t eseioctldata;
+#endif
+// Default max retry count for SPI CLT write blocked in secs
+static unsigned long int gsMaxSpiWriteRetryCnt = 10;
+#if (NFC_NXP_ESE_VER == JCOP_VER_4_0)
+static ESESTATUS phNxpEse_spiIoctl_legacy(uint64_t ioctlType, void* p_data);
+#endif
+
+/*******************************************************************************
+**
+** Function phPalEse_spi_close
+**
+** Description Closes PN547 device
+**
+** Parameters pDevHandle - device handle
+**
+** Returns None
+**
+*******************************************************************************/
+void EseSpiTransport::Close(void* pDevHandle) {
+ if (NULL != pDevHandle) {
+ close((intptr_t)pDevHandle);
+ }
+ return;
+}
+
+/*******************************************************************************
+**
+** Function phNxpEse_spiIoctl
+**
+** Description Perform cross HAL IOCTL functionality
+**
+** Parameters ioctlType, input data
+**
+** Returns SUCCESS/FAIL
+**
+*******************************************************************************/
+ESESTATUS phNxpEse_spiIoctl(uint64_t ioctlType, void* p_data) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ if (!p_data) {
+ ALOGE("halimpl phNxpEse_spiIoctl p_data is null ioctltyp: %ld",
+ (long)ioctlType);
+ return ESESTATUS_FAILED;
+ }
+#if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
+ ese_nxp_IoctlInOutData_t* inpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
+ switch (ioctlType) {
+ case HAL_ESE_IOCTL_RF_STATUS_UPDATE:
+ rf_status = inpOutData->inp.data.nxpCmd.p_cmd[0];
+ if (rf_status == 1) {
+ ALOGD_IF(
+ ese_debug_enabled,
+ "******************RF IS ON*************************************");
+ } else {
+ ALOGD_IF(
+ ese_debug_enabled,
+ "******************RF IS OFF*************************************");
+ }
+ break;
+ case HAL_ESE_IOCTL_NFC_JCOP_DWNLD:
+
+ eseioctldata.nfc_jcop_download_state =
+ inpOutData->inp.data.nxpCmd.p_cmd[0];
+ if (eseioctldata.nfc_jcop_download_state == 1) {
+ ALOGD_IF(ese_debug_enabled,
+ "******************JCOP Download "
+ "started*************************************");
+ } else {
+ ALOGD_IF(ese_debug_enabled,
+ "******************JCOP Download "
+ "stopped*************************************");
+ }
+ break;
+ default:
+ ALOGD_IF(ese_debug_enabled, "Invalid IOCTL type");
+ break;
+ }
+#endif
+#if (NFC_NXP_ESE_VER == JCOP_VER_4_0)
+ status = phNxpEse_spiIoctl_legacy(ioctlType, p_data);
+#endif
+ return status;
+}
+#if (NFC_NXP_ESE_VER == JCOP_VER_4_0)
+/*******************************************************************************
+**
+** Function phNxpEse_spiIoctl_legacy
+**
+** Description Perform cross HAL IOCTL functionality
+**
+** Parameters ioctlType, input data
+**
+** Returns SUCCESS/FAIL
+**
+*******************************************************************************/
+static ESESTATUS phNxpEse_spiIoctl_legacy(uint64_t ioctlType, void* p_data) {
+ ese_nxp_IoctlInOutData_t* inpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
+ switch (ioctlType) {
+ case HAL_ESE_IOCTL_RF_STATUS_UPDATE:
+
+ rf_status = inpOutData->inp.data.nxpCmd.p_cmd[0];
+ if (rf_status == 1) {
+ ALOGD_IF(
+ ese_debug_enabled,
+ "******************RF IS ON*************************************");
+ } else {
+ ALOGD_IF(
+ ese_debug_enabled,
+ "******************RF IS OFF*************************************");
+ }
+ break;
+ default:
+ ALOGD_IF(ese_debug_enabled, "Invalid IOCTL type");
+ break;
+ }
+ return ESESTATUS_SUCCESS;
+}
+#endif
+
+/*******************************************************************************
+**
+** Function OpenAndConfigure
+**
+** Description Open and configure pn547 device
+**
+** Parameters pConfig - hardware information
+** pLinkHandle - device handle
+**
+** Returns ESE status:
+** ESESTATUS_SUCCESS - open_and_configure operation
+*success
+** ESESTATUS_INVALID_DEVICE - device open operation failure
+**
+*******************************************************************************/
+ESESTATUS EseSpiTransport::OpenAndConfigure(pphPalEse_Config_t pConfig) {
+ int nHandle;
+ int retryCnt = 0;
+ ALOGD("NxpEse EseSpiTransport::OpenAndConfigure 1");
+ if (EseConfig::hasKey(NAME_NXP_SOF_WRITE)) {
+ mConfigSofWrite = EseConfig::getUnsigned(NAME_NXP_SOF_WRITE);
+ ALOGD_IF(ese_debug_enabled, "NXP_SOF_WRITE value from config file = %ld",
+ mConfigSofWrite);
+ }
+ if (EseConfig::hasKey(NAME_NXP_SPI_WRITE_TIMEOUT)) {
+ mConfigSpiWriteTimeout = EseConfig::getUnsigned(NAME_NXP_SPI_WRITE_TIMEOUT);
+ ALOGD_IF(ese_debug_enabled,
+ "NXP_SPI_WRITE_TIMEOUT value from config file = %ld",
+ mConfigSpiWriteTimeout);
+ }
+ /* Read eSE cold reset interface from ese config file */
+ if (EseConfig::hasKey(NAME_NXP_P61_COLD_RESET_INTERFACE)) {
+ mConfigColdResetIntf =
+ EseConfig::getUnsigned(NAME_NXP_P61_COLD_RESET_INTERFACE);
+ ALOGD_IF(ese_debug_enabled,
+ "mConfigColdResetIntf value from config file = %ld",
+ mConfigColdResetIntf);
+ } else {
+ mConfigColdResetIntf = 0x01; /* Default interface is NFC HAL */
+ ALOGD_IF(ese_debug_enabled, "mConfigColdResetIntf: Default value ");
+ }
+ ALOGD_IF(ese_debug_enabled, "Opening port=%s\n", pConfig->pDevName);
+/* open port */
+retry:
+ nHandle = open((char const*)pConfig->pDevName, O_RDWR);
+ if (nHandle < 0) {
+ ALOGE("%s : failed errno = 0x%x, retval %x", __FUNCTION__, errno, nHandle);
+
+ if ((errno == -EBUSY) || (errno == EBUSY)) {
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ phPalEse_sleep(100 * 1000); // 100ms delay
+ return ESESTATUS_DRIVER_BUSY;
+ } else {
+ retryCnt++;
+ ALOGE("Retry open eSE driver, retry cnt : %d", retryCnt);
+ if (retryCnt < MAX_RETRY_CNT) {
+ phPalEse_sleep(1000000);
+ goto retry;
+ }
+ }
+ }
+ ALOGE("_spi_open() Failed: retval %x", nHandle);
+ pConfig->pDevHandle = NULL;
+ return ESESTATUS_INVALID_DEVICE;
+ }
+ ALOGD_IF(ese_debug_enabled, "eSE driver opened :: fd = [%d]", nHandle);
+ pConfig->pDevHandle = (void*)((intptr_t)nHandle);
+ return ESESTATUS_SUCCESS;
+}
+
+/*******************************************************************************
+**
+** Function Read
+**
+** Description Reads requested number of bytes from pn547 device into given
+*buffer
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToRead - number of bytes requested to be read
+**
+** Returns numRead - number of successfully read bytes
+** -1 - read operation failure
+**
+*******************************************************************************/
+int EseSpiTransport::Read(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToRead) {
+ int ret = -1;
+ ret = read((intptr_t)pDevHandle, (void*)pBuffer, (nNbBytesToRead));
+ return ret;
+}
+
+/*******************************************************************************
+**
+** Function Write
+**
+** Description Writes requested number of bytes from given buffer into
+*pn547 device
+**
+** Parameters pDevHandle - valid device handle
+** pBuffer - buffer for read data
+** nNbBytesToWrite - number of bytes requested to be written
+**
+** Returns numWrote - number of successfully written bytes
+** -1 - write operation failure
+**
+*******************************************************************************/
+int EseSpiTransport::Write(void* pDevHandle, uint8_t* pBuffer,
+ int nNbBytesToWrite) {
+ int ret = -1;
+ int numWrote = 0;
+ unsigned long int retryCount = 0;
+ if (NULL == pDevHandle) {
+ ALOGE("phPalEse_spi_write: received pDevHandle=NULL");
+ return -1;
+ }
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ if (mConfigSofWrite == 1) {
+ /* Appending SOF for SPI write */
+ pBuffer[0] = SEND_PACKET_SOF;
+ } else {
+ /* Do Nothing */
+ }
+ }
+ ALOGE("NXP_SPI_WRITE_TIMEOUT value is... : %ld secs", mConfigSpiWriteTimeout);
+ if (mConfigSpiWriteTimeout > 0) {
+ gsMaxSpiWriteRetryCnt = mConfigSpiWriteTimeout;
+ ALOGE(" spi_write_timeout Wait time ... : %ld", gsMaxSpiWriteRetryCnt);
+ } else {
+ /* Do Nothing */
+ }
+
+ while (numWrote < nNbBytesToWrite) {
+ // usleep(5000);
+ if (rf_status == 0) {
+ ret = write((intptr_t)pDevHandle, pBuffer + numWrote,
+ nNbBytesToWrite - numWrote);
+ } else {
+ ret = -1;
+ }
+ if (ret > 0) {
+ numWrote += ret;
+ } else if (ret == 0) {
+ ALOGE("_spi_write() EOF");
+ return -1;
+ } else {
+ ALOGE("_spi_write() errno : %x", errno);
+ ALOGD_IF(ese_debug_enabled, "rf_status value is %d", rf_status);
+ if ((errno == EINTR || errno == EAGAIN || rf_status == 1) &&
+ (retryCount < gsMaxSpiWriteRetryCnt)) {
+ /*Configure retry count or timeout here,now its configured for 2*10
+ * secs*/
+ if (retryCount > gsMaxSpiWriteRetryCnt) {
+ ret = -1;
+ break;
+ }
+
+ retryCount++;
+ /* 5ms delay to give ESE wake up delay */
+ phPalEse_sleep(1000 * (GET_WAKE_UP_DELAY()));
+ ALOGE("_spi_write() failed. Going to retry, counter:%ld !", retryCount);
+ continue;
+ }
+ return -1;
+ }
+ }
+ return numWrote;
+}
+
+/*******************************************************************************
+**
+** Function Ioctl
+**
+** Description Exposed ioctl by p61 spi driver
+**
+** Parameters pDevHandle - valid device handle
+** level - reset level
+**
+** Returns 0 - ioctl operation success
+** -1 - ioctl operation failure
+**
+*******************************************************************************/
+ESESTATUS EseSpiTransport::Ioctl(phPalEse_ControlCode_t eControlCode,
+ void* pDevHandle, long level) {
+ ESESTATUS ret = ESESTATUS_IOCTL_FAILED;
+ int retioctl = 0x00;
+#if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
+ ese_nxp_IoctlInOutData_t inpOutData;
+ inpOutData.inp.level = level;
+ NfcAdaptation& pNfcAdapt = NfcAdaptation::GetInstance();
+#endif
+ ALOGD_IF(ese_debug_enabled, "phPalEse_spi_ioctl(), ioctl %x , level %lx",
+ eControlCode, level);
+ if (NULL == pDevHandle) {
+ if (GET_CHIP_OS_VERSION() == OS_VERSION_4_0) {
+ return ESESTATUS_IOCTL_FAILED;
+ }
+ }
+ switch (eControlCode) {
+ case phPalEse_e_ResetDevice:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_PWR, level);
+ }
+ break;
+
+ case phPalEse_e_EnableLog:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_DBG, level);
+ }
+ break;
+
+ case phPalEse_e_EnablePollMode:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_POLL, level);
+ }
+ break;
+ case phPalEse_e_SetSecureMode:
+ ret =
+ (ESESTATUS)ioctl((intptr_t)pDevHandle, ESE_SET_TRUSTED_ACCESS, level);
+ if (0x00 <= ret) {
+ ret = ESESTATUS_SUCCESS;
+ }
+ break;
+ case phPalEse_e_ChipRst:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ if (level == 5) { // SPI driver communication part
+ if (!mConfigColdResetIntf) { /* Call the driver IOCTL */
+ retioctl =
+ ioctl((intptr_t)pDevHandle, ESE_PERFORM_COLD_RESET, level);
+ if (0x00 <= retioctl) {
+ ret = ESESTATUS_SUCCESS;
+ }
+ } else {
+#if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
+ // Nfc Driver communication part
+ ret = pNfcAdapt.resetEse(level);
+#else
+ ret = ESESTATUS_SUCCESS;
+#endif
+ }
+ } else {
+ ret = ESESTATUS_SUCCESS;
+ }
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_SPM_PWR, level);
+ }
+ break;
+ case phPalEse_e_ResetProtection:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ retioctl = ioctl((intptr_t)pDevHandle, PERFORM_RESET_PROTECTION, level);
+ if (0x00 <= retioctl) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ALOGE("phPalEse_e_ResetProtection ioctl failed status :%x !",
+ retioctl);
+ }
+ }
+ break;
+ case phPalEse_e_EnableThroughputMeasurement:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_THROUGHPUT, level);
+ }
+ break;
+
+ case phPalEse_e_SetPowerScheme:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret =
+ (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_POWER_SCHEME, level);
+ }
+ break;
+
+ case phPalEse_e_GetSPMStatus:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_GET_SPM_STATUS, level);
+ }
+ break;
+
+ case phPalEse_e_GetEseAccess:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret = (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_GET_ESE_ACCESS, level);
+ }
+ break;
+ case phPalEse_e_SetJcopDwnldState:
+ if (GET_CHIP_OS_VERSION() != OS_VERSION_4_0) {
+ ret = ESESTATUS_SUCCESS;
+ } else {
+ ret =
+ (ESESTATUS)ioctl((intptr_t)pDevHandle, P61_SET_DWNLD_STATUS, level);
+ }
+ break;
+#if (NFC_NXP_ESE_VER == JCOP_VER_5_x)
+ case phPalEse_e_SetClientUpdateState: {
+ pNfcAdapt.Initialize();
+ ALOGD_IF(ese_debug_enabled,
+ "phPalEse_spi_ioctl state = phPalEse_e_SetJcopDwnldState");
+ ese_nxp_IoctlInOutData_t inpOutData;
+ memset(&inpOutData, 0x00, sizeof(ese_nxp_IoctlInOutData_t));
+ inpOutData.inp.data.nxpCmd.cmd_len = 1;
+ inpOutData.inp.data_source = 1;
+ uint8_t data = (uint8_t)level;
+ memcpy(inpOutData.inp.data.nxpCmd.p_cmd, &data, sizeof(data));
+ ALOGD_IF(ese_debug_enabled, "Before phPalEse_e_SetClientUpdateState");
+
+ ret = pNfcAdapt.setEseUpdateState(&inpOutData);
+ ALOGD_IF(ese_debug_enabled, "After phPalEse_e_SetClientUpdateState");
+ } break;
+#endif
+ case phPalEse_e_DisablePwrCntrl:
+ ret = ESESTATUS_SUCCESS;
+ break;
+ default:
+ ret = ESESTATUS_IOCTL_FAILED;
+ break;
+ }
+ ALOGD_IF(ese_debug_enabled, "Exit phPalEse_spi_ioctl : ret = %d errno = %d",
+ ret, errno);
+ return (ESESTATUS)ret;
+}
diff --git a/snxxx/libese-spi/p73/pal/spi/EseSpiTransport.h b/snxxx/libese-spi/p73/pal/spi/EseSpiTransport.h
new file mode 100644
index 0000000..2d252c2
--- /dev/null
+++ b/snxxx/libese-spi/p73/pal/spi/EseSpiTransport.h
@@ -0,0 +1,34 @@
+/******************************************************************************
+ *
+ * Copyright 2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#pragma once
+#include "EseTransport.h"
+
+class EseSpiTransport : public EseTransport {
+ public:
+ void Close(void* pDevHandle);
+ ESESTATUS OpenAndConfigure(pphPalEse_Config_t pConfig);
+ int Read(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToRead);
+ int Write(void* pDevHandle, uint8_t* pBuffer, int nNbBytesToWrite);
+ ESESTATUS Ioctl(phPalEse_ControlCode_t eControlCode, void* pDevHandle,
+ long level);
+
+ private:
+ unsigned long int mConfigSofWrite, mConfigSpiWriteTimeout,
+ mConfigColdResetIntf;
+}; \ No newline at end of file
diff --git a/snxxx/libese-spi/p73/spm/phNxpEse_Spm.cpp b/snxxx/libese-spi/p73/spm/phNxpEse_Spm.cpp
new file mode 100755
index 0000000..836c24b
--- /dev/null
+++ b/snxxx/libese-spi/p73/spm/phNxpEse_Spm.cpp
@@ -0,0 +1,476 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NxpEseHal"
+#include <log/log.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <phNxpEsePal.h>
+#include <phNxpEse_Internal.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "phNxpEseFeatures.h"
+#include "phNxpEse_Spm.h"
+
+/*********************** Global Variables *************************************/
+
+static void* pEseDeviceHandle = NULL;
+#define MAX_ESE_ACCESS_TIME_OUT_MS 2000 /*2 seconds*/
+
+/**
+ * \addtogroup SPI_Power_Management
+ *
+ * @{ */
+/******************************************************************************
+\section Introduction Introduction
+
+ * This module provide power request to Pn54x nfc-i2c driver, it cheks if
+ * wired access is already granted. It should have access to pn54x drive.
+ * Below are the apis provided by the SPM module.
+ ******************************************************************************/
+/******************************************************************************
+ * Function phNxpEse_SPM_Init
+ *
+ * Description This function opens the nfc i2c driver to manage power
+ * and synchronization for ese secure element.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_Init(void* pDevHandle) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ pEseDeviceHandle = pDevHandle;
+ if (NULL == pEseDeviceHandle) {
+ ALOGE("%s : failed, device handle is null", __FUNCTION__);
+ status = ESESTATUS_FAILED;
+ }
+ ALOGD_IF(ese_debug_enabled, "%s : exit status = %d", __FUNCTION__, status);
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_DeInit
+ *
+ * Description This function closes the nfc i2c driver node.
+ *
+ * Returns Always returns ESESTATUS_SUCCESS
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_DeInit(void) {
+ pEseDeviceHandle = NULL;
+ return ESESTATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_ConfigPwr
+ *
+ * Description This function request to the nfc i2c driver
+ * to enable/disable power to ese. This api should be called
+ *before
+ * sending any apdu to ese/once apdu exchange is done.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_ConfigPwr(spm_power_t arg) {
+ int32_t ret = -1;
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+ if (GET_CHIP_OS_VERSION() > OS_VERSION_4_0) {
+ /*None of the IOCTLs valid except SPM_RECOVERY_RESET*/
+ if (arg != SPM_RECOVERY_RESET) {
+ return ESESTATUS_SUCCESS;
+ }
+ }
+ ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, arg);
+ switch (arg) {
+ case SPM_POWER_DISABLE: {
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ wSpmStatus = ESESTATUS_FAILED;
+ } else {
+ if (phNxpEse_SPM_RelAccess() != ESESTATUS_SUCCESS) {
+ ALOGE(" %s phNxpEse_SPM_RelAccess : failed \n", __FUNCTION__);
+ }
+ }
+ } break;
+ case SPM_POWER_ENABLE: {
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ if (errno == -EBUSY) {
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ if (phNxpEse_SPM_RelAccess() != ESESTATUS_SUCCESS) {
+ ALOGE(" %s phNxpEse_SPM_RelAccess : failed \n", __FUNCTION__);
+ }
+ return wSpmStatus;
+ } else {
+ if (current_spm_state & SPM_STATE_DWNLD) {
+ wSpmStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wSpmStatus = ESESTATUS_BUSY;
+ }
+ }
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ }
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ if (phNxpEse_SPM_RelAccess() != ESESTATUS_SUCCESS) {
+ ALOGE(" %s phNxpEse_SPM_RelAccess : failed \n", __FUNCTION__);
+ }
+ }
+ }
+ } break;
+ case SPM_POWER_RESET: {
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ if (errno == -EBUSY) {
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ return wSpmStatus;
+ } else {
+ if (current_spm_state & SPM_STATE_DWNLD) {
+ wSpmStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wSpmStatus = ESESTATUS_BUSY;
+ }
+ }
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ }
+ }
+ } break;
+ case SPM_POWER_PRIO_ENABLE: {
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ if (errno == -EBUSY) {
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ return wSpmStatus;
+ } else {
+ if (current_spm_state & SPM_STATE_DWNLD) {
+ wSpmStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wSpmStatus = ESESTATUS_BUSY;
+ }
+ }
+
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ }
+ }
+ } break;
+ case SPM_POWER_PRIO_DISABLE: {
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ wSpmStatus = ESESTATUS_FAILED;
+ }
+ } break;
+ case SPM_RECOVERY_RESET: {
+ } break;
+ }
+ return wSpmStatus;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_EnablePwr
+ *
+ * Description This function request to the nfc i2c driver
+ * to enable power to ese. This api should be called before
+ * sending any apdu to ese.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_EnablePwr(void) {
+ int32_t ret = -1;
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+ ALOGD_IF(ese_debug_enabled, "%s : phNxpEse_SPM_EnablePwr is set to = 0x%d",
+ __FUNCTION__, 0);
+ ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 0);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ if (errno == -EBUSY) {
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ return wSpmStatus;
+ } else {
+ if (current_spm_state == SPM_STATE_DWNLD) {
+ wSpmStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wSpmStatus = ESESTATUS_BUSY;
+ }
+ }
+
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ }
+ }
+
+ return wSpmStatus;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_DisablePwr
+ *
+ * Description This function request to the nfc i2c driver
+ * to disable power to ese. This api should be called
+ * once apdu exchange is done.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_DisablePwr(void) {
+ int32_t ret = -1;
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ALOGD_IF(ese_debug_enabled, "%s : phNxpEse_SPM_DisablePwr is set to = 0x%d",
+ __FUNCTION__, 1);
+ ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 1);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ status = ESESTATUS_FAILED;
+ }
+
+ return status;
+}
+/******************************************************************************
+ * Function phNxpEse_SPM_SetPwrScheme
+ *
+ * Description This function request to the nfc i2c driver
+ * to set the chip type and power scheme.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_SetPwrScheme(long arg) {
+ int32_t ret = -1;
+ ESESTATUS status = ESESTATUS_SUCCESS;
+
+ ALOGD_IF(ese_debug_enabled, "%s : Power scheme is set to = 0x%ld",
+ __FUNCTION__, arg);
+ ret = phPalEse_ioctl(phPalEse_e_SetPowerScheme, pEseDeviceHandle, arg);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ status = ESESTATUS_FAILED;
+ }
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEseP61_SPM_EnableDisablePwrCntrl
+ *
+ * Description This function request to the nfc i2c driver
+ * to set the chip type and power scheme.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_DisablePwrControl(unsigned long arg) {
+ int32_t ret = -1;
+ ESESTATUS status = ESESTATUS_SUCCESS;
+
+ ALOGD_IF(ese_debug_enabled, "%s : Inhibit power control is set to = 0x%ld",
+ __FUNCTION__, arg);
+ ret = phPalEse_ioctl(phPalEse_e_DisablePwrCntrl, pEseDeviceHandle, arg);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ status = ESESTATUS_FAILED;
+ }
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_GetState
+ *
+ * Description This function gets the current power state of ESE
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_GetState(spm_state_t* current_state) {
+ int32_t ret = -1;
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ spm_state_t ese_current_state = SPM_STATE_INVALID;
+
+ if (current_state == NULL) {
+ ALOGE("%s : failed Invalid argument", __FUNCTION__);
+ return ESESTATUS_FAILED;
+ }
+ ret = phPalEse_ioctl(phPalEse_e_GetSPMStatus, pEseDeviceHandle,
+ (unsigned long)&ese_current_state);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ status = ESESTATUS_FAILED;
+ } else {
+ *current_state = ese_current_state; /* Current ESE state */
+ }
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_SetJcopDwnldState
+ *
+ * Description This function is used to set the JCOP OS download state
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_SetJcopDwnldState(long arg) {
+ int ret = -1;
+ ESESTATUS status = ESESTATUS_SUCCESS;
+
+ ALOGD_IF(ese_debug_enabled, "%s :phNxpEse_SPM_SetJcopDwnldState = 0x%ld",
+ __FUNCTION__, arg);
+ ret = phPalEse_ioctl(phPalEse_e_SetJcopDwnldState, pEseDeviceHandle, arg);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ status = ESESTATUS_FAILED;
+ }
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_SetEseClientUpdateState
+ *
+ * Description This function is used to set the ese Update state
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_SetEseClientUpdateState(long arg) {
+ int ret = -1;
+ ESESTATUS status = ESESTATUS_SUCCESS;
+
+ ALOGD_IF(ese_debug_enabled,
+ "%s :phNxpEse_SPM_SetEseClientUpdateState = 0x%ld", __FUNCTION__,
+ arg);
+ ret = phPalEse_ioctl(phPalEse_e_SetClientUpdateState, pEseDeviceHandle, arg);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ status = ESESTATUS_FAILED;
+ }
+
+ return status;
+}
+
+/******************************************************************************
+ * Function phNxpEse_SPM_ResetPwr
+ *
+ * Description This function request to the nfc i2c driver
+ * to reset ese.
+ *
+ * Returns On Success ESESTATUS_SUCCESS else proper error code
+ *
+ ******************************************************************************/
+ESESTATUS phNxpEse_SPM_ResetPwr(void) {
+ int32_t ret = -1;
+ ESESTATUS wSpmStatus = ESESTATUS_SUCCESS;
+ spm_state_t current_spm_state = SPM_STATE_INVALID;
+
+ /* reset the ese */
+ ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 2);
+ if (ret < 0) {
+ ALOGE("%s : failed errno = 0x%x", __FUNCTION__, errno);
+ if (errno == -EBUSY || errno == EBUSY) {
+ wSpmStatus = phNxpEse_SPM_GetState(&current_spm_state);
+ if (wSpmStatus != ESESTATUS_SUCCESS) {
+ ALOGE(" %s : phNxpEse_SPM_GetPwrState Failed", __FUNCTION__);
+ return wSpmStatus;
+ } else {
+ if (current_spm_state == SPM_STATE_DWNLD) {
+ wSpmStatus = ESESTATUS_DWNLD_BUSY;
+ } else {
+ wSpmStatus = ESESTATUS_BUSY;
+ }
+ }
+
+ } else {
+ wSpmStatus = ESESTATUS_FAILED;
+ }
+ }
+
+ return wSpmStatus;
+}
+
+/*******************************************************************************
+**
+** Function phTmlEse_get_ese_access
+**
+** Description
+**
+** Parameters timeout - timeout to wait for ese access
+**
+** Returns success or failure
+**
+*******************************************************************************/
+ESESTATUS phNxpEse_SPM_GetAccess(long timeout) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+ ALOGD_IF(ese_debug_enabled, "phTmlEse_get_ese_access(), timeout %ld",
+ timeout);
+#if ((NFC_NXP_ESE_VER == JCOP_VER_3_1) || (NFC_NXP_ESE_VER == JCOP_VER_3_2))
+ int ret = -1;
+
+ ret = phPalEse_ioctl(phPalEse_e_GetEseAccess, pEseDeviceHandle, timeout);
+ if (ret < 0) {
+ if (ret == -EBUSY)
+ status = ESESTATUS_BUSY;
+ else
+ status = ESESTATUS_FAILED;
+ }
+ ALOGD_IF(ese_debug_enabled, "phTmlEse_get_ese_access(), exit %d", status);
+#endif
+ return status;
+}
+/*******************************************************************************
+**
+** Function phNxpEse_SPM_RelAccess
+**
+** Description
+**
+** Parameters timeout - Releases the ese access
+**
+** Returns success or failure
+**
+*******************************************************************************/
+ESESTATUS phNxpEse_SPM_RelAccess(void) {
+ ESESTATUS status = ESESTATUS_SUCCESS;
+#if ((NFC_NXP_ESE_VER == JCOP_VER_3_1) || (NFC_NXP_ESE_VER == JCOP_VER_3_2))
+ int ret = -1;
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_SPM_RelAccess(): enter");
+
+ ret = phPalEse_ioctl(phPalEse_e_ChipRst, pEseDeviceHandle, 5);
+ if (ret < 0) {
+ status = ESESTATUS_FAILED;
+ }
+ ALOGD_IF(ese_debug_enabled, "phNxpEse_SPM_RelAccess(): exit %d", status);
+#endif
+ return status;
+}
+/** @} */
diff --git a/snxxx/libese-spi/p73/spm/phNxpEse_Spm.h b/snxxx/libese-spi/p73/spm/phNxpEse_Spm.h
new file mode 100644
index 0000000..a65d991
--- /dev/null
+++ b/snxxx/libese-spi/p73/spm/phNxpEse_Spm.h
@@ -0,0 +1,195 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2019 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/**
+ * \addtogroup SPI_Power_Management
+ *
+ * @{ */
+
+#ifndef _PHNXPESE_SPM_H
+#define _PHNXPESE_SPM_H
+
+#include <phEseStatus.h>
+#include <phNxpEseFeatures.h>
+/*! SPI Power Manager (SPM) possible error codes */
+typedef enum spm_power {
+ SPM_POWER_DISABLE = 0,
+ SPM_POWER_ENABLE, /*!< SPM power disable */
+ SPM_POWER_RESET, /*!< SPM Reset pwer */
+ SPM_POWER_PRIO_ENABLE, /*!< SPM prio mode enable */
+ SPM_POWER_PRIO_DISABLE, /*!< SPM prio mode disable */
+ SPM_RECOVERY_RESET
+} spm_power_t;
+
+/*! SPI Power Manager (SPM) possible states */
+typedef enum spm_state {
+ SPM_STATE_INVALID = 0x0000, /*!< Nfc i2c driver misbehaving */
+ SPM_STATE_IDLE = 0x0100, /*!< ESE is free to use */
+ SPM_STATE_WIRED = 0x0200, /*!< p61 is being accessed by DWP (NFCC)*/
+ SPM_STATE_SPI = 0x0400, /*!< ESE is being accessed by SPI */
+ SPM_STATE_DWNLD = 0x0800, /*!< NFCC fw download is in progress */
+ SPM_STATE_SPI_PRIO = 0x1000, /*!< Start of p61 access by SPI on priority*/
+ SPM_STATE_SPI_PRIO_END = 0x2000, /*!< End of p61 access by SPI on priority*/
+ SPM_STATE_SPI_FAILED = 0x0010, /*SPI open/close failed*/
+ SPM_STATE_JCOP_DWNLD = 0x8000 /*!< P73 state JCOP Download*/
+} spm_state_t;
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function opens the nfc i2c driver to manage power
+ * and synchronization for ese secure element.
+ *
+ * \param[in] pDevHandle - Device handle to open.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_Init(void* pDevHandle);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief TThis function closes the nfc i2c driver node.
+ *
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_DeInit(void);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to the nfc i2c driver
+ * to enable/disable power to ese. This api should be called
+ *before sending any apdu to ese/once apdu exchange is done.
+ *
+ * \param[in] arg -input can be of type spm_power_t.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_ConfigPwr(spm_power_t arg);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to the nfc i2c driver
+ * to enable power to ese. This api should be called before
+ * sending any apdu to ese.
+ *
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_EnablePwr(void);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to the nfc i2c driver
+ * to disable power to ese. This api should be called
+ * once apdu exchange is done.
+ *
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_DisablePwr(void);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function gets the current power state of ESE
+ * \param[in] current_state -input is of type spm_state_t.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_GetState(spm_state_t* current_state);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to the nfc i2c driver
+ * to reset ese.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_ResetPwr(void);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to get access to eSE
+ *
+ * \param[in] timeout - timeout to wait for ese access.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_GetAccess(long timeout);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function set the SPM power state
+ *
+ * \param[in] arg - state value.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_SetState(long arg);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief phNxpEse_SPM_RelAccess
+ *
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_RelAccess(void);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to the nfc i2c driver
+ * to set the chip type and power scheme.
+ *
+ * \param[in] arg - set power scheme from config.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_SetPwrScheme(long arg);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function request to the nfc i2c driver
+ * to set the chip type and power scheme.
+ *
+ * \param[in] arg - arg.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_DisablePwrControl(unsigned long arg);
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function is used to set the ese Update state.
+ *
+ * \param[in] arg - eSE update status started/completed.
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_SetEseClientUpdateState(long arg);
+
+/**
+ * \ingroup SPI_Power_Management
+ * \brief This function is used to set the ese Update state.
+ *
+ * \param[in] arg - JCOP update status started/completed..
+ *
+ * \retval -On Success ESESTATUS_SUCCESS else proper error code
+ */
+ESESTATUS phNxpEse_SPM_SetJcopDwnldState(long arg);
+
+#endif /* _PHNXPESE_SPM_H */
+/** @} */
diff --git a/snxxx/libese-spi/p73/utils/config.cpp b/snxxx/libese-spi/p73/utils/config.cpp
new file mode 100644
index 0000000..a470af8
--- /dev/null
+++ b/snxxx/libese-spi/p73/utils/config.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2017 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.
+ */
+/******************************************************************************
+ *
+ * The original Work has been changed by NXP Semiconductors.
+ *
+ * Copyright (C) 2019 NXP Semiconductors
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#include "config.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+using namespace ::std;
+using namespace ::android::base;
+
+namespace {
+
+bool parseBytesString(std::string in, std::vector<uint8_t>& out) {
+ vector<string> values = Split(in, ":");
+ if (values.size() == 0) return false;
+ for (const string& value : values) {
+ if (value.length() != 2) return false;
+ uint8_t tmp = 0;
+ string hexified = "0x";
+ hexified.append(value);
+ if (!ParseUint(hexified.c_str(), &tmp)) return false;
+ out.push_back(tmp);
+ }
+ return true;
+}
+
+} // namespace
+
+ConfigValue::ConfigValue() {
+ value_unsigned_ = 0;
+ type_ = UNSIGNED;
+}
+
+ConfigValue::Type ConfigValue::getType() const { return type_; }
+
+std::string ConfigValue::getString() const {
+ CHECK(type_ == STRING);
+ return value_string_;
+};
+
+unsigned ConfigValue::getUnsigned() const {
+ CHECK(type_ == UNSIGNED);
+ return value_unsigned_;
+};
+
+std::vector<uint8_t> ConfigValue::getBytes() const {
+ CHECK(type_ == BYTES);
+ return value_bytes_;
+};
+
+bool ConfigValue::parseFromString(std::string in) {
+ if (in.length() > 1 && in[0] == '"' && in[in.length() - 1] == '"') {
+ CHECK(in.length() > 2); // Don't allow empty strings
+ type_ = STRING;
+ value_string_ = in.substr(1, in.length() - 2);
+ return true;
+ }
+
+ if (in.length() > 1 && in[0] == '{' && in[in.length() - 1] == '}') {
+ CHECK(in.length() >= 4); // Needs at least one byte
+ type_ = BYTES;
+ return parseBytesString(in.substr(1, in.length() - 2), value_bytes_);
+ }
+
+ unsigned tmp = 0;
+ if (ParseUint(in.c_str(), &tmp)) {
+ type_ = UNSIGNED;
+ value_unsigned_ = tmp;
+ return true;
+ }
+
+ return false;
+}
+
+void ConfigFile::parseFromFile(const std::string& file_name) {
+ string config;
+ bool config_read = ReadFileToString(file_name, &config);
+ CHECK(config_read);
+ LOG(INFO) << "ConfigFile - Parsing file '" << file_name << "'";
+ parseFromString(config);
+}
+
+void ConfigFile::parseFromString(const std::string& config) {
+ stringstream ss(config);
+ string line;
+ while (getline(ss, line)) {
+ line = Trim(line);
+ if (line.empty()) continue;
+ if (line.at(0) == '#') continue;
+ if (line.at(0) == 0) continue;
+
+ auto search = line.find('=');
+ CHECK(search != string::npos);
+
+ string key(Trim(line.substr(0, search)));
+ string value_string(Trim(line.substr(search + 1, string::npos)));
+
+ ConfigValue value;
+ bool value_parsed = value.parseFromString(value_string);
+ CHECK(value_parsed);
+ CHECK(!hasKey(key));
+ values_.emplace(key, value);
+
+ LOG(INFO) << "ConfigFile - [" << key << "] = " << value_string;
+ }
+}
+
+bool ConfigFile::hasKey(const std::string& key) {
+ return values_.count(key) != 0;
+}
+
+ConfigValue& ConfigFile::getValue(const std::string& key) {
+ CHECK(values_.find(key) != values_.end());
+ auto search = values_.find(key);
+ return search->second;
+}
+
+std::string ConfigFile::getString(const std::string& key) {
+ return getValue(key).getString();
+}
+
+unsigned ConfigFile::getUnsigned(const std::string& key) {
+ return getValue(key).getUnsigned();
+}
+
+std::vector<uint8_t> ConfigFile::getBytes(const std::string& key) {
+ return getValue(key).getBytes();
+}
+
+void ConfigFile::clear() { values_.clear(); }
diff --git a/snxxx/libese-spi/p73/utils/config.h b/snxxx/libese-spi/p73/utils/config.h
new file mode 100644
index 0000000..115c7fa
--- /dev/null
+++ b/snxxx/libese-spi/p73/utils/config.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 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.
+ */
+/******************************************************************************
+ *
+ * The original Work has been changed by NXP Semiconductors.
+ *
+ * Copyright (C) 2019 NXP Semiconductors
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+
+class ConfigValue {
+ public:
+ enum Type { UNSIGNED, STRING, BYTES };
+
+ ConfigValue();
+ Type getType() const;
+ std::string getString() const;
+ unsigned getUnsigned() const;
+ std::vector<uint8_t> getBytes() const;
+
+ bool parseFromString(std::string in);
+
+ private:
+ Type type_;
+ std::string value_string_;
+ unsigned value_unsigned_;
+ std::vector<uint8_t> value_bytes_;
+};
+
+class ConfigFile {
+ public:
+ void parseFromFile(const std::string& file_name);
+ void parseFromString(const std::string& config);
+
+ bool hasKey(const std::string& key);
+ std::string getString(const std::string& key);
+ unsigned getUnsigned(const std::string& key);
+ std::vector<uint8_t> getBytes(const std::string& key);
+
+ void clear();
+
+ private:
+ ConfigValue& getValue(const std::string& key);
+
+ std::map<std::string, ConfigValue> values_;
+};
diff --git a/snxxx/libese-spi/p73/utils/ese_config.cpp b/snxxx/libese-spi/p73/utils/ese_config.cpp
new file mode 100644
index 0000000..4a6b2cc
--- /dev/null
+++ b/snxxx/libese-spi/p73/utils/ese_config.cpp
@@ -0,0 +1,87 @@
+/******************************************************************************
+ *
+ * Copyright 2018 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include "ese_config.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+#include <config.h>
+
+using namespace ::std;
+using namespace ::android::base;
+
+namespace {
+
+std::string findConfigPath() {
+ const vector<string> search_path = {"/odm/etc/", "/vendor/etc/", "/etc/"};
+ const string file_name = "libese-nxp.conf";
+
+ for (string path : search_path) {
+ path.append(file_name);
+ struct stat file_stat;
+ if (stat(path.c_str(), &file_stat) != 0) continue;
+ if (S_ISREG(file_stat.st_mode)) return path;
+ }
+ return "";
+}
+
+} // namespace
+
+EseConfig::EseConfig() {
+ string config_path = findConfigPath();
+ CHECK(config_path != "");
+ config_.parseFromFile(config_path);
+}
+
+EseConfig& EseConfig::getInstance() {
+ static EseConfig theInstance;
+ return theInstance;
+}
+
+bool EseConfig::hasKey(const std::string& key) {
+ return getInstance().config_.hasKey(key);
+}
+
+std::string EseConfig::getString(const std::string& key) {
+ return getInstance().config_.getString(key);
+}
+
+std::string EseConfig::getString(const std::string& key,
+ std::string default_value) {
+ if (hasKey(key)) return getString(key);
+ return default_value;
+}
+
+unsigned EseConfig::getUnsigned(const std::string& key) {
+ return getInstance().config_.getUnsigned(key);
+}
+
+unsigned EseConfig::getUnsigned(const std::string& key,
+ unsigned default_value) {
+ if (hasKey(key)) return getUnsigned(key);
+ return default_value;
+}
+
+std::vector<uint8_t> EseConfig::getBytes(const std::string& key) {
+ return getInstance().config_.getBytes(key);
+}
+
+void EseConfig::clear() { getInstance().config_.clear(); }
diff --git a/snxxx/libese-spi/p73/utils/ese_config.h b/snxxx/libese-spi/p73/utils/ese_config.h
new file mode 100755
index 0000000..bba26c8
--- /dev/null
+++ b/snxxx/libese-spi/p73/utils/ese_config.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <config.h>
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define NAME_SE_DEBUG_ENABLED "SE_DEBUG_ENABLED"
+#define NAME_NXP_JCOPDL_AT_BOOT_ENABLE "NXP_JCOPDL_AT_BOOT_ENABLE"
+#define NAME_NXP_WTX_COUNT_VALUE "NXP_WTX_COUNT_VALUE"
+#define NAME_NXP_MAX_RSP_TIMEOUT "NXP_MAX_RSP_TIMEOUT"
+#define NAME_NXP_POWER_SCHEME "NXP_POWER_SCHEME"
+#define NAME_NXP_SOF_WRITE "NXP_SOF_WRITE"
+#define NAME_NXP_TP_MEASUREMENT "NXP_TP_MEASUREMENT"
+#define NAME_NXP_SPI_INTF_RST_ENABLE "NXP_SPI_INTF_RST_ENABLE"
+#define NAME_NXP_MAX_RNACK_RETRY "NXP_MAX_RNACK_RETRY"
+#define NAME_NXP_SPI_WRITE_TIMEOUT "NXP_SPI_WRITE_TIMEOUT"
+#define NAME_NXP_ESE_DEV_NODE "NXP_ESE_DEV_NODE"
+#define NAME_NXP_VISO_DPD_ENABLED "NXP_VISO_DPD_ENABLED"
+#define NAME_NXP_NAD_POLL_RETRY_TIME "NXP_NAD_POLL_RETRY_TIME"
+#define NAME_RNACK_RETRY_DELAY "RNACK_RETRY_DELAY"
+#define NAME_NXP_P61_JCOP_DEFAULT_INTERFACE "NXP_P61_JCOP_DEFAULT_INTERFACE"
+#define NAME_NXP_ESE_IFSD_VALUE "NXP_ESE_IFSD_VALUE"
+#define NAME_NXP_EUICC_IFSD_VALUE "NXP_EUICC_IFSD_VALUE"
+#define NAME_NXP_P61_COLD_RESET_INTERFACE "NXP_P61_COLD_RESET_INTERFACE"
+#define NAME_NXP_OS_VERSION "NXP_OS_VERSION"
+#define NAME_NXP_WTX_NTF_COUNT "NXP_WTX_NTF_COUNT"
+#define NAME_NXP_OSU_MAX_WTX_COUNT "NXP_OSU_MAX_WTX_COUNT"
+#define NAME_NXP_TRANSPORT "NXP_TRANSPORT"
+#endif
+
+class EseConfig {
+ public:
+ static bool hasKey(const std::string& key);
+ static std::string getString(const std::string& key);
+ static std::string getString(const std::string& key,
+ std::string default_value);
+ static unsigned getUnsigned(const std::string& key);
+ static unsigned getUnsigned(const std::string& key, unsigned default_value);
+ static std::vector<uint8_t> getBytes(const std::string& key);
+ static void clear();
+
+ private:
+ static EseConfig& getInstance();
+ EseConfig();
+
+ ConfigFile config_;
+};
diff --git a/snxxx/libese-spi/p73/utils/ringbuffer.cpp b/snxxx/libese-spi/p73/utils/ringbuffer.cpp
new file mode 100644
index 0000000..d7798fd
--- /dev/null
+++ b/snxxx/libese-spi/p73/utils/ringbuffer.cpp
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2017 Google Inc.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "ringbuffer.h"
+
+struct ringbuffer_t {
+ size_t total;
+ size_t available;
+ uint8_t* base;
+ uint8_t* head;
+ uint8_t* tail;
+};
+
+ringbuffer_t* ringbuffer_init(const size_t size) {
+ ringbuffer_t* p = static_cast<ringbuffer_t*>(calloc(1, sizeof(ringbuffer_t)));
+
+ if (p == NULL) return p;
+
+ p->base = static_cast<uint8_t*>(calloc(size, sizeof(uint8_t)));
+ p->head = p->tail = p->base;
+ p->total = p->available = size;
+
+ return p;
+}
+
+void ringbuffer_free(ringbuffer_t* rb) {
+ if (rb != NULL) free(rb->base);
+ free(rb);
+}
+
+size_t ringbuffer_available(const ringbuffer_t* rb) {
+ assert(rb);
+ return rb->available;
+}
+
+size_t ringbuffer_size(const ringbuffer_t* rb) {
+ assert(rb);
+ return rb->total - rb->available;
+}
+
+size_t ringbuffer_insert(ringbuffer_t* rb, const uint8_t* p, size_t length) {
+ assert(rb);
+ assert(p);
+
+ if (length > ringbuffer_available(rb)) length = ringbuffer_available(rb);
+
+ for (size_t i = 0; i != length; ++i) {
+ *rb->tail++ = *p++;
+ if (rb->tail >= (rb->base + rb->total)) rb->tail = rb->base;
+ }
+
+ rb->available -= length;
+ return length;
+}
+
+size_t ringbuffer_delete(ringbuffer_t* rb, size_t length) {
+ assert(rb);
+
+ if (length > ringbuffer_size(rb)) length = ringbuffer_size(rb);
+
+ rb->head += length;
+ if (rb->head >= (rb->base + rb->total)) rb->head -= rb->total;
+
+ rb->available += length;
+ return length;
+}
+
+size_t ringbuffer_peek(const ringbuffer_t* rb, off_t offset, uint8_t* p,
+ size_t length) {
+ assert(rb);
+ assert(p);
+ assert(offset >= 0);
+ assert((size_t)offset <= ringbuffer_size(rb));
+
+ uint8_t* b = ((rb->head - rb->base + offset) % rb->total) + rb->base;
+ const size_t bytes_to_copy = (offset + length > ringbuffer_size(rb))
+ ? ringbuffer_size(rb) - offset
+ : length;
+
+ for (size_t copied = 0; copied < bytes_to_copy; ++copied) {
+ *p++ = *b++;
+ if (b >= (rb->base + rb->total)) b = rb->base;
+ }
+
+ return bytes_to_copy;
+}
+
+size_t ringbuffer_pop(ringbuffer_t* rb, uint8_t* p, size_t length) {
+ assert(rb);
+ assert(p);
+
+ const size_t copied = ringbuffer_peek(rb, 0, p, length);
+ rb->head += copied;
+ if (rb->head >= (rb->base + rb->total)) rb->head -= rb->total;
+
+ rb->available += copied;
+ return copied;
+}
diff --git a/snxxx/libese-spi/p73/utils/ringbuffer.h b/snxxx/libese-spi/p73/utils/ringbuffer.h
new file mode 100644
index 0000000..d2c310a
--- /dev/null
+++ b/snxxx/libese-spi/p73/utils/ringbuffer.h
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2017 Google Inc.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#pragma once
+
+#include <stdint.h>
+
+typedef struct ringbuffer_t ringbuffer_t;
+
+// NOTE:
+// None of the functions below are thread safe when it comes to accessing the
+// *rb pointer. It is *NOT* possible to insert and pop/delete at the same time.
+// Callers must protect the *rb pointer separately.
+
+// Create a ringbuffer with the specified size
+// Returns NULL if memory allocation failed. Resulting pointer must be freed
+// using |ringbuffer_free|.
+ringbuffer_t* ringbuffer_init(const size_t size);
+
+// Frees the ringbuffer structure and buffer
+// Save to call with NULL.
+void ringbuffer_free(ringbuffer_t* rb);
+
+// Returns remaining buffer size
+size_t ringbuffer_available(const ringbuffer_t* rb);
+
+// Returns size of data in buffer
+size_t ringbuffer_size(const ringbuffer_t* rb);
+
+// Attempts to insert up to |length| bytes of data at |p| into the buffer
+// Return actual number of bytes added. Can be less than |length| if buffer
+// is full.
+size_t ringbuffer_insert(ringbuffer_t* rb, const uint8_t* p, size_t length);
+
+// Peek |length| number of bytes from the ringbuffer, starting at |offset|,
+// into the buffer |p|. Return the actual number of bytes peeked. Can be less
+// than |length| if there is less than |length| data available. |offset| must
+// be non-negative.
+size_t ringbuffer_peek(const ringbuffer_t* rb, off_t offset, uint8_t* p,
+ size_t length);
+
+// Does the same as |ringbuffer_peek|, but also advances the ring buffer head
+size_t ringbuffer_pop(ringbuffer_t* rb, uint8_t* p, size_t length);
+
+// Deletes |length| bytes from the ringbuffer starting from the head
+// Return actual number of bytes deleted.
+size_t ringbuffer_delete(ringbuffer_t* rb, size_t length);
diff --git a/snxxx/libese-spi/src/adaptation/CondVar.cpp b/snxxx/libese-spi/src/adaptation/CondVar.cpp
new file mode 100755
index 0000000..ad69973
--- /dev/null
+++ b/snxxx/libese-spi/src/adaptation/CondVar.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Encapsulate a condition variable for thread synchronization.
+ */
+
+#include "CondVar.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <android-base/stringprintf.h>
+#include <base/logging.h>
+
+using android::base::StringPrintf;
+
+/*******************************************************************************
+**
+** Function: CondVar
+**
+** Description: Initialize member variables.
+**
+** Returns: None.
+**
+*******************************************************************************/
+CondVar::CondVar() {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ memset(&mCondition, 0, sizeof(mCondition));
+ int const res = pthread_cond_init(&mCondition, &attr);
+ if (res) {
+ LOG(ERROR) << StringPrintf("CondVar::CondVar: fail init; error=0x%X", res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: ~CondVar
+**
+** Description: Cleanup all resources.
+**
+** Returns: None.
+**
+*******************************************************************************/
+CondVar::~CondVar() {
+ int const res = pthread_cond_destroy(&mCondition);
+ if (res) {
+ LOG(ERROR) << StringPrintf("CondVar::~CondVar: fail destroy; error=0x%X",
+ res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: wait
+**
+** Description: Block the caller and wait for a condition.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void CondVar::wait(Mutex& mutex) {
+ int const res = pthread_cond_wait(&mCondition, mutex.nativeHandle());
+ if (res) {
+ LOG(ERROR) << StringPrintf("CondVar::wait: fail wait; error=0x%X", res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: wait
+**
+** Description: Block the caller and wait for a condition.
+** millisec: Timeout in milliseconds.
+**
+** Returns: True if wait is successful; false if timeout occurs.
+**
+*******************************************************************************/
+bool CondVar::wait(Mutex& mutex, long millisec) {
+ bool retVal = false;
+ struct timespec absoluteTime;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &absoluteTime) == -1) {
+ LOG(ERROR) << StringPrintf("CondVar::wait: fail get time; errno=0x%X",
+ errno);
+ } else {
+ absoluteTime.tv_sec += millisec / 1000;
+ long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
+ if (ns > 1000000000) {
+ absoluteTime.tv_sec++;
+ absoluteTime.tv_nsec = ns - 1000000000;
+ } else
+ absoluteTime.tv_nsec = ns;
+ }
+
+ int waitResult =
+ pthread_cond_timedwait(&mCondition, mutex.nativeHandle(), &absoluteTime);
+ if ((waitResult != 0) && (waitResult != ETIMEDOUT))
+ LOG(ERROR) << StringPrintf("CondVar::wait: fail timed wait; error=0x%X",
+ waitResult);
+ retVal = (waitResult == 0); // waited successfully
+ return retVal;
+}
+
+/*******************************************************************************
+**
+** Function: notifyOne
+**
+** Description: Unblock the waiting thread.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void CondVar::notifyOne() {
+ int const res = pthread_cond_signal(&mCondition);
+ if (res) {
+ LOG(ERROR) << StringPrintf("CondVar::notifyOne: fail signal; error=0x%X",
+ res);
+ }
+}
diff --git a/snxxx/libese-spi/src/adaptation/Mutex.cpp b/snxxx/libese-spi/src/adaptation/Mutex.cpp
new file mode 100755
index 0000000..ef4d5e5
--- /dev/null
+++ b/snxxx/libese-spi/src/adaptation/Mutex.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Encapsulate a mutex for thread synchronization.
+ */
+
+#include "Mutex.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <android-base/stringprintf.h>
+#include <base/logging.h>
+
+using android::base::StringPrintf;
+
+/*******************************************************************************
+**
+** Function: Mutex
+**
+** Description: Initialize member variables.
+**
+** Returns: None.
+**
+*******************************************************************************/
+Mutex::Mutex() {
+ memset(&mMutex, 0, sizeof(mMutex));
+ int res = pthread_mutex_init(&mMutex, NULL);
+ if (res != 0) {
+ LOG(ERROR) << StringPrintf("Mutex::Mutex: fail init; error=0x%X", res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: ~Mutex
+**
+** Description: Cleanup all resources.
+**
+** Returns: None.
+**
+*******************************************************************************/
+Mutex::~Mutex() {
+ int res = pthread_mutex_destroy(&mMutex);
+ if (res != 0) {
+ LOG(ERROR) << StringPrintf("Mutex::~Mutex: fail destroy; error=0x%X", res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: lock
+**
+** Description: Block the thread and try lock the mutex.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void Mutex::lock() {
+ int res = pthread_mutex_lock(&mMutex);
+ if (res != 0) {
+ LOG(ERROR) << StringPrintf("Mutex::lock: fail lock; error=0x%X", res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: unlock
+**
+** Description: Unlock a mutex to unblock a thread.
+**
+** Returns: None.
+**
+*******************************************************************************/
+void Mutex::unlock() {
+ int res = pthread_mutex_unlock(&mMutex);
+ if (res != 0) {
+ LOG(ERROR) << StringPrintf("Mutex::unlock: fail unlock; error=0x%X", res);
+ }
+}
+
+/*******************************************************************************
+**
+** Function: tryLock
+**
+** Description: Try to lock the mutex.
+**
+** Returns: True if the mutex is locked.
+**
+*******************************************************************************/
+bool Mutex::tryLock() {
+ int res = pthread_mutex_trylock(&mMutex);
+ if ((res != 0) && (res != EBUSY)) {
+ LOG(ERROR) << StringPrintf("Mutex::tryLock: error=0x%X", res);
+ }
+ return res == 0;
+}
+
+/*******************************************************************************
+**
+** Function: nativeHandle
+**
+** Description: Get the handle of the mutex.
+**
+** Returns: Handle of the mutex.
+**
+*******************************************************************************/
+pthread_mutex_t* Mutex::nativeHandle() { return &mMutex; }
diff --git a/snxxx/libese-spi/src/adaptation/NfcAdaptation.cpp b/snxxx/libese-spi/src/adaptation/NfcAdaptation.cpp
new file mode 100644
index 0000000..d746a0c
--- /dev/null
+++ b/snxxx/libese-spi/src/adaptation/NfcAdaptation.cpp
@@ -0,0 +1,258 @@
+/******************************************************************************
+ *
+ * Copyright 2018-2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#define LOG_TAG "NxpEseHal-NfcAdaptation"
+#include "NfcAdaptation.h"
+#include <android/hardware/nfc/1.0/types.h>
+#include <hwbinder/ProcessState.h>
+#include <log/log.h>
+#include <pthread.h>
+
+#undef LOG_TAG
+#define LOG_TAG "SpiAdaptation"
+
+using android::OK;
+using android::sp;
+using android::status_t;
+
+using android::hardware::hidl_vec;
+using android::hardware::ProcessState;
+using android::hardware::Return;
+using android::hardware::Void;
+using vendor::nxp::nxpnfc::V2_0::INxpNfc;
+
+sp<INxpNfc> NfcAdaptation::mHalNxpNfc = nullptr;
+ThreadMutex NfcAdaptation::sIoctlLock;
+NfcAdaptation* NfcAdaptation::mpInstance = NULL;
+ThreadMutex NfcAdaptation::sLock;
+
+int omapi_status;
+
+void NfcAdaptation::Initialize() {
+ const char* func = "NfcAdaptation::Initialize";
+ ALOGD_IF(ese_debug_enabled, "%s", func);
+ if (mHalNxpNfc != nullptr) return;
+ mHalNxpNfc = INxpNfc::tryGetService();
+ if (mHalNxpNfc != nullptr) {
+ ALOGE("%s: INxpNfc::getService() returned %p (%s)", func, mHalNxpNfc.get(),
+ (mHalNxpNfc->isRemote() ? "remote" : "local"));
+ }
+ ALOGD_IF(ese_debug_enabled, "%s: exit", func);
+}
+/*******************************************************************************
+**
+** Function: NfcAdaptation::GetInstance()
+**
+** Description: access class singleton
+**
+** Returns: pointer to the singleton object
+**
+*******************************************************************************/
+NfcAdaptation& NfcAdaptation::GetInstance() {
+ AutoThreadMutex a(sLock);
+
+ if (!mpInstance) mpInstance = new NfcAdaptation;
+ return *mpInstance;
+}
+/*******************************************************************************
+**
+** Function: ThreadMutex::ThreadMutex()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+ThreadMutex::ThreadMutex() {
+ pthread_mutexattr_t mutexAttr;
+
+ pthread_mutexattr_init(&mutexAttr);
+ pthread_mutex_init(&mMutex, &mutexAttr);
+ pthread_mutexattr_destroy(&mutexAttr);
+}
+/*******************************************************************************
+**
+** Function: ThreadMutex::~ThreadMutex()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
+
+/*******************************************************************************
+**
+** Function: AutoThreadMutex::AutoThreadMutex()
+**
+** Description: class constructor, automatically lock the mutex
+**
+** Returns: none
+**
+*******************************************************************************/
+AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
+
+/*******************************************************************************
+**
+** Function: AutoThreadMutex::~AutoThreadMutex()
+**
+** Description: class destructor, automatically unlock the mutex
+**
+** Returns: none
+**
+*******************************************************************************/
+AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
+
+/*******************************************************************************
+**
+** Function: ThreadMutex::lock()
+**
+** Description: lock kthe mutex
+**
+** Returns: none
+**
+*******************************************************************************/
+void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
+
+/*******************************************************************************
+**
+** Function: ThreadMutex::unblock()
+**
+** Description: unlock the mutex
+**
+** Returns: none
+**
+*******************************************************************************/
+void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::NfcAdaptation()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+NfcAdaptation::NfcAdaptation() { mCurrentIoctlData = NULL; }
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::~NfcAdaptation()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+NfcAdaptation::~NfcAdaptation() { mpInstance = NULL; }
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::resetEse
+**
+** Description: This function a wrapper function which triggers Ese reset
+**
+**
+**
+** Returns: -1 or 0.
+**
+*******************************************************************************/
+ESESTATUS NfcAdaptation::resetEse(uint64_t level) {
+ const char* func = "NfcAdaptation::resetEse";
+ ESESTATUS result = ESESTATUS_FAILED;
+ bool ret = 0;
+
+ ALOGD_IF(ese_debug_enabled, "%s : Enter", func);
+
+ if (mHalNxpNfc != nullptr) {
+ ret = mHalNxpNfc->resetEse(level);
+ if (ret) {
+ ALOGE("NfcAdaptation::resetEse mHalNxpNfc completed");
+ result = ESESTATUS_SUCCESS;
+ } else {
+ ALOGE("NfcAdaptation::resetEse mHalNxpNfc failed");
+ }
+ }
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function: NfcAdaptation::setEseUpdateState
+**
+** Description: This is a wrapper functions notifies upper layer about
+** the jcob download comple
+** tion.
+** Returns: -1 or 0.
+**
+*******************************************************************************/
+ESESTATUS NfcAdaptation::setEseUpdateState(void* p_data) {
+ const char* func = "NfcAdaptation::setEseUpdateState";
+ ::android::hardware::nfc::V1_0::NfcData data;
+ ESESTATUS result = ESESTATUS_FAILED;
+ bool ret = 0;
+
+ ALOGD_IF(ese_debug_enabled, "%s : Enter", func);
+
+ ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
+ data.setToExternal((uint8_t*)pInpOutData, sizeof(ese_nxp_IoctlInOutData_t));
+
+ if (mHalNxpNfc != nullptr) {
+ ret = mHalNxpNfc->setEseUpdateState(
+ (::vendor::nxp::nxpnfc::V2_0::NxpNfcHalEseState)
+ pInpOutData->inp.data.nxpCmd.p_cmd[0]);
+ if (ret) {
+ ALOGE("NfcAdaptation::setEseUpdateState completed");
+ result = ESESTATUS_SUCCESS;
+ } else {
+ ALOGE("NfcAdaptation::setEseUpdateState failed");
+ }
+ }
+
+ return result;
+}
+
+/*******************************************************************************
+**
+** Function: ThreadCondVar::ThreadCondVar()
+**
+** Description: class constructor
+**
+** Returns: none
+**
+*******************************************************************************/
+ThreadCondVar::ThreadCondVar() {
+ pthread_condattr_t CondAttr;
+
+ pthread_condattr_init(&CondAttr);
+ pthread_cond_init(&mCondVar, &CondAttr);
+
+ pthread_condattr_destroy(&CondAttr);
+}
+
+/*******************************************************************************
+**
+** Function: ThreadCondVar::~ThreadCondVar()
+**
+** Description: class destructor
+**
+** Returns: none
+**
+*******************************************************************************/
+ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
diff --git a/snxxx/libese-spi/src/include/CondVar.h b/snxxx/libese-spi/src/include/CondVar.h
new file mode 100644
index 0000000..a2be51f
--- /dev/null
+++ b/snxxx/libese-spi/src/include/CondVar.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Encapsulate a condition variable for thread synchronization.
+ */
+
+#pragma once
+#include <pthread.h>
+#include "Mutex.h"
+
+class CondVar {
+ public:
+ /*******************************************************************************
+ **
+ ** Function: CondVar
+ **
+ ** Description: Initialize member variables.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ CondVar();
+
+ /*******************************************************************************
+ **
+ ** Function: ~CondVar
+ **
+ ** Description: Cleanup all resources.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~CondVar();
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the caller and wait for a condition.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void wait(Mutex& mutex);
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the caller and wait for a condition.
+ ** millisec: Timeout in milliseconds.
+ **
+ ** Returns: True if wait is successful; false if timeout occurs.
+ **
+ *******************************************************************************/
+ bool wait(Mutex& mutex, long millisec);
+
+ /*******************************************************************************
+ **
+ ** Function: notifyOne
+ **
+ ** Description: Unblock the waiting thread.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void notifyOne();
+
+ private:
+ pthread_cond_t mCondition;
+};
diff --git a/snxxx/libese-spi/src/include/Mutex.h b/snxxx/libese-spi/src/include/Mutex.h
new file mode 100644
index 0000000..bcabf31
--- /dev/null
+++ b/snxxx/libese-spi/src/include/Mutex.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Encapsulate a mutex for thread synchronization.
+ */
+
+#pragma once
+#include <pthread.h>
+
+class Mutex {
+ public:
+ /*******************************************************************************
+ **
+ ** Function: Mutex
+ **
+ ** Description: Initialize member variables.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ Mutex();
+
+ /*******************************************************************************
+ **
+ ** Function: ~Mutex
+ **
+ ** Description: Cleanup all resources.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~Mutex();
+
+ /*******************************************************************************
+ **
+ ** Function: lock
+ **
+ ** Description: Block the thread and try lock the mutex.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void lock();
+
+ /*******************************************************************************
+ **
+ ** Function: unlock
+ **
+ ** Description: Unlock a mutex to unblock a thread.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void unlock();
+
+ /*******************************************************************************
+ **
+ ** Function: tryLock
+ **
+ ** Description: Try to lock the mutex.
+ **
+ ** Returns: True if the mutex is locked.
+ **
+ *******************************************************************************/
+ bool tryLock();
+
+ /*******************************************************************************
+ **
+ ** Function: nativeHandle
+ **
+ ** Description: Get the handle of the mutex.
+ **
+ ** Returns: Handle of the mutex.
+ **
+ *******************************************************************************/
+ pthread_mutex_t* nativeHandle();
+
+ class Autolock {
+ public:
+ inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
+ inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
+ inline ~Autolock() { mLock.unlock(); }
+
+ private:
+ Mutex& mLock;
+ };
+
+ private:
+ pthread_mutex_t mMutex;
+};
+
+typedef Mutex::Autolock AutoMutex;
diff --git a/snxxx/libese-spi/src/include/NfcAdaptation.h b/snxxx/libese-spi/src/include/NfcAdaptation.h
new file mode 100644
index 0000000..18720f6
--- /dev/null
+++ b/snxxx/libese-spi/src/include/NfcAdaptation.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Copyright 2020 NXP
+ *
+ * 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.
+ *
+ ******************************************************************************/
+#pragma once
+#include <pthread.h>
+
+#include <android/hardware/nfc/1.0/types.h>
+#include <phEseStatus.h>
+#include <phNxpEseFeatures.h>
+#include <utils/RefBase.h>
+#include <vendor/nxp/nxpnfc/2.0/INxpNfc.h>
+#include "hal_nxpese.h"
+using vendor::nxp::nxpnfc::V2_0::INxpNfc;
+
+class ThreadMutex {
+ public:
+ ThreadMutex();
+ virtual ~ThreadMutex();
+ void lock();
+ void unlock();
+ operator pthread_mutex_t*() { return &mMutex; }
+
+ private:
+ pthread_mutex_t mMutex;
+};
+
+class ThreadCondVar : public ThreadMutex {
+ public:
+ ThreadCondVar();
+ virtual ~ThreadCondVar();
+ void signal();
+ void wait();
+ operator pthread_cond_t*() { return &mCondVar; }
+ operator pthread_mutex_t*() {
+ return ThreadMutex::operator pthread_mutex_t*();
+ }
+
+ private:
+ pthread_cond_t mCondVar;
+};
+
+class AutoThreadMutex {
+ public:
+ AutoThreadMutex(ThreadMutex& m);
+ virtual ~AutoThreadMutex();
+ operator ThreadMutex&() { return mm; }
+ operator pthread_mutex_t*() { return (pthread_mutex_t*)mm; }
+
+ private:
+ ThreadMutex& mm;
+};
+
+class NfcAdaptation {
+ public:
+ virtual ~NfcAdaptation();
+ void Initialize();
+ static NfcAdaptation& GetInstance();
+ static ESESTATUS resetEse(uint64_t level);
+ static ESESTATUS setEseUpdateState(void* p_data);
+ ese_nxp_IoctlInOutData_t* mCurrentIoctlData;
+
+ private:
+ NfcAdaptation();
+ static NfcAdaptation* mpInstance;
+ static ThreadMutex sLock;
+ static ThreadMutex sIoctlLock;
+ ThreadCondVar mCondVar;
+ static ThreadCondVar mHalIoctlEvent;
+ static android::sp<INxpNfc> mHalNxpNfc;
+};
diff --git a/snxxx/libese-spi/src/include/SyncEvent.h b/snxxx/libese-spi/src/include/SyncEvent.h
new file mode 100644
index 0000000..96851ef
--- /dev/null
+++ b/snxxx/libese-spi/src/include/SyncEvent.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * Synchronize two or more threads using a condition variable and a mutex.
+ */
+#pragma once
+#include "CondVar.h"
+#include "Mutex.h"
+
+class SyncEvent {
+ public:
+ /*******************************************************************************
+ **
+ ** Function: ~SyncEvent
+ **
+ ** Description: Cleanup all resources.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~SyncEvent() {}
+
+ /*******************************************************************************
+ **
+ ** Function: start
+ **
+ ** Description: Start a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void start() { mMutex.lock(); }
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the thread and wait for the event to occur.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void wait() { mCondVar.wait(mMutex); }
+
+ /*******************************************************************************
+ **
+ ** Function: wait
+ **
+ ** Description: Block the thread and wait for the event to occur.
+ ** millisec: Timeout in milliseconds.
+ **
+ ** Returns: True if wait is successful; false if timeout occurs.
+ **
+ *******************************************************************************/
+ bool wait(long millisec) {
+ bool retVal = mCondVar.wait(mMutex, millisec);
+ return retVal;
+ }
+
+ /*******************************************************************************
+ **
+ ** Function: notifyOne
+ **
+ ** Description: Notify a blocked thread that the event has occurred.
+ ** Unblocks it.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void notifyOne() { mCondVar.notifyOne(); }
+
+ /*******************************************************************************
+ **
+ ** Function: end
+ **
+ ** Description: End a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ void end() { mMutex.unlock(); }
+
+ private:
+ CondVar mCondVar;
+ Mutex mMutex;
+};
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+/*****************************************************************************
+**
+** Name: SyncEventGuard
+**
+** Description: Automatically start and end a synchronization event.
+**
+*****************************************************************************/
+class SyncEventGuard {
+ public:
+ /*******************************************************************************
+ **
+ ** Function: SyncEventGuard
+ **
+ ** Description: Start a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ SyncEventGuard(SyncEvent& event) : mEvent(event) {
+ event.start(); // automatically start operation
+ };
+
+ /*******************************************************************************
+ **
+ ** Function: ~SyncEventGuard
+ **
+ ** Description: End a synchronization operation.
+ **
+ ** Returns: None.
+ **
+ *******************************************************************************/
+ ~SyncEventGuard() {
+ mEvent.end(); // automatically end operation
+ };
+
+ private:
+ SyncEvent& mEvent;
+};