1 /******************************************************************************
2  *
3  *
4  *  Copyright (C) 2015 NXP Semiconductors
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 #define SIGNAL_NONE 0
59 #define SIGNAL_SIGNALED 1
60 static uint8_t isSignaled = SIGNAL_NONE;
61 static uint8_t evt_status;
62 #endif
63 
64 /*******************************************************************************
65 **
66 ** Function:    EseAdaptation::EseAdaptation()
67 **
68 ** Description: class constructor
69 **
70 ** Returns:     none
71 **
72 *******************************************************************************/
EseAdaptation()73 EseAdaptation::EseAdaptation() {
74   mCurrentIoctlData = NULL;
75   memset(&mSpiHalEntryFuncs, 0, sizeof(mSpiHalEntryFuncs));
76 }
77 
78 /*******************************************************************************
79 **
80 ** Function:    EseAdaptation::~EseAdaptation()
81 **
82 ** Description: class destructor
83 **
84 ** Returns:     none
85 **
86 *******************************************************************************/
~EseAdaptation()87 EseAdaptation::~EseAdaptation() { mpInstance = NULL; }
88 
89 /*******************************************************************************
90 **
91 ** Function:    EseAdaptation::GetInstance()
92 **
93 ** Description: access class singleton
94 **
95 ** Returns:     pointer to the singleton object
96 **
97 *******************************************************************************/
GetInstance()98 EseAdaptation& EseAdaptation::GetInstance() {
99   AutoThreadMutex a(sLock);
100 
101   if (!mpInstance) mpInstance = new EseAdaptation;
102   return *mpInstance;
103 }
104 
105 /*******************************************************************************
106 **
107 ** Function:    EseAdaptation::Initialize()
108 **
109 ** Description: class initializer
110 **
111 ** Returns:     none
112 **
113 *******************************************************************************/
Initialize()114 void EseAdaptation::Initialize() {
115   const char* func = "EseAdaptation::Initialize";
116   uint8_t cmd_ese_nxp[] = {0x2F, 0x01, 0x01, 0x01};
117   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
118 
119   mHalCallback = NULL;
120   ese_nxp_IoctlInOutData_t* pInpOutData;
121   pInpOutData =
122       (ese_nxp_IoctlInOutData_t*)malloc(sizeof(ese_nxp_IoctlInOutData_t));
123   if (!pInpOutData) {
124     ALOGE("%s Unable to initialize as memory allocation failed", __func__);
125     return;
126   }
127   memset(pInpOutData, 0x00, sizeof(ese_nxp_IoctlInOutData_t));
128   pInpOutData->inp.data.nxpCmd.cmd_len = sizeof(cmd_ese_nxp);
129   memcpy(pInpOutData->inp.data.nxpCmd.p_cmd, cmd_ese_nxp, sizeof(cmd_ese_nxp));
130   InitializeHalDeviceContext();
131   if (pInpOutData != NULL) free(pInpOutData);
132   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
133 }
134 
135 /*******************************************************************************
136 **
137 ** Function:    EseAdaptation::signal()
138 **
139 ** Description: signal the CondVar to release the thread that is waiting
140 **
141 ** Returns:     none
142 **
143 *******************************************************************************/
signal()144 void EseAdaptation::signal() { mCondVar.signal(); }
145 
146 /*******************************************************************************
147 **
148 ** Function:    EseAdaptation::Thread()
149 **
150 ** Description: Creates work threads
151 **
152 ** Returns:     none
153 **
154 *******************************************************************************/
Thread(uint32_t arg)155 uint32_t EseAdaptation::Thread(uint32_t arg) {
156   const char* func = "EseAdaptation::Thread";
157   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
158   arg = 0;
159   { ThreadCondVar CondVar; }
160 
161   EseAdaptation::GetInstance().signal();
162 
163   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
164   return 0;
165 }
166 
167 /*******************************************************************************
168 **
169 ** Function:    EseAdaptation::GetHalEntryFuncs()
170 **
171 ** Description: Get the set of HAL entry points.
172 **
173 ** Returns:     Functions pointers for HAL entry points.
174 **
175 *******************************************************************************/
GetHalEntryFuncs()176 tHAL_ESE_ENTRY* EseAdaptation::GetHalEntryFuncs() {
177   ALOGD_IF(nfc_debug_enabled, "GetHalEntryFuncs: enter");
178   return &mSpiHalEntryFuncs;
179 }
180 
181 /*******************************************************************************
182 **
183 ** Function:    EseAdaptation::InitializeHalDeviceContext
184 **
185 ** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
186 **
187 ** Returns:     None.
188 **
189 *******************************************************************************/
190 
InitializeHalDeviceContext()191 void EseAdaptation::InitializeHalDeviceContext() {
192   const char* func = "EseAdaptation::InitializeHalDeviceContext";
193   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
194   ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::tryGetService()", func);
195   mHalNxpEse = INxpEse::tryGetService();
196   ALOGD_IF(mHalNxpEse == nullptr, "%s: Failed to retrieve the NXP ESE HAL!",
197            func);
198   if (mHalNxpEse != nullptr) {
199     ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::getService() returned %p (%s)",
200              func, mHalNxpEse.get(),
201              (mHalNxpEse->isRemote() ? "remote" : "local"));
202   }
203   /*Transceive NCI_INIT_CMD*/
204   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
205 }
206 /*******************************************************************************
207 **
208 ** Function:    EseAdaptation::HalDeviceContextDataCallback
209 **
210 ** Description: Translate generic Android HAL's callback into Broadcom-specific
211 **              callback function.
212 **
213 ** Returns:     None.
214 **
215 *******************************************************************************/
HalDeviceContextDataCallback(uint16_t data_len,uint8_t * p_data)216 void EseAdaptation::HalDeviceContextDataCallback(uint16_t data_len,
217                                                  uint8_t* p_data) {
218   const char* func = "EseAdaptation::HalDeviceContextDataCallback";
219   ALOGD_IF(nfc_debug_enabled, "%s: len=%u", func, data_len);
220   if (mHalDataCallback) mHalDataCallback(data_len, p_data);
221 }
222 
223 /*******************************************************************************
224 **
225 ** Function:    IoctlCallback
226 **
227 ** Description: Callback from HAL stub for IOCTL api invoked.
228 **              Output data for IOCTL is sent as argument
229 **
230 ** Returns:     None.
231 **
232 *******************************************************************************/
IoctlCallback(hidl_vec<uint8_t> outputData)233 void IoctlCallback(hidl_vec<uint8_t> outputData) {
234   const char* func = "IoctlCallback";
235   ese_nxp_ExtnOutputData_t* pOutData =
236       (ese_nxp_ExtnOutputData_t*)&outputData[0];
237   ALOGD_IF(nfc_debug_enabled, "%s Ioctl Type=%lu", func,
238            (unsigned long)pOutData->ioctlType);
239   EseAdaptation* pAdaptation = (EseAdaptation*)pOutData->context;
240   /*Output Data from stub->Proxy is copied back to output data
241    * This data will be sent back to libese*/
242   memcpy(&pAdaptation->mCurrentIoctlData->out, &outputData[0],
243          sizeof(ese_nxp_ExtnOutputData_t));
244 }
245 /*******************************************************************************
246 **
247 ** Function:    EseAdaptation::HalIoctl
248 **
249 ** Description: Calls ioctl to the Ese driver.
250 **              If called with a arg value of 0x01 than wired access requested,
251 **              status of the requst would be updated to p_data.
252 **              If called with a arg value of 0x00 than wired access will be
253 **              released, status of the requst would be updated to p_data.
254 **              If called with a arg value of 0x02 than current p61 state would
255 *be
256 **              updated to p_data.
257 **
258 ** Returns:     -1 or 0.
259 **
260 *******************************************************************************/
HalIoctl(long arg,void * p_data)261 int EseAdaptation::HalIoctl(long arg, void* p_data) {
262   const char* func = "EseAdaptation::HalIoctl";
263   hidl_vec<uint8_t> data;
264   AutoThreadMutex a(sIoctlLock);
265   ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
266   ALOGD_IF(nfc_debug_enabled, "%s arg=%ld", func, arg);
267   pInpOutData->inp.context = &EseAdaptation::GetInstance();
268   EseAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
269   data.setToExternal((uint8_t*)pInpOutData, sizeof(ese_nxp_IoctlInOutData_t));
270   if (mHalNxpEse != nullptr) mHalNxpEse->ioctl(arg, data, IoctlCallback);
271   ALOGD_IF(nfc_debug_enabled, "%s Ioctl Completed for Type=%lu", func,
272            (unsigned long)pInpOutData->out.ioctlType);
273   return (pInpOutData->out.result);
274 }
275 
276 /*******************************************************************************
277 **
278 ** Function:    ThreadMutex::ThreadMutex()
279 **
280 ** Description: class constructor
281 **
282 ** Returns:     none
283 **
284 *******************************************************************************/
ThreadMutex()285 ThreadMutex::ThreadMutex() {
286   pthread_mutexattr_t mutexAttr;
287 
288   pthread_mutexattr_init(&mutexAttr);
289   pthread_mutex_init(&mMutex, &mutexAttr);
290   pthread_mutexattr_destroy(&mutexAttr);
291 }
292 
293 /*******************************************************************************
294 **
295 ** Function:    ThreadMutex::~ThreadMutex()
296 **
297 ** Description: class destructor
298 **
299 ** Returns:     none
300 **
301 *******************************************************************************/
~ThreadMutex()302 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
303 
304 /*******************************************************************************
305 **
306 ** Function:    ThreadMutex::lock()
307 **
308 ** Description: lock kthe mutex
309 **
310 ** Returns:     none
311 **
312 *******************************************************************************/
lock()313 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
314 
315 /*******************************************************************************
316 **
317 ** Function:    ThreadMutex::unblock()
318 **
319 ** Description: unlock the mutex
320 **
321 ** Returns:     none
322 **
323 *******************************************************************************/
unlock()324 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
325 
326 /*******************************************************************************
327 **
328 ** Function:    ThreadCondVar::ThreadCondVar()
329 **
330 ** Description: class constructor
331 **
332 ** Returns:     none
333 **
334 *******************************************************************************/
ThreadCondVar()335 ThreadCondVar::ThreadCondVar() {
336   pthread_condattr_t CondAttr;
337 
338   pthread_condattr_init(&CondAttr);
339   pthread_cond_init(&mCondVar, &CondAttr);
340 
341   pthread_condattr_destroy(&CondAttr);
342 }
343 
344 /*******************************************************************************
345 **
346 ** Function:    ThreadCondVar::~ThreadCondVar()
347 **
348 ** Description: class destructor
349 **
350 ** Returns:     none
351 **
352 *******************************************************************************/
~ThreadCondVar()353 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
354 
355 /*******************************************************************************
356 **
357 ** Function:    ThreadCondVar::wait()
358 **
359 ** Description: wait on the mCondVar
360 **
361 ** Returns:     none
362 **
363 *******************************************************************************/
wait()364 void ThreadCondVar::wait() {
365   pthread_cond_wait(&mCondVar, *this);
366   pthread_mutex_unlock(*this);
367 }
368 
369 /*******************************************************************************
370 **
371 ** Function:    ThreadCondVar::signal()
372 **
373 ** Description: signal the mCondVar
374 **
375 ** Returns:     none
376 **
377 *******************************************************************************/
signal()378 void ThreadCondVar::signal() {
379   AutoThreadMutex a(*this);
380   pthread_cond_signal(&mCondVar);
381 }
382 
383 /*******************************************************************************
384 **
385 ** Function:    AutoThreadMutex::AutoThreadMutex()
386 **
387 ** Description: class constructor, automatically lock the mutex
388 **
389 ** Returns:     none
390 **
391 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)392 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
393 
394 /*******************************************************************************
395 **
396 ** Function:    AutoThreadMutex::~AutoThreadMutex()
397 **
398 ** Description: class destructor, automatically unlock the mutex
399 **
400 ** Returns:     none
401 **
402 *******************************************************************************/
~AutoThreadMutex()403 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
404