1 /******************************************************************************
2  *
3  *
4  *  Copyright 2015-2023 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 
22 #include <hwbinder/ProcessState.h>
23 #include <log/log.h>
24 
25 using android::sp;
26 using android::hardware::hidl_vec;
27 using android::hardware::Return;
28 using android::hardware::Void;
29 
30 using vendor::nxp::nxpese::V1_0::INxpEse;
31 
32 extern bool nfc_debug_enabled;
33 
34 extern "C" void GKI_shutdown();
35 extern void resetConfig();
36 extern "C" void verify_stack_non_volatile_store();
37 extern "C" void delete_stack_non_volatile_store(bool forceDelete);
38 
39 EseAdaptation* EseAdaptation::mpInstance = NULL;
40 NfcHalThreadMutex EseAdaptation::sLock;
41 NfcHalThreadMutex EseAdaptation::sIoctlLock;
42 sp<INxpEse> EseAdaptation::mHalNxpEse;
43 tHAL_ESE_CBACK* EseAdaptation::mHalCallback = NULL;
44 tHAL_ESE_DATA_CBACK* EseAdaptation::mHalDataCallback = NULL;
45 NfcHalThreadCondVar EseAdaptation::mHalOpenCompletedEvent;
46 NfcHalThreadCondVar EseAdaptation::mHalCloseCompletedEvent;
47 
48 NfcHalThreadCondVar EseAdaptation::mHalCoreResetCompletedEvent;
49 NfcHalThreadCondVar EseAdaptation::mHalCoreInitCompletedEvent;
50 NfcHalThreadCondVar EseAdaptation::mHalInitCompletedEvent;
51 #define SIGNAL_NONE 0
52 #define SIGNAL_SIGNALED 1
53 
54 /*******************************************************************************
55 **
56 ** Function:    EseAdaptation::EseAdaptation()
57 **
58 ** Description: class constructor
59 **
60 ** Returns:     none
61 **
62 *******************************************************************************/
EseAdaptation()63 EseAdaptation::EseAdaptation() {
64   mCurrentIoctlData = NULL;
65   memset(&mSpiHalEntryFuncs, 0, sizeof(mSpiHalEntryFuncs));
66 }
67 
68 /*******************************************************************************
69 **
70 ** Function:    EseAdaptation::~EseAdaptation()
71 **
72 ** Description: class destructor
73 **
74 ** Returns:     none
75 **
76 *******************************************************************************/
~EseAdaptation()77 EseAdaptation::~EseAdaptation() { mpInstance = NULL; }
78 
79 /*******************************************************************************
80 **
81 ** Function:    EseAdaptation::GetInstance()
82 **
83 ** Description: access class singleton
84 **
85 ** Returns:     pointer to the singleton object
86 **
87 *******************************************************************************/
GetInstance()88 EseAdaptation& EseAdaptation::GetInstance() {
89   NfcHalAutoThreadMutex a(sLock);
90 
91   if (!mpInstance) mpInstance = new EseAdaptation;
92   return *mpInstance;
93 }
94 
95 /*******************************************************************************
96 **
97 ** Function:    EseAdaptation::Initialize()
98 **
99 ** Description: class initializer
100 **
101 ** Returns:     none
102 **
103 *******************************************************************************/
Initialize()104 void EseAdaptation::Initialize() {
105   const char* func = "EseAdaptation::Initialize";
106   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
107 
108   mHalCallback = NULL;
109   InitializeHalDeviceContext();
110 
111   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
112 }
113 
114 /*******************************************************************************
115 **
116 ** Function:    EseAdaptation::signal()
117 **
118 ** Description: signal the CondVar to release the thread that is waiting
119 **
120 ** Returns:     none
121 **
122 *******************************************************************************/
signal()123 void EseAdaptation::signal() { mCondVar.signal(); }
124 
125 /*******************************************************************************
126 **
127 ** Function:    EseAdaptation::Thread()
128 **
129 ** Description: Creates work threads
130 **
131 ** Returns:     none
132 **
133 *******************************************************************************/
Thread()134 uint32_t EseAdaptation::Thread() {
135   const char* func = "EseAdaptation::Thread";
136   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
137   { NfcHalThreadCondVar CondVar; }
138 
139   EseAdaptation::GetInstance().signal();
140 
141   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
142   return 0;
143 }
144 
145 /*******************************************************************************
146 **
147 ** Function:    EseAdaptation::GetHalEntryFuncs()
148 **
149 ** Description: Get the set of HAL entry points.
150 **
151 ** Returns:     Functions pointers for HAL entry points.
152 **
153 *******************************************************************************/
GetHalEntryFuncs()154 tHAL_ESE_ENTRY* EseAdaptation::GetHalEntryFuncs() {
155   ALOGD_IF(nfc_debug_enabled, "GetHalEntryFuncs: enter");
156   return &mSpiHalEntryFuncs;
157 }
158 
159 /*******************************************************************************
160 **
161 ** Function:    EseAdaptation::InitializeHalDeviceContext
162 **
163 ** Description: Ask the generic Android HAL to find the Broadcom-specific HAL.
164 **
165 ** Returns:     None.
166 **
167 *******************************************************************************/
168 
InitializeHalDeviceContext()169 void EseAdaptation::InitializeHalDeviceContext() {
170   const char* func = "EseAdaptation::InitializeHalDeviceContext";
171   ALOGD_IF(nfc_debug_enabled, "%s: enter", func);
172   ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::tryGetService()", func);
173   mHalNxpEse = INxpEse::tryGetService();
174   ALOGD_IF(mHalNxpEse == nullptr, "%s: Failed to retrieve the NXP ESE HAL!",
175            func);
176   if (mHalNxpEse != nullptr) {
177     ALOGD_IF(nfc_debug_enabled, "%s: INxpEse::getService() returned %p (%s)",
178              func, mHalNxpEse.get(),
179              (mHalNxpEse->isRemote() ? "remote" : "local"));
180   }
181   /*Transceive NCI_INIT_CMD*/
182   ALOGD_IF(nfc_debug_enabled, "%s: exit", func);
183 }
184 /*******************************************************************************
185 **
186 ** Function:    EseAdaptation::HalDeviceContextDataCallback
187 **
188 ** Description: Translate generic Android HAL's callback into Broadcom-specific
189 **              callback function.
190 **
191 ** Returns:     None.
192 **
193 *******************************************************************************/
HalDeviceContextDataCallback(uint16_t data_len,uint8_t * p_data)194 void EseAdaptation::HalDeviceContextDataCallback(uint16_t data_len,
195                                                  uint8_t* p_data) {
196   const char* func = "EseAdaptation::HalDeviceContextDataCallback";
197   ALOGD_IF(nfc_debug_enabled, "%s: len=%u", func, data_len);
198   if (mHalDataCallback) mHalDataCallback(data_len, p_data);
199 }
200 
201 /*******************************************************************************
202 **
203 ** Function:    IoctlCallback
204 **
205 ** Description: Callback from HAL stub for IOCTL api invoked.
206 **              Output data for IOCTL is sent as argument
207 **
208 ** Returns:     None.
209 **
210 *******************************************************************************/
IoctlCallback(hidl_vec<uint8_t> outputData)211 void IoctlCallback(hidl_vec<uint8_t> outputData) {
212   const char* func = "IoctlCallback";
213   ese_nxp_ExtnOutputData_t* pOutData =
214       (ese_nxp_ExtnOutputData_t*)&outputData[0];
215   ALOGD_IF(nfc_debug_enabled, "%s Ioctl Type=%lu", func,
216            (unsigned long)pOutData->ioctlType);
217   EseAdaptation* pAdaptation = &EseAdaptation::GetInstance();
218   /*Output Data from stub->Proxy is copied back to output data
219    * This data will be sent back to libese*/
220   memcpy(&pAdaptation->mCurrentIoctlData->out, &outputData[0],
221          sizeof(ese_nxp_ExtnOutputData_t));
222 }
223 /*******************************************************************************
224 **
225 ** Function:    EseAdaptation::HalIoctl
226 **
227 ** Description: Calls ioctl to the Ese driver.
228 **              If called with a arg value of 0x01 than wired access requested,
229 **              status of the request would be updated to p_data.
230 **              If called with a arg value of 0x00 than wired access will be
231 **              released, status of the request would be updated to p_data.
232 **              If called with a arg value of 0x02 than current p61 state would
233 *be
234 **              updated to p_data.
235 **
236 ** Returns:     -1 or 0.
237 **
238 *******************************************************************************/
HalIoctl(long arg,void * p_data)239 int EseAdaptation::HalIoctl(long arg, void* p_data) {
240   const char* func = "EseAdaptation::HalIoctl";
241   hidl_vec<uint8_t> data;
242   NfcHalAutoThreadMutex a(sIoctlLock);
243   ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
244   ALOGD_IF(nfc_debug_enabled, "%s arg=%ld", func, arg);
245 
246   EseAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
247   data.setToExternal((uint8_t*)pInpOutData, sizeof(ese_nxp_IoctlInOutData_t));
248   if (mHalNxpEse != nullptr) mHalNxpEse->ioctl(arg, data, IoctlCallback);
249   ALOGD_IF(nfc_debug_enabled, "%s Ioctl Completed for Type=%lu", func,
250            (unsigned long)pInpOutData->out.ioctlType);
251   return (pInpOutData->out.result);
252 }
253