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