1 /******************************************************************************
2 *
3 * Copyright 2018 NXP
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #define LOG_TAG "SpiAddaptation"
20 #include "NfcAdaptation.h"
21 #include <android/hardware/nfc/1.0/types.h>
22 #include <hwbinder/ProcessState.h>
23 #include <log/log.h>
24 #include <pthread.h>
25
26 using android::sp;
27 using android::hardware::Return;
28 using android::hardware::Void;
29 using android::hardware::hidl_vec;
30 using vendor::nxp::nxpnfc::V1_0::INxpNfc;
31
32 sp<INxpNfc> NfcAdaptation::mHalNxpNfc = nullptr;
33 ThreadMutex NfcAdaptation::sIoctlLock;
34 NfcAdaptation* NfcAdaptation::mpInstance = NULL;
35 ThreadMutex NfcAdaptation::sLock;
36
37 int omapi_status;
38 extern bool ese_debug_enabled;
Initialize()39 void NfcAdaptation::Initialize() {
40 const char* func = "NfcAdaptation::Initialize";
41 ALOGD_IF(ese_debug_enabled, "%s", func);
42 if (mHalNxpNfc != nullptr) return;
43 mHalNxpNfc = INxpNfc::tryGetService();
44 LOG_FATAL_IF(mHalNxpNfc == nullptr, "Failed to retrieve the NXP NFC HAL!");
45 if (mHalNxpNfc != nullptr) {
46 ALOGD_IF(ese_debug_enabled, "%s: INxpNfc::getService() returned %p (%s)",
47 func, mHalNxpNfc.get(),
48 (mHalNxpNfc->isRemote() ? "remote" : "local"));
49 }
50 ALOGD_IF(ese_debug_enabled, "%s: exit", func);
51 }
52 /*******************************************************************************
53 **
54 ** Function: NfcAdaptation::GetInstance()
55 **
56 ** Description: access class singleton
57 **
58 ** Returns: pointer to the singleton object
59 **
60 *******************************************************************************/
GetInstance()61 NfcAdaptation& NfcAdaptation::GetInstance() {
62 AutoThreadMutex a(sLock);
63
64 if (!mpInstance) mpInstance = new NfcAdaptation;
65 return *mpInstance;
66 }
67 /*******************************************************************************
68 **
69 ** Function: ThreadMutex::ThreadMutex()
70 **
71 ** Description: class constructor
72 **
73 ** Returns: none
74 **
75 *******************************************************************************/
ThreadMutex()76 ThreadMutex::ThreadMutex() {
77 pthread_mutexattr_t mutexAttr;
78
79 pthread_mutexattr_init(&mutexAttr);
80 pthread_mutex_init(&mMutex, &mutexAttr);
81 pthread_mutexattr_destroy(&mutexAttr);
82 }
83 /*******************************************************************************
84 **
85 ** Function: ThreadMutex::~ThreadMutex()
86 **
87 ** Description: class destructor
88 **
89 ** Returns: none
90 **
91 *******************************************************************************/
~ThreadMutex()92 ThreadMutex::~ThreadMutex() { pthread_mutex_destroy(&mMutex); }
93
94 /*******************************************************************************
95 **
96 ** Function: AutoThreadMutex::AutoThreadMutex()
97 **
98 ** Description: class constructor, automatically lock the mutex
99 **
100 ** Returns: none
101 **
102 *******************************************************************************/
AutoThreadMutex(ThreadMutex & m)103 AutoThreadMutex::AutoThreadMutex(ThreadMutex& m) : mm(m) { mm.lock(); }
104
105 /*******************************************************************************
106 **
107 ** Function: AutoThreadMutex::~AutoThreadMutex()
108 **
109 ** Description: class destructor, automatically unlock the mutex
110 **
111 ** Returns: none
112 **
113 *******************************************************************************/
~AutoThreadMutex()114 AutoThreadMutex::~AutoThreadMutex() { mm.unlock(); }
115
116 /*******************************************************************************
117 **
118 ** Function: ThreadMutex::lock()
119 **
120 ** Description: lock kthe mutex
121 **
122 ** Returns: none
123 **
124 *******************************************************************************/
lock()125 void ThreadMutex::lock() { pthread_mutex_lock(&mMutex); }
126
127 /*******************************************************************************
128 **
129 ** Function: ThreadMutex::unblock()
130 **
131 ** Description: unlock the mutex
132 **
133 ** Returns: none
134 **
135 *******************************************************************************/
unlock()136 void ThreadMutex::unlock() { pthread_mutex_unlock(&mMutex); }
137
138 /*******************************************************************************
139 **
140 ** Function: NfcAdaptation::NfcAdaptation()
141 **
142 ** Description: class constructor
143 **
144 ** Returns: none
145 **
146 *******************************************************************************/
NfcAdaptation()147 NfcAdaptation::NfcAdaptation() { mCurrentIoctlData = NULL; }
148
149 /*******************************************************************************
150 **
151 ** Function: NfcAdaptation::~NfcAdaptation()
152 **
153 ** Description: class destructor
154 **
155 ** Returns: none
156 **
157 *******************************************************************************/
~NfcAdaptation()158 NfcAdaptation::~NfcAdaptation() { mpInstance = NULL; }
159
160 /*******************************************************************************
161 **
162 ** Function: IoctlCallback
163 **
164 ** Description: Callback from HAL stub for IOCTL api invoked.
165 ** Output data for IOCTL is sent as argument
166 **
167 ** Returns: None.
168 **
169 *******************************************************************************/
IoctlCallback(::android::hardware::nfc::V1_0::NfcData outputData)170 void IoctlCallback(::android::hardware::nfc::V1_0::NfcData outputData) {
171 const char* func = "IoctlCallback";
172 ese_nxp_ExtnOutputData_t* pOutData =
173 (ese_nxp_ExtnOutputData_t*)&outputData[0];
174 ALOGD_IF(ese_debug_enabled, "%s Ioctl Type=%lu", func,
175 (unsigned long)pOutData->ioctlType);
176 NfcAdaptation* pAdaptation = (NfcAdaptation*)pOutData->context;
177 /*Output Data from stub->Proxy is copied back to output data
178 * This data will be sent back to libnfc*/
179 memcpy(&pAdaptation->mCurrentIoctlData->out, &outputData[0],
180 sizeof(ese_nxp_ExtnOutputData_t));
181 ALOGD_IF(ese_debug_enabled, "%s Ioctl Type value[0]:0x%x and value[3] 0x%x",
182 func, pOutData->data.nxpRsp.p_rsp[0],
183 pOutData->data.nxpRsp.p_rsp[3]);
184 omapi_status = pOutData->data.nxpRsp.p_rsp[3];
185 }
186
187 /*******************************************************************************
188 **
189 ** Function: NfcAdaptation::HalIoctl
190 **
191 ** Description: Calls ioctl to the Nfc driver.
192 ** If called with a arg value of 0x01 than wired access requested,
193 ** status of the requst would be updated to p_data.
194 ** If called with a arg value of 0x00 than wired access will be
195 ** released, status of the requst would be updated to p_data.
196 ** If called with a arg value of 0x02 than current p61 state would
197 *be
198 ** updated to p_data.
199 **
200 ** Returns: -1 or 0.
201 **
202 *******************************************************************************/
HalIoctl(long arg,void * p_data)203 ESESTATUS NfcAdaptation::HalIoctl(long arg, void* p_data) {
204 const char* func = "NfcAdaptation::HalIoctl";
205 ::android::hardware::nfc::V1_0::NfcData data;
206 ESESTATUS result = ESESTATUS_FAILED;
207 AutoThreadMutex a(sIoctlLock);
208 ese_nxp_IoctlInOutData_t* pInpOutData = (ese_nxp_IoctlInOutData_t*)p_data;
209 ALOGD_IF(ese_debug_enabled, "%s arg=%ld", func, arg);
210 pInpOutData->inp.context = &NfcAdaptation::GetInstance();
211 NfcAdaptation::GetInstance().mCurrentIoctlData = pInpOutData;
212 data.setToExternal((uint8_t*)pInpOutData, sizeof(ese_nxp_IoctlInOutData_t));
213 if (mHalNxpNfc != nullptr) {
214 mHalNxpNfc->ioctl(arg, data, IoctlCallback);
215 }
216 ALOGD_IF(ese_debug_enabled, "%s Ioctl Completed for Type=%lu", func,
217 (unsigned long)pInpOutData->out.ioctlType);
218 result = (ESESTATUS)(pInpOutData->out.result);
219 return result;
220 }
221
222 /*******************************************************************************
223 **
224 ** Function: ThreadCondVar::ThreadCondVar()
225 **
226 ** Description: class constructor
227 **
228 ** Returns: none
229 **
230 *******************************************************************************/
ThreadCondVar()231 ThreadCondVar::ThreadCondVar() {
232 pthread_condattr_t CondAttr;
233
234 pthread_condattr_init(&CondAttr);
235 pthread_cond_init(&mCondVar, &CondAttr);
236
237 pthread_condattr_destroy(&CondAttr);
238 }
239
240 /*******************************************************************************
241 **
242 ** Function: ThreadCondVar::~ThreadCondVar()
243 **
244 ** Description: class destructor
245 **
246 ** Returns: none
247 **
248 *******************************************************************************/
~ThreadCondVar()249 ThreadCondVar::~ThreadCondVar() { pthread_cond_destroy(&mCondVar); }
250