blob: ca2b74bdf971366d2c6276ada1e4b7f984883b72 [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301/******************************************************************************
nxf24591dc0bc2c2018-02-21 17:33:08 +05302*
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*
15* Copyright 2018 NXP
16*
17******************************************************************************/
nxpandroid64fd68c2015-09-23 16:45:15 +053018
nxf24591dc0bc2c2018-02-21 17:33:08 +053019#include <android-base/stringprintf.h>
20#include <base/logging.h>
21#include "PowerSwitch.h"
22#include "RoutingManager.h"
23#include <nativehelper/ScopedPrimitiveArray.h>
24#include <nativehelper/ScopedUtfChars.h>
25#include <nativehelper/ScopedLocalRef.h>
26#include "JavaClassConstants.h"
27#include "NfcJniUtil.h"
28#include "config.h"
nxf24591dc0bc2c2018-02-21 17:33:08 +053029#include "SecureElement.h"
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +053030#include "NfcAdaptation.h"
nxf24591dc0bc2c2018-02-21 17:33:08 +053031
32using android::base::StringPrintf;
33
nxpandroid64fd68c2015-09-23 16:45:15 +053034namespace android
35{
nxpandroid64fd68c2015-09-23 16:45:15 +053036static const int EE_ERROR_INIT = -3;
nxpandroid64fd68c2015-09-23 16:45:15 +053037/*******************************************************************************
38**
39** Function: nativeNfcSecureElement_doOpenSecureElementConnection
40**
41** Description: Connect to the secure element.
42** e: JVM environment.
43** o: Java object.
44**
45** Returns: Handle of secure element. values < 0 represent failure.
46**
47*******************************************************************************/
48static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject)
49{
nxf24591dc0bc2c2018-02-21 17:33:08 +053050 LOG(INFO) << StringPrintf("%s: Enter; ", __func__);
nxpandroid64fd68c2015-09-23 16:45:15 +053051 bool stat = false;
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +053052 const int32_t recvBufferMaxSize = 1024;
53 uint8_t recvBuffer [recvBufferMaxSize];
54 int32_t recvBufferActualSize = 0;
55
nxpandroid64fd68c2015-09-23 16:45:15 +053056 jint secElemHandle = EE_ERROR_INIT;
nxpandroid64fd68c2015-09-23 16:45:15 +053057 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid64fd68c2015-09-23 16:45:15 +053058 SecureElement &se = SecureElement::getInstance();
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053059 se.mModeSetNtfstatus = NFA_STATUS_FAILED;
nxpandroid7d44e572016-08-01 19:11:04 +053060
nxf24591dc0bc2c2018-02-21 17:33:08 +053061 /* Tell the controller to power up to get ready for sec elem operations */
62 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
63 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED);
nxpandroid0f06fde2017-08-14 11:25:28 +053064
nxf24591dc0bc2c2018-02-21 17:33:08 +053065 /* If controller is not routing AND there is no pipe connected,
66 then turn on the sec elem */
67 stat = se.activate(SecureElement::ESE_ID); // It is to get the current activated handle.
nxpandroid0f06fde2017-08-14 11:25:28 +053068
nxf24591dc0bc2c2018-02-21 17:33:08 +053069 if((stat) && (nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD))
nxpandroid0f06fde2017-08-14 11:25:28 +053070 {
nxf24591dc0bc2c2018-02-21 17:33:08 +053071 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON|se.COMM_LINK_ACTIVE);
nxpandroid7d44e572016-08-01 19:11:04 +053072 }
nxpandroid0f06fde2017-08-14 11:25:28 +053073 if(status != NFA_STATUS_OK)
74 {
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053075 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
76 stat =false;
nxpandroid0f06fde2017-08-14 11:25:28 +053077 }
78 else
79 {
nxpandroid82f7e9e2018-04-05 14:54:41 +053080 stat = se.SecEle_Modeset(se.NFCEE_ENABLE);
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053081 if(se.mModeSetNtfstatus != NFA_STATUS_OK)
82 {
83 stat = false;
84 LOG(INFO) << StringPrintf("%s: Mode set ntf STATUS_FAILED", __func__);
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053085
hariprasad nalacheruvu7254b032018-11-13 15:43:47 +053086 SyncEventGuard guard (se.mEERecoveryComplete);
87 {
88 se.mEERecoveryComplete.wait();
89 LOG(INFO) << StringPrintf("%s: Recovery complete", __func__);
90 }
91 if(se.mErrorRecovery)
92 {
93 stat = true;
94 }
95 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +053096 if(stat == true)
97 {
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053098 se.mIsWiredModeOpen = true;
Suraj Uday Kotharkar9e250fb2018-06-08 21:06:52 +053099 stat = se.apduGateReset(se.mActiveEeHandle, recvBuffer, &recvBufferActualSize);
100 if (stat)
101 {
102 secElemHandle = se.mActiveEeHandle;
103 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530104 }
nxpandroid0f06fde2017-08-14 11:25:28 +0530105 }
nxpandroid0f06fde2017-08-14 11:25:28 +0530106
nxf24591dc0bc2c2018-02-21 17:33:08 +0530107 /* if code fails to connect to the secure element, and nothing is active, then
108 * tell the controller to power down
109 */
110 if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)))
111 {
112 LOG(INFO) << StringPrintf("%s: stat fails; ", __func__);
113 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
114 se.deactivate(SecureElement::ESE_ID);
115 se.mIsWiredModeOpen = false;
116 stat = false;
117 }
118 LOG(INFO) << StringPrintf("%s: exit; return handle=0x%X", __func__, secElemHandle);
119 return secElemHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +0530120}
121
122
123/*******************************************************************************
124**
125** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection
126**
127** Description: Disconnect from the secure element.
128** e: JVM environment.
129** o: Java object.
130** handle: Handle of secure element.
131**
132** Returns: True if ok.
133**
134*******************************************************************************/
135static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle)
136{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530137 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid64fd68c2015-09-23 16:45:15 +0530138 bool stat = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530139 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid34627bd2016-05-27 15:52:30 +0530140 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530141
nxf24591dc0bc2c2018-02-21 17:33:08 +0530142 if(!se.mIsWiredModeOpen)
143 return false;
Sreenivas88ee6aa2018-05-14 13:17:57 +0530144 /* release any pending transceive wait */
145 se.releasePendingTransceive();
nxpandroid7d44e572016-08-01 19:11:04 +0530146
nxf24591dc0bc2c2018-02-21 17:33:08 +0530147 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON);
148 if(status != NFA_STATUS_OK)
149 {
150 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530151 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530152 else
153 {
Sreenivasf83b8762018-04-09 16:09:49 +0530154 status = se.sendEvent(SecureElement::EVT_END_OF_APDU_TRANSFER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530155 if(status == NFA_STATUS_OK)
Sreenivasf83b8762018-04-09 16:09:49 +0530156 stat = true;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530157 }
Sreenivas88ee6aa2018-05-14 13:17:57 +0530158 se.mIsWiredModeOpen = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530159
nxpandroid5d64ce92016-11-18 19:48:53 +0530160 /* if nothing is active after this, then tell the controller to power down */
nxpandroid64fd68c2015-09-23 16:45:15 +0530161 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))
162 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530163 LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid64fd68c2015-09-23 16:45:15 +0530164 return stat ? JNI_TRUE : JNI_FALSE;
165}
166/*******************************************************************************
167**
168** Function: nativeNfcSecureElement_doResetSecureElement
169**
170** Description: Reset the secure element.
171** e: JVM environment.
172** o: Java object.
173** handle: Handle of secure element.
174**
175** Returns: True if ok.
176**
177*******************************************************************************/
178static jboolean nativeNfcSecureElement_doResetSecureElement (JNIEnv*, jobject, jint handle)
179{
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530180 bool stat = false;
181 int ret = -1;
182 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
183 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs ();
184 nfc_nci_IoctlInOutData_t inpOutData;
185 inpOutData.inp.level = NCI_ESE_HARD_RESET_IOCTL;
186 LOG(INFO) << StringPrintf("%s: Entry", __func__);
187 if(NULL == halFuncEntries) {
188 LOG(INFO) << StringPrintf("%s: halFuncEntries is NULL", __func__);
189 } else {
190 ret = halFuncEntries->ioctl(HAL_NFC_IOCTL_ESE_HARD_RESET, (void*)&inpOutData);
191 if(ret < 0) {
192 LOG(INFO) << StringPrintf("%s: IOCTL failed", __func__);
193 } else {
194 stat = true;
nxpandroid7d44e572016-08-01 19:11:04 +0530195 }
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530196 }
197 LOG(INFO) << StringPrintf("%s: exit", __func__);
198 return stat;
nxpandroid64fd68c2015-09-23 16:45:15 +0530199}
200
201/*******************************************************************************
202**
203** Function: nativeNfcSecureElement_doGetAtr
204**
205** Description: GetAtr from the connected eSE.
206** e: JVM environment.
207** o: Java object.
208** handle: Handle of secure element.
209**
210** Returns: Buffer of received data.
211**
212*******************************************************************************/
213static jbyteArray nativeNfcSecureElement_doGetAtr (JNIEnv* e, jobject, jint handle)
214{
215 bool stat = false;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530216 const int32_t recvBufferMaxSize = 1024;
217 uint8_t recvBuffer [recvBufferMaxSize];
218 int32_t recvBufferActualSize = 0;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530219 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
220 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530221
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530222 stat = se.getAtr(recvBuffer, &recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530223
nxf24591dc0bc2c2018-02-21 17:33:08 +0530224 //copy results back to java
nxpandroid64fd68c2015-09-23 16:45:15 +0530225 jbyteArray result = e->NewByteArray(recvBufferActualSize);
226 if (result != NULL) {
227 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
228 }
229
nxf24591dc0bc2c2018-02-21 17:33:08 +0530230 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530231
232 return result;
233}
234
235/*******************************************************************************
236**
237** Function: nativeNfcSecureElement_doTransceive
238**
239** Description: Send data to the secure element; retrieve response.
240** e: JVM environment.
241** o: Java object.
242** handle: Secure element's handle.
243** data: Data to send.
244**
245** Returns: Buffer of received data.
246**
247*******************************************************************************/
248static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data)
249{
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530250 const int32_t recvBufferMaxSize = 0x8800;//1024; 34k
251 uint8_t recvBuffer [recvBufferMaxSize];
252 int32_t recvBufferActualSize = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530253 ScopedByteArrayRW bytes(e, data);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530254 LOG(INFO) << StringPrintf("%s: enter; handle=0x%X; buf len=%zu", __func__, handle, bytes.size());
255
256 SecureElement &se = SecureElement::getInstance();
257 if(!se.mIsWiredModeOpen)
258 return NULL;
259
Sreenivas426138e2018-04-04 14:56:08 +0530260 se.transceive(reinterpret_cast<uint8_t*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, se.SmbTransceiveTimeOutVal);
nxpandroid64fd68c2015-09-23 16:45:15 +0530261
nxpandroida9a68ba2016-01-14 21:12:17 +0530262 //copy results back to java
263 jbyteArray result = e->NewByteArray(recvBufferActualSize);
264 if (result != NULL)
nxpandroid7d44e572016-08-01 19:11:04 +0530265 {
nxpandroida9a68ba2016-01-14 21:12:17 +0530266 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
nxpandroid7d44e572016-08-01 19:11:04 +0530267 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530268
269 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroida9a68ba2016-01-14 21:12:17 +0530270 return result;
nxpandroid64fd68c2015-09-23 16:45:15 +0530271}
272
273/*****************************************************************************
274**
275** Description: JNI functions
276**
277*****************************************************************************/
278static JNINativeMethod gMethods[] =
279{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530280 {"doNativeOpenSecureElementConnection", "()I", (void *) nativeNfcSecureElement_doOpenSecureElementConnection},
nxpandroid64fd68c2015-09-23 16:45:15 +0530281 {"doNativeDisconnectSecureElementConnection", "(I)Z", (void *) nativeNfcSecureElement_doDisconnectSecureElementConnection},
282 {"doNativeResetSecureElement", "(I)Z", (void *) nativeNfcSecureElement_doResetSecureElement},
nxpandroid64fd68c2015-09-23 16:45:15 +0530283 {"doTransceive", "(I[B)[B", (void *) nativeNfcSecureElement_doTransceive},
284 {"doNativeGetAtr", "(I)[B", (void *) nativeNfcSecureElement_doGetAtr},
285};
286
287
288/*******************************************************************************
289**
290** Function: register_com_android_nfc_NativeNfcSecureElement
291**
292** Description: Regisgter JNI functions with Java Virtual Machine.
293** e: Environment of JVM.
294**
295** Returns: Status of registration.
296**
297*******************************************************************************/
298int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
299{
300 return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName,
301 gMethods, NELEM(gMethods));
302}
303
nxpandroid64fd68c2015-09-23 16:45:15 +0530304} // namespace android