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