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