1 /******************************************************************************
2  *
3  *
4  *  Copyright 2015-2021 NXP
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  ******************************************************************************/
19 #define LOG_TAG "EseAdaptation"
20 #include "EseAdaptation.h"
21 #include <android/hardware/secure_element/1.0/ISecureElement.h>
22 #include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h>
23 #include <android/hardware/secure_element/1.0/types.h>
24 #include <hwbinder/ProcessState.h>
25 #include <log/log.h>
26 #include <pthread.h>
27 
28 using android::sp;
29 using android::hardware::hidl_vec;
30 using android::hardware::Return;
31 using android::hardware::Void;
32 using android::hardware::secure_element::V1_0::ISecureElement;
33 using android::hardware::secure_element::V1_0::ISecureElementHalCallback;
34 
35 using vendor::nxp::nxpese::V1_0::INxpEse;
36 
37 extern bool nfc_debug_enabled;
38 
39 extern "C" void GKI_shutdown();
40 extern void resetConfig();
41 extern "C" void verify_stack_non_volatile_store();
42 extern "C" void delete_stack_non_volatile_store(bool forceDelete);
43 
44 EseAdaptation* EseAdaptation::mpInstance = NULL;
45 ThreadMutex EseAdaptation::sLock;
46 ThreadMutex EseAdaptation::sIoctlLock;
47 sp<INxpEse> EseAdaptation::mHalNxpEse;
48 sp<ISecureElement> EseAdaptation::mHal;
49 tHAL_ESE_CBACK* EseAdaptation::mHalCallback = NULL;
50 tHAL_ESE_DATA_CBACK* EseAdaptation::mHalDataCallback = NULL;
51 ThreadCondVar EseAdaptation::mHalOpenCompletedEvent;
52 ThreadCondVar EseAdaptation::mHalCloseCompletedEvent;
53 
54 #if (NXP_EXTNS == TRUE)
55 ThreadCondVar EseAdaptation::mHalCoreResetCompletedEvent;
56 ThreadCondVar EseAdaptation::mHalCoreInitCompletedEvent;
57 ThreadCondVar EseAdaptation::mHalInitCompletedEvent;
58 #endif
59 #define SIGNAL_NONE 0
60 #define SIGNAL_SIGNALED 1
61 
62 /*******************************************************************************
63 **
64 ** Function:    EseAdaptation::EseAdaptation()
65 **
66 ** Description: class constructor
67 **
68 ** Returns:     none
69 **
70 *******************************************************************************/
EseAdaptation()71 EseAdaptation::EseAdaptation() {
72   mCurrentIoctlData = NULL;
73   memset(&mSpiHalEntryFuncs, 0, sizeof(mSpiHalEntryFuncs));
74 }
75 
76 /*******************************************************************************
77 **
78 ** Function:    EseAdaptation::~EseAdaptation()
79 **
80 ** Description: class destructor
81 **
82 ** Returns:     none
83 **
84 *******************************************************************************/
~EseAdaptation()85 EseAdaptation::~EseAdaptation() { mpInstance = NULL; }
86 
87 /*******************************************************************************
88 **
89 ** Function:    EseAdaptation::GetInstance()
90 **
91 ** Description: access class singleton
92 **
93 ** Returns:     pointer to the singleton object
94 **
95 *******************************************************************************/
GetInstance()96 EseAdaptation& EseAdaptation::GetInstance() {
97   AutoThreadMutex a(sLock);
98 
99   if (!mpInstance) mpInstance = new EseAdaptation;
100   return *mpInstance;
101 }
102 
103 /*******************************************************************************
104 **
105 ** Function:    EseAdaptation::Initialize()
106 **
107 ** Description: class initializer
108 **
109 ** Returns:     none
110 **
111 *******************************************************************************/
Initialize()112 void EseAdaptation::Initialize() {
113   const char* func = "EseAdaptation::Initialize";
114   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
115 
116   mHalCallback = NULL;
117   InitializeHalDeviceContext();
118 
119   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
120 }
121 
122 /*******************************************************************************
123 **
124 ** Function:    EseAdaptation::signal()
125 **
126 ** Description: signal the CondVar to release the thread that is waiting
127 **
128 ** Returns:     none
129 **
130 *******************************************************************************/
signal()131 void EseAdaptation::signal() { mCondVar.signal(); }
132 
133 /*******************************************************************************
134 **
135 ** Function:    EseAdaptation::Thread()
136 **
137 ** Description: Creates work threads
138 **
139 ** Returns:     none
140 **
141 *******************************************************************************/
Thread(uint32_t arg)142 uint32_t EseAdaptation::Thread(uint32_t arg) {
143   const char* func = "EseAdaptation::Thread";
144   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
145   arg = 0;
146   { ThreadCondVar CondVar; }
147 
148   EseAdaptation::GetInstance().signal();
149 
150   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
151   return 0;
152 }
153 
154 /*******************************************************************************
155 **
156 ** Function:    EseAdaptation::GetHalEntryFuncs()
157 **
158 ** Description: Get the set of HAL entry points.
159 **
160 ** Returns:     Functions pointers for HAL entry points.
161 **
162 *******************************************************************************/
GetHalEntryFuncs()163 tHAL_ESE_ENTRY* EseAdaptation::GetHalEntryFuncs() {
164   ALOGD_IF(nfc_debug_enabled, "GetHalEntryFuncs: enter");
165   return &mSpiHalEntryFuncs;
166 }
167 
168 /*******************************************************************************
169 **
170 ** Function:    EseAdaptation::InitializeHalDeviceContext
171 **
172 ** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
173 **
174 ** Returns:     None.
175 **
176 *******************************************************************************/
177 
InitializeHalDeviceContext()178 void EseAdaptation::InitializeHalDeviceContext() {
179   const char* func = "EseAdaptation::InitializeHalDeviceContext";
180   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
181   ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::tryGetService()", func);
182   mHalNxpEse = INxpEse::tryGetService();
183   ALOGD_IF(mHalNxpEse == nullptr, "%s: Failed to retrieve the NXP ESE HAL!",
184            func);
185   if (mHalNxpEse != nullptr) {
186     ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::getService() returned %p (%s)",
187              func, mHalNxpEse.get(),
188              (mHalNxpEse->isRemote() ? "remote" : "local"));
189   }
190   /*Transceive NCI_INIT_CMD*/
191   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
192 }
193 /*******************************************************************************
194 **
195 ** Function:    EseAdaptation::HalDeviceContextDataCallback
196 **
197 ** Description: Translate generic Android HAL's callback into Broadcom-specific
198 **              callback function.
199 **
200 ** Returns:     None.
201 **
202 *******************************************************************************/
HalDeviceContextDataCallback(uint16_t data_len,uint8_t * p_data)203 void EseAdaptation::HalDeviceContextDataCallback(uint16_t data_len,
204                                                  uint8_t* p_data) {
205   const char* func = "EseAdaptation::HalDeviceContextDataCallback";
206   ALOGD_IF(nfc_debug_enabled, "%s: len=%u", func, data_len);
207   if (mHalDataCallback) mHalDataCallback(data_len, p_data);
208 }
209 
210 /*******************************************************************************
211 **
212 ** Function:    IoctlCallback
213 **
214 ** Description: Callback from HAL stub for IOCTL api invoked.
215 **              Output data for IOCTL is sent as argument
216 **
217 ** Returns:     None.
218 **
219 *******************************************************************************/
IoctlCallback(hidl_vec<uint8_t> outputData)220 void IoctlCallback(hidl_vec<uint8_t> outputData) {
221   const char* func = "IoctlCallback";
222   ese_nxp_ExtnOutputData_t* pOutData =
223       (ese_nxp_ExtnOutputData_t*)&outputData[0];
224   ALOGD_IF(nfc_debug_enabled, "%s Ioctl Type=%lu", func,
225            (unsigned long)pOutData->ioctlType);
226   EseAdaptation* pAdaptation = &EseAdaptation::GetInstance();
227   /*Output Data from stub->Proxy is copied back to output data
228    * This data will be sent back to libese*/
229   memcpy(&pAdaptation->mCurrentIoctlData->out, &outputData[0],
230          sizeof(ese_nxp_ExtnOutputData_t));
231 }
232 /*******************************************************************************
233 **
234 ** Function:    EseAdaptation::HalIoctl
235 **
236 ** Description: Calls ioctl to the Ese driver.
237 **              If called with a arg value of 0x01 than wired access requested,
238 **              status of the request would be updated to p_data.
239 **              If called with a arg value of 0x00 than wired access will be
240 **              released, status of the request would be updated to p_data.
241 **              If called with a arg value of 0x02 than current p61 state would
242 *be
243 **              updated to p_data.
244 **
245 ** Returns:     -1 or 0.
246 **
247 *******************************************************************************/
HalIoctl(long arg,void * p_data)248 int EseAdaptation::HalIoctl(long arg, void* p_data) {
249   const char* func = "EseAdaptation::HalIoctl";
250   hidl_vec<uint8_t> data;
251   AutoThreadMutex a(sIoctlLock);
252   ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
253   ALOGD_IF(nfc_debug_enabled, "%s arg=%ld", func, arg);
254 
255   EseAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
256   data.setToExternal((uint8_t*)pInpOutData, sizeof(ese_nxp_IoctlInOutData_t));
257   if (mHalNxpEse != nullptr) mHalNxpEse->ioctl(arg, data, IoctlCallback);
258   ALOGD_IF(nfc_debug_enabled, "%s Ioctl Completed for Type=%lu", func,
259            (unsigned long)pInpOutData->out.ioctlType);
260   return (pInpOutData->out.result);
261 }
262 
263 /*******************************************************************************
264 **
265 ** Function:    ThreadMutex::ThreadMutex()
266 **
267 ** Description: class constructor
268 **
269 ** Returns:     none
270 **
271 *******************************************************************************/
ThreadMutex()272 ThreadMutex::ThreadMutex() {
273   pthread_mutexattr_t mutexAttr;
274 
275   pthread_mutexattr_init(&mutexAttr);
276   pthread_mutex_init(&mMutex, &mutexAttr);
277   pthread_mutexattr_destroy(&mutexAttr);
278 }
279 
280 /*******************************************************************************
281 **
282 ** Function:    ThreadMutex::~ThreadMutex()
283 **
284 ** Description: class destructor
285 **
286 ** Returns:     none
287 **
288 *******************************************************************************/
~ThreadMutex()289 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
290 
291 /*******************************************************************************
292 **
293 ** Function:    ThreadMutex::lock()
294 **
295 ** Description: lock kthe mutex
296 **
297 ** Returns:     none
298 **
299 *******************************************************************************/
lock()300 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
301 
302 /*******************************************************************************
303 **
304 ** Function:    ThreadMutex::unblock()
305 **
306 ** Description: unlock the mutex
307 **
308 ** Returns:     none
309 **
310 *******************************************************************************/
unlock()311 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
312 
313 /*******************************************************************************
314 **
315 ** Function:    ThreadCondVar::ThreadCondVar()
316 **
317 ** Description: class constructor
318 **
319 ** Returns:     none
320 **
321 *******************************************************************************/
ThreadCondVar()322 ThreadCondVar::ThreadCondVar() {
323   pthread_condattr_t CondAttr;
324 
325   pthread_condattr_init(&CondAttr);
326   pthread_cond_init(&mCondVar, &CondAttr);
327 
328   pthread_condattr_destroy(&CondAttr);
329 }
330 
331 /*******************************************************************************
332 **
333 ** Function:    ThreadCondVar::~ThreadCondVar()
334 **
335 ** Description: class destructor
336 **
337 ** Returns:     none
338 **
339 *******************************************************************************/
~ThreadCondVar()340 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
341 
342 /*******************************************************************************
343 **
344 ** Function:    ThreadCondVar::wait()
345 **
346 ** Description: wait on the mCondVar
347 **
348 ** Returns:     none
349 **
350 *******************************************************************************/
wait()351 void ThreadCondVar::wait() {
352   pthread_cond_wait(&mCondVar, *this);
353   pthread_mutex_unlock(*this);
354 }
355 
356 /*******************************************************************************
357 **
358 ** Function:    ThreadCondVar::signal()
359 **
360 ** Description: signal the mCondVar
361 **
362 ** Returns:     none
363 **
364 *******************************************************************************/
signal()365 void ThreadCondVar::signal() {
366   AutoThreadMutex a(*this);
367   pthread_cond_signal(&mCondVar);
368 }
369 
370 /*******************************************************************************
371 **
372 ** Function:    AutoThreadMutex::AutoThreadMutex()
373 **
374 ** Description: class constructor, automatically lock the mutex
375 **
376 ** Returns:     none
377 **
378 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)379 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
380 
381 /*******************************************************************************
382 **
383 ** Function:    AutoThreadMutex::~AutoThreadMutex()
384 **
385 ** Description: class destructor, automatically unlock the mutex
386 **
387 ** Returns:     none
388 **
389 *******************************************************************************/
~AutoThreadMutex()390 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
391