blob: 8761d774ff26a717ed41a0bb9495b1418f00ce31 [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*
Suraj Uday Kotharkare12d10f2019-04-17 15:44:08 +053015* Copyright 2018-2019 NXP
nxf24591dc0bc2c2018-02-21 17:33:08 +053016*
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"
Suraj Uday Kotharkare12d10f2019-04-17 15:44:08 +053031#include "NativeJniExtns.h"
nxf24591dc0bc2c2018-02-21 17:33:08 +053032using 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
Suraj Uday Kotharkare12d10f2019-04-17 15:44:08 +053061 NativeJniExtns::getInstance().notifyNfcEvent(__func__);
nxf24591dc0bc2c2018-02-21 17:33:08 +053062 /* Tell the controller to power up to get ready for sec elem operations */
63 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
64 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED);
nxpandroid0f06fde2017-08-14 11:25:28 +053065
nxf24591dc0bc2c2018-02-21 17:33:08 +053066 /* If controller is not routing AND there is no pipe connected,
67 then turn on the sec elem */
68 stat = se.activate(SecureElement::ESE_ID); // It is to get the current activated handle.
nxpandroid0f06fde2017-08-14 11:25:28 +053069
nxf24591dc0bc2c2018-02-21 17:33:08 +053070 if((stat) && (nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD))
nxpandroid0f06fde2017-08-14 11:25:28 +053071 {
nxf24591dc0bc2c2018-02-21 17:33:08 +053072 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON|se.COMM_LINK_ACTIVE);
nxpandroid7d44e572016-08-01 19:11:04 +053073 }
nxpandroid0f06fde2017-08-14 11:25:28 +053074 if(status != NFA_STATUS_OK)
75 {
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053076 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
77 stat =false;
nxpandroid0f06fde2017-08-14 11:25:28 +053078 }
79 else
80 {
nxpandroid82f7e9e2018-04-05 14:54:41 +053081 stat = se.SecEle_Modeset(se.NFCEE_ENABLE);
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053082 if(se.mModeSetNtfstatus != NFA_STATUS_OK)
83 {
84 stat = false;
85 LOG(INFO) << StringPrintf("%s: Mode set ntf STATUS_FAILED", __func__);
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053086
hariprasad nalacheruvu7254b032018-11-13 15:43:47 +053087 SyncEventGuard guard (se.mEERecoveryComplete);
88 {
89 se.mEERecoveryComplete.wait();
90 LOG(INFO) << StringPrintf("%s: Recovery complete", __func__);
91 }
92 if(se.mErrorRecovery)
93 {
94 stat = true;
95 }
96 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +053097 if(stat == true)
98 {
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053099 se.mIsWiredModeOpen = true;
Suraj Uday Kotharkar9e250fb2018-06-08 21:06:52 +0530100 stat = se.apduGateReset(se.mActiveEeHandle, recvBuffer, &recvBufferActualSize);
101 if (stat)
102 {
103 secElemHandle = se.mActiveEeHandle;
104 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530105 }
nxpandroid0f06fde2017-08-14 11:25:28 +0530106 }
nxpandroid0f06fde2017-08-14 11:25:28 +0530107
nxf24591dc0bc2c2018-02-21 17:33:08 +0530108 /* if code fails to connect to the secure element, and nothing is active, then
109 * tell the controller to power down
110 */
111 if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)))
112 {
113 LOG(INFO) << StringPrintf("%s: stat fails; ", __func__);
114 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
115 se.deactivate(SecureElement::ESE_ID);
116 se.mIsWiredModeOpen = false;
117 stat = false;
118 }
119 LOG(INFO) << StringPrintf("%s: exit; return handle=0x%X", __func__, secElemHandle);
120 return secElemHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +0530121}
122
123
124/*******************************************************************************
125**
126** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection
127**
128** Description: Disconnect from the secure element.
129** e: JVM environment.
130** o: Java object.
131** handle: Handle of secure element.
132**
133** Returns: True if ok.
134**
135*******************************************************************************/
136static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle)
137{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530138 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid64fd68c2015-09-23 16:45:15 +0530139 bool stat = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530140 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid34627bd2016-05-27 15:52:30 +0530141 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530142
nxf24591dc0bc2c2018-02-21 17:33:08 +0530143 if(!se.mIsWiredModeOpen)
144 return false;
Sreenivas88ee6aa2018-05-14 13:17:57 +0530145 /* release any pending transceive wait */
146 se.releasePendingTransceive();
nxpandroid7d44e572016-08-01 19:11:04 +0530147
nxf24591dc0bc2c2018-02-21 17:33:08 +0530148 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON);
149 if(status != NFA_STATUS_OK)
150 {
151 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530152 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530153 else
154 {
Sreenivasf83b8762018-04-09 16:09:49 +0530155 status = se.sendEvent(SecureElement::EVT_END_OF_APDU_TRANSFER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530156 if(status == NFA_STATUS_OK)
Sreenivasf83b8762018-04-09 16:09:49 +0530157 stat = true;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530158 }
Sreenivas88ee6aa2018-05-14 13:17:57 +0530159 se.mIsWiredModeOpen = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530160
nxpandroid5d64ce92016-11-18 19:48:53 +0530161 /* if nothing is active after this, then tell the controller to power down */
nxpandroid64fd68c2015-09-23 16:45:15 +0530162 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))
163 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530164 LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid64fd68c2015-09-23 16:45:15 +0530165 return stat ? JNI_TRUE : JNI_FALSE;
166}
167/*******************************************************************************
168**
Suraj Uday Kotharkarce445d82019-04-19 10:30:46 +0530169** Function: nativeNfcSecureElement_doResetForEseCosUpdate
nxpandroid64fd68c2015-09-23 16:45:15 +0530170**
171** Description: Reset the secure element.
172** e: JVM environment.
173** o: Java object.
174** handle: Handle of secure element.
175**
176** Returns: True if ok.
177**
178*******************************************************************************/
Suraj Uday Kotharkarce445d82019-04-19 10:30:46 +0530179static jboolean nativeNfcSecureElement_doResetForEseCosUpdate(JNIEnv*, jobject,
180 jint handle) {
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530181 bool stat = false;
182 int ret = -1;
183 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
184 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs ();
185 nfc_nci_IoctlInOutData_t inpOutData;
186 inpOutData.inp.level = NCI_ESE_HARD_RESET_IOCTL;
187 LOG(INFO) << StringPrintf("%s: Entry", __func__);
188 if(NULL == halFuncEntries) {
189 LOG(INFO) << StringPrintf("%s: halFuncEntries is NULL", __func__);
190 } else {
191 ret = halFuncEntries->ioctl(HAL_NFC_IOCTL_ESE_HARD_RESET, (void*)&inpOutData);
192 if(ret < 0) {
193 LOG(INFO) << StringPrintf("%s: IOCTL failed", __func__);
194 } else {
195 stat = true;
nxpandroid7d44e572016-08-01 19:11:04 +0530196 }
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530197 }
198 LOG(INFO) << StringPrintf("%s: exit", __func__);
199 return stat;
nxpandroid64fd68c2015-09-23 16:45:15 +0530200}
201
202/*******************************************************************************
203**
204** Function: nativeNfcSecureElement_doGetAtr
205**
206** Description: GetAtr from the connected eSE.
207** e: JVM environment.
208** o: Java object.
209** handle: Handle of secure element.
210**
211** Returns: Buffer of received data.
212**
213*******************************************************************************/
214static jbyteArray nativeNfcSecureElement_doGetAtr (JNIEnv* e, jobject, jint handle)
215{
216 bool stat = false;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530217 const int32_t recvBufferMaxSize = 1024;
218 uint8_t recvBuffer [recvBufferMaxSize];
219 int32_t recvBufferActualSize = 0;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530220 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
221 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530222
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530223 stat = se.getAtr(recvBuffer, &recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530224
nxf24591dc0bc2c2018-02-21 17:33:08 +0530225 //copy results back to java
nxpandroid64fd68c2015-09-23 16:45:15 +0530226 jbyteArray result = e->NewByteArray(recvBufferActualSize);
227 if (result != NULL) {
228 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
229 }
230
nxf24591dc0bc2c2018-02-21 17:33:08 +0530231 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530232
233 return result;
234}
235
236/*******************************************************************************
237**
238** Function: nativeNfcSecureElement_doTransceive
239**
240** Description: Send data to the secure element; retrieve response.
241** e: JVM environment.
242** o: Java object.
243** handle: Secure element's handle.
244** data: Data to send.
245**
246** Returns: Buffer of received data.
247**
248*******************************************************************************/
249static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data)
250{
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530251 const int32_t recvBufferMaxSize = 0x8800;//1024; 34k
252 uint8_t recvBuffer [recvBufferMaxSize];
253 int32_t recvBufferActualSize = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530254 ScopedByteArrayRW bytes(e, data);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530255 LOG(INFO) << StringPrintf("%s: enter; handle=0x%X; buf len=%zu", __func__, handle, bytes.size());
256
257 SecureElement &se = SecureElement::getInstance();
258 if(!se.mIsWiredModeOpen)
259 return NULL;
260
Sreenivas426138e2018-04-04 14:56:08 +0530261 se.transceive(reinterpret_cast<uint8_t*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, se.SmbTransceiveTimeOutVal);
nxpandroid64fd68c2015-09-23 16:45:15 +0530262
nxpandroida9a68ba2016-01-14 21:12:17 +0530263 //copy results back to java
264 jbyteArray result = e->NewByteArray(recvBufferActualSize);
265 if (result != NULL)
nxpandroid7d44e572016-08-01 19:11:04 +0530266 {
nxpandroida9a68ba2016-01-14 21:12:17 +0530267 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
nxpandroid7d44e572016-08-01 19:11:04 +0530268 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530269
270 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroida9a68ba2016-01-14 21:12:17 +0530271 return result;
nxpandroid64fd68c2015-09-23 16:45:15 +0530272}
273
274/*****************************************************************************
275**
276** Description: JNI functions
277**
278*****************************************************************************/
Suraj Uday Kotharkarce445d82019-04-19 10:30:46 +0530279static JNINativeMethod gMethods[] = {
280 {"doNativeOpenSecureElementConnection", "()I",
281 (void*)nativeNfcSecureElement_doOpenSecureElementConnection},
282 {"doNativeDisconnectSecureElementConnection", "(I)Z",
283 (void*)nativeNfcSecureElement_doDisconnectSecureElementConnection},
284 {"doResetForEseCosUpdate", "(I)Z",
285 (void*)nativeNfcSecureElement_doResetForEseCosUpdate},
286 {"doTransceive", "(I[B)[B", (void*)nativeNfcSecureElement_doTransceive},
287 {"doNativeGetAtr", "(I)[B", (void*)nativeNfcSecureElement_doGetAtr},
nxpandroid64fd68c2015-09-23 16:45:15 +0530288};
289
290
291/*******************************************************************************
292**
293** Function: register_com_android_nfc_NativeNfcSecureElement
294**
295** Description: Regisgter JNI functions with Java Virtual Machine.
296** e: Environment of JVM.
297**
298** Returns: Status of registration.
299**
300*******************************************************************************/
301int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
302{
303 return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName,
304 gMethods, NELEM(gMethods));
305}
306
nxpandroid64fd68c2015-09-23 16:45:15 +0530307} // namespace android