1 /******************************************************************************
2 *
3 * Copyright 2018-2023 NXP
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 #define LOG_TAG "nxpese@1.2-service"
19 #include <aidl/android/hardware/nfc/INfc.h>
20 #include <android/hardware/nfc/1.2/INfc.h>
21 #include <android/hardware/secure_element/1.2/ISecureElement.h>
22 #include <hidl/LegacySupport.h>
23 #include <log/log.h>
24 #include <string.h>
25
26 #include <regex>
27
28 #include "SecureElement.h"
29 #include "VirtualISO.h"
30 #ifdef NXP_BOOTTIME_UPDATE
31 #include <vendor/nxp/nxpese/1.0/INxpEse.h>
32 #include "NxpEse.h"
33 #include "eSEClient.h"
34 #endif
35
36 #define MAX_NFC_GET_RETRY 30
37 #define NFC_GET_SERVICE_DELAY_MS 100
38
39 // Generated HIDL files
40 using android::OK;
41 using android::base::StringPrintf;
42 using android::hardware::configureRpcThreadpool;
43 using android::hardware::defaultPassthroughServiceImplementation;
44 using android::hardware::joinRpcThreadpool;
45 using android::hardware::registerPassthroughServiceImplementation;
46 using INfc = android::hardware::nfc::V1_2::INfc;
47 using android::hardware::secure_element::V1_2::ISecureElement;
48 using android::hardware::secure_element::V1_2::implementation::SecureElement;
49 #ifdef NXP_BOOTTIME_UPDATE
50 using vendor::nxp::nxpese::V1_0::INxpEse;
51 using vendor::nxp::nxpese::V1_0::implementation::NxpEse;
52 #endif
53 using vendor::nxp::virtual_iso::V1_0::implementation::VirtualISO;
54 using INfcAidl = ::aidl::android::hardware::nfc::INfc;
55
56 using android::OK;
57 using android::sp;
58 using android::status_t;
59
60 std::string NFC_AIDL_HAL_SERVICE_NAME = "android.hardware.nfc.INfc/default";
61
waitForNFCHAL()62 static inline void waitForNFCHAL() {
63 int retry = 0;
64 android::sp<INfc> nfc_service = nullptr;
65 std::shared_ptr<INfcAidl> nfc_aidl_service = nullptr;
66
67 ALOGI("Waiting for NFC HAL .. ");
68 do {
69 ::ndk::SpAIBinder binder(
70 AServiceManager_checkService(NFC_AIDL_HAL_SERVICE_NAME.c_str()));
71 nfc_aidl_service = INfcAidl::fromBinder(binder);
72 if (nfc_aidl_service != nullptr) {
73 ALOGI("NFC HAL service is registered");
74 break;
75 }
76 /* Wait for 100 MS for HAL RETRY*/
77 usleep(NFC_GET_SERVICE_DELAY_MS * 1000);
78 } while (retry++ < MAX_NFC_GET_RETRY);
79
80 if (nfc_aidl_service == nullptr) {
81 ALOGE("Failed to get NFC AIDLHAL Service, trying to get HIDL service");
82 nfc_service = INfc::tryGetService();
83 if (nfc_service != nullptr) {
84 ALOGI("NFC HAL service is registered");
85 } else {
86 ALOGE("Failed to get NFC HAL Service");
87 }
88 }
89 }
90
main()91 int main() {
92 status_t status;
93
94 char terminalID[5] = "eSE1";
95 const char* SEterminal = "eSEx";
96 bool ret = false;
97
98 android::sp<ISecureElement> se_service = nullptr;
99 #ifdef NXP_BOOTTIME_UPDATE
100 android::sp<INxpEse> nxp_se_service = nullptr;
101 #endif
102 android::sp<ISecureElement> virtual_iso_service = nullptr;
103
104 try {
105 waitForNFCHAL();
106 ALOGI("Secure Element HAL Service 1.2 is starting.");
107 se_service = new SecureElement();
108 if (se_service == nullptr) {
109 ALOGE("Can not create an instance of Secure Element HAL Iface, exiting.");
110 goto shutdown;
111 }
112 configureRpcThreadpool(1, true /*callerWillJoin*/);
113
114 #ifdef NXP_BOOTTIME_UPDATE
115 checkEseClientUpdate();
116 ret = geteSETerminalId(terminalID);
117 #else
118 ret = true;
119 #endif
120 ALOGI("Terminal val = %s", terminalID);
121 if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
122 ALOGI("Terminal ID found");
123 status = se_service->registerAsService(terminalID);
124
125 if (status != OK) {
126 ALOGE("Could not register service for Secure Element HAL Iface (%d).",
127 status);
128 goto shutdown;
129 }
130 ALOGI("Secure Element Service is ready");
131 #ifdef NXP_BOOTTIME_UPDATE
132 ALOGI("NXP Secure Element Extn Service 1.0 is starting.");
133 nxp_se_service = new NxpEse();
134 if (nxp_se_service == nullptr) {
135 ALOGE(
136 "Can not create an instance of NXP Secure Element Extn "
137 "Iface,exiting.");
138 goto shutdown;
139 }
140 status = nxp_se_service->registerAsService();
141 if (status != OK) {
142 ALOGE(
143 "Could not register service for Power Secure Element Extn Iface "
144 "(%d).",
145 status);
146 goto shutdown;
147 }
148 ALOGI("Secure Element Service is ready");
149 #endif
150 }
151
152 #ifdef NXP_VISO_ENABLE
153 ALOGI("Virtual ISO HAL Service 1.0 is starting.");
154 virtual_iso_service = new VirtualISO();
155 if (virtual_iso_service == nullptr) {
156 ALOGE("Can not create an instance of Virtual ISO HAL Iface, exiting.");
157 goto shutdown;
158 }
159 #ifdef NXP_BOOTTIME_UPDATE
160 ret = geteUICCTerminalId(terminalID);
161 #else
162 strncpy(terminalID, "eSE2", 4);
163 ret = true;
164 #endif
165 if ((ret) && (strncmp(SEterminal, terminalID, 3) == 0)) {
166 status = virtual_iso_service->registerAsService(terminalID);
167 if (status != OK) {
168 ALOGE("Could not register service for Virtual ISO HAL Iface (%d).",
169 status);
170 goto shutdown;
171 }
172 }
173
174 ALOGI("Virtual ISO: Secure Element Service is ready");
175 #endif
176 #ifdef NXP_BOOTTIME_UPDATE
177 perform_eSEClientUpdate();
178 #endif
179 joinRpcThreadpool();
180 } catch (const std::length_error& e) {
181 ALOGE("Length Exception occurred = %s ", e.what());
182 } catch (const std::__1::ios_base::failure& e) {
183 ALOGE("ios failure Exception occurred = %s ", e.what());
184 } catch (std::__1::regex_error& e) {
185 ALOGE("Regex Exception occurred = %s ", e.what());
186 }
187 // Should not pass this line
188 shutdown:
189 // In normal operation, we don't expect the thread pool to exit
190 ALOGE("Secure Element Service is shutting down");
191 return 1;
192 }
193