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 <android/hardware/secure_element/1.0/ISecureElement.h>
21 #include <android/hardware/secure_element/1.0/ISecureElementHalCallback.h>
22 #include <android/hardware/secure_element/1.0/types.h>
23 #include <hwbinder/ProcessState.h>
24 #include <pthread.h>
25 #include "EseAdaptation.h"
26 #include <log/log.h>
27
28 using android::hardware::Return;
29 using android::hardware::Void;
30 using android::hardware::secure_element::V1_0::ISecureElement;
31 using android::hardware::secure_element::V1_0::ISecureElementHalCallback;
32 using android::hardware::hidl_vec;
33 using android::sp;
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!", func);
197 if(mHalNxpEse != nullptr) {
198 ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::getService() returned %p (%s)",
199 func, mHalNxpEse.get(),
200 (mHalNxpEse->isRemote() ? "remote" : "local"));
201 }
202 /*Transceive NCI_INIT_CMD*/
203 ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
204 }
205 /*******************************************************************************
206 **
207 ** Function: EseAdaptation::HalDeviceContextDataCallback
208 **
209 ** Description: Translate generic Android HAL's callback into Broadcom-specific
210 ** callback function.
211 **
212 ** Returns: None.
213 **
214 *******************************************************************************/
HalDeviceContextDataCallback(uint16_t data_len,uint8_t * p_data)215 void EseAdaptation::HalDeviceContextDataCallback(uint16_t data_len,
216 uint8_t* p_data) {
217 const char* func = "EseAdaptation::HalDeviceContextDataCallback";
218 ALOGD_IF(nfc_debug_enabled, "%s: len=%u", func, data_len);
219 if (mHalDataCallback) mHalDataCallback(data_len, p_data);
220 }
221
222 /*******************************************************************************
223 **
224 ** Function: IoctlCallback
225 **
226 ** Description: Callback from HAL stub for IOCTL api invoked.
227 ** Output data for IOCTL is sent as argument
228 **
229 ** Returns: None.
230 **
231 *******************************************************************************/
IoctlCallback(hidl_vec<uint8_t> outputData)232 void IoctlCallback(hidl_vec<uint8_t> outputData) {
233 const char* func = "IoctlCallback";
234 ese_nxp_ExtnOutputData_t* pOutData =
235 (ese_nxp_ExtnOutputData_t*)&outputData[0];
236 ALOGD_IF(nfc_debug_enabled, "%s Ioctl Type=%lu", func,
237 (unsigned long)pOutData->ioctlType);
238 EseAdaptation* pAdaptation = (EseAdaptation*)pOutData->context;
239 /*Output Data from stub->Proxy is copied back to output data
240 * This data will be sent back to libese*/
241 memcpy(&pAdaptation->mCurrentIoctlData->out, &outputData[0],
242 sizeof(ese_nxp_ExtnOutputData_t));
243 }
244 /*******************************************************************************
245 **
246 ** Function: EseAdaptation::HalIoctl
247 **
248 ** Description: Calls ioctl to the Ese driver.
249 ** If called with a arg value of 0x01 than wired access requested,
250 ** status of the requst would be updated to p_data.
251 ** If called with a arg value of 0x00 than wired access will be
252 ** released, status of the requst would be updated to p_data.
253 ** If called with a arg value of 0x02 than current p61 state would
254 *be
255 ** updated to p_data.
256 **
257 ** Returns: -1 or 0.
258 **
259 *******************************************************************************/
HalIoctl(long arg,void * p_data)260 int EseAdaptation::HalIoctl(long arg, void* p_data) {
261 const char* func = "EseAdaptation::HalIoctl";
262 hidl_vec<uint8_t> data;
263 AutoThreadMutex a(sIoctlLock);
264 ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
265 ALOGD_IF(nfc_debug_enabled, "%s arg=%ld", func, arg);
266 pInpOutData->inp.context = &EseAdaptation::GetInstance();
267 EseAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
268 data.setToExternal((uint8_t*)pInpOutData, sizeof(ese_nxp_IoctlInOutData_t));
269 if (mHalNxpEse != nullptr) mHalNxpEse->ioctl(arg, data, IoctlCallback);
270 ALOGD_IF(nfc_debug_enabled, "%s Ioctl Completed for Type=%lu", func,
271 (unsigned long)pInpOutData->out.ioctlType);
272 return (pInpOutData->out.result);
273 }
274
275 /*******************************************************************************
276 **
277 ** Function: ThreadMutex::ThreadMutex()
278 **
279 ** Description: class constructor
280 **
281 ** Returns: none
282 **
283 *******************************************************************************/
ThreadMutex()284 ThreadMutex::ThreadMutex() {
285 pthread_mutexattr_t mutexAttr;
286
287 pthread_mutexattr_init(&mutexAttr);
288 pthread_mutex_init(&mMutex, &mutexAttr);
289 pthread_mutexattr_destroy(&mutexAttr);
290 }
291
292 /*******************************************************************************
293 **
294 ** Function: ThreadMutex::~ThreadMutex()
295 **
296 ** Description: class destructor
297 **
298 ** Returns: none
299 **
300 *******************************************************************************/
~ThreadMutex()301 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
302
303 /*******************************************************************************
304 **
305 ** Function: ThreadMutex::lock()
306 **
307 ** Description: lock kthe mutex
308 **
309 ** Returns: none
310 **
311 *******************************************************************************/
lock()312 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
313
314 /*******************************************************************************
315 **
316 ** Function: ThreadMutex::unblock()
317 **
318 ** Description: unlock the mutex
319 **
320 ** Returns: none
321 **
322 *******************************************************************************/
unlock()323 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
324
325 /*******************************************************************************
326 **
327 ** Function: ThreadCondVar::ThreadCondVar()
328 **
329 ** Description: class constructor
330 **
331 ** Returns: none
332 **
333 *******************************************************************************/
ThreadCondVar()334 ThreadCondVar::ThreadCondVar() {
335 pthread_condattr_t CondAttr;
336
337 pthread_condattr_init(&CondAttr);
338 pthread_cond_init(&mCondVar, &CondAttr);
339
340 pthread_condattr_destroy(&CondAttr);
341 }
342
343 /*******************************************************************************
344 **
345 ** Function: ThreadCondVar::~ThreadCondVar()
346 **
347 ** Description: class destructor
348 **
349 ** Returns: none
350 **
351 *******************************************************************************/
~ThreadCondVar()352 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
353
354 /*******************************************************************************
355 **
356 ** Function: ThreadCondVar::wait()
357 **
358 ** Description: wait on the mCondVar
359 **
360 ** Returns: none
361 **
362 *******************************************************************************/
wait()363 void ThreadCondVar::wait() {
364 pthread_cond_wait(&mCondVar, *this);
365 pthread_mutex_unlock(*this);
366 }
367
368 /*******************************************************************************
369 **
370 ** Function: ThreadCondVar::signal()
371 **
372 ** Description: signal the mCondVar
373 **
374 ** Returns: none
375 **
376 *******************************************************************************/
signal()377 void ThreadCondVar::signal() {
378 AutoThreadMutex a(*this);
379 pthread_cond_signal(&mCondVar);
380 }
381
382 /*******************************************************************************
383 **
384 ** Function: AutoThreadMutex::AutoThreadMutex()
385 **
386 ** Description: class constructor, automatically lock the mutex
387 **
388 ** Returns: none
389 **
390 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)391 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
392
393 /*******************************************************************************
394 **
395 ** Function: AutoThreadMutex::~AutoThreadMutex()
396 **
397 ** Description: class destructor, automatically unlock the mutex
398 **
399 ** Returns: none
400 **
401 *******************************************************************************/
~AutoThreadMutex()402 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
403