blob: c399126d9ae0deaeae9bd418a12e7126473e218c [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"
29#include "phNxpConfig.h"
30#include "SecureElement.h"
31
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();
nxpandroid7d44e572016-08-01 19:11:04 +053059
nxf24591dc0bc2c2018-02-21 17:33:08 +053060 /* Tell the controller to power up to get ready for sec elem operations */
61 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
62 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED);
nxpandroid0f06fde2017-08-14 11:25:28 +053063
nxf24591dc0bc2c2018-02-21 17:33:08 +053064 /* If controller is not routing AND there is no pipe connected,
65 then turn on the sec elem */
66 stat = se.activate(SecureElement::ESE_ID); // It is to get the current activated handle.
nxpandroid0f06fde2017-08-14 11:25:28 +053067
nxf24591dc0bc2c2018-02-21 17:33:08 +053068 if((stat) && (nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD))
nxpandroid0f06fde2017-08-14 11:25:28 +053069 {
nxf24591dc0bc2c2018-02-21 17:33:08 +053070 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON|se.COMM_LINK_ACTIVE);
nxpandroid7d44e572016-08-01 19:11:04 +053071 }
nxpandroid0f06fde2017-08-14 11:25:28 +053072 if(status != NFA_STATUS_OK)
73 {
nxf24591dc0bc2c2018-02-21 17:33:08 +053074 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
75 stat =false;
nxpandroid0f06fde2017-08-14 11:25:28 +053076 }
77 else
78 {
nxpandroid82f7e9e2018-04-05 14:54:41 +053079 stat = se.SecEle_Modeset(se.NFCEE_ENABLE);
nxf24591dc0bc2c2018-02-21 17:33:08 +053080 se.mIsWiredModeOpen = true;
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +053081 if(stat == true)
82 {
Suraj Uday Kotharkar9e250fb2018-06-08 21:06:52 +053083 stat = se.apduGateReset(se.mActiveEeHandle, recvBuffer, &recvBufferActualSize);
84 if (stat)
85 {
86 secElemHandle = se.mActiveEeHandle;
87 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +053088 }
nxpandroid0f06fde2017-08-14 11:25:28 +053089 }
nxpandroid0f06fde2017-08-14 11:25:28 +053090
nxf24591dc0bc2c2018-02-21 17:33:08 +053091 /* if code fails to connect to the secure element, and nothing is active, then
92 * tell the controller to power down
93 */
94 if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)))
95 {
96 LOG(INFO) << StringPrintf("%s: stat fails; ", __func__);
97 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
98 se.deactivate(SecureElement::ESE_ID);
99 se.mIsWiredModeOpen = false;
100 stat = false;
101 }
102 LOG(INFO) << StringPrintf("%s: exit; return handle=0x%X", __func__, secElemHandle);
103 return secElemHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +0530104}
105
106
107/*******************************************************************************
108**
109** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection
110**
111** Description: Disconnect from the secure element.
112** e: JVM environment.
113** o: Java object.
114** handle: Handle of secure element.
115**
116** Returns: True if ok.
117**
118*******************************************************************************/
119static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle)
120{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530121 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid64fd68c2015-09-23 16:45:15 +0530122 bool stat = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530123 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid34627bd2016-05-27 15:52:30 +0530124 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530125
nxf24591dc0bc2c2018-02-21 17:33:08 +0530126 if(!se.mIsWiredModeOpen)
127 return false;
Sreenivas88ee6aa2018-05-14 13:17:57 +0530128 /* release any pending transceive wait */
129 se.releasePendingTransceive();
nxpandroid7d44e572016-08-01 19:11:04 +0530130
nxf24591dc0bc2c2018-02-21 17:33:08 +0530131 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON);
132 if(status != NFA_STATUS_OK)
133 {
134 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530135 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530136 else
137 {
Sreenivasf83b8762018-04-09 16:09:49 +0530138 status = se.sendEvent(SecureElement::EVT_END_OF_APDU_TRANSFER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530139 if(status == NFA_STATUS_OK)
Sreenivasf83b8762018-04-09 16:09:49 +0530140 stat = true;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530141 }
Sreenivas88ee6aa2018-05-14 13:17:57 +0530142 se.mIsWiredModeOpen = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530143
nxpandroid5d64ce92016-11-18 19:48:53 +0530144 /* if nothing is active after this, then tell the controller to power down */
nxpandroid64fd68c2015-09-23 16:45:15 +0530145 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))
146 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530147 LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid64fd68c2015-09-23 16:45:15 +0530148 return stat ? JNI_TRUE : JNI_FALSE;
149}
150/*******************************************************************************
151**
152** Function: nativeNfcSecureElement_doResetSecureElement
153**
154** Description: Reset the secure element.
155** e: JVM environment.
156** o: Java object.
157** handle: Handle of secure element.
158**
159** Returns: True if ok.
160**
161*******************************************************************************/
162static jboolean nativeNfcSecureElement_doResetSecureElement (JNIEnv*, jobject, jint handle)
163{
164 bool stat = false;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530165 NFCSTATUS status = NFCSTATUS_FAILED;
166 SecureElement &se = SecureElement::getInstance();
167 if(!se.mIsWiredModeOpen)
168 return false;
nxpandroidebf53fb2016-12-22 18:48:59 +0530169
nxf24591dc0bc2c2018-02-21 17:33:08 +0530170 if( nfcFL.nfcNxpEse) {
171 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid0f06fde2017-08-14 11:25:28 +0530172 if(!se.mIsWiredModeOpen)
173 {
nxf24591dc0bc2c2018-02-21 17:33:08 +0530174 LOG(ERROR) << StringPrintf("wired mode is not open");
nxpandroid0f06fde2017-08-14 11:25:28 +0530175 return stat;
176 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530177 status = se.setNfccPwrConfig(se.NFCC_DECIDES);
178 if(status != NFA_STATUS_OK)
nxpandroid5d64ce92016-11-18 19:48:53 +0530179 {
nxf24591dc0bc2c2018-02-21 17:33:08 +0530180 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid7d44e572016-08-01 19:11:04 +0530181 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530182 else {
nxpandroid82f7e9e2018-04-05 14:54:41 +0530183 stat = se.SecEle_Modeset(se.NFCEE_DISABLE);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530184 usleep(2000 * 1000);
nxpandroid6c999f02017-02-24 15:45:35 +0530185 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530186 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON|se.COMM_LINK_ACTIVE);
187 if(status != NFA_STATUS_OK)
188 {
189 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
190 }
191 else {
nxpandroid82f7e9e2018-04-05 14:54:41 +0530192 stat = se.SecEle_Modeset(se.NFCEE_ENABLE);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530193 usleep(2000 * 1000);
194 }
nxpandroid7d44e572016-08-01 19:11:04 +0530195 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530196LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530197return stat ? JNI_TRUE : JNI_FALSE;
nxpandroid64fd68c2015-09-23 16:45:15 +0530198}
199
200/*******************************************************************************
201**
202** Function: nativeNfcSecureElement_doGetAtr
203**
204** Description: GetAtr from the connected eSE.
205** e: JVM environment.
206** o: Java object.
207** handle: Handle of secure element.
208**
209** Returns: Buffer of received data.
210**
211*******************************************************************************/
212static jbyteArray nativeNfcSecureElement_doGetAtr (JNIEnv* e, jobject, jint handle)
213{
214 bool stat = false;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530215 const int32_t recvBufferMaxSize = 1024;
216 uint8_t recvBuffer [recvBufferMaxSize];
217 int32_t recvBufferActualSize = 0;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530218 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
219 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530220
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530221 stat = se.getAtr(recvBuffer, &recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530222
nxf24591dc0bc2c2018-02-21 17:33:08 +0530223 //copy results back to java
nxpandroid64fd68c2015-09-23 16:45:15 +0530224 jbyteArray result = e->NewByteArray(recvBufferActualSize);
225 if (result != NULL) {
226 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
227 }
228
nxf24591dc0bc2c2018-02-21 17:33:08 +0530229 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530230
231 return result;
232}
233
234/*******************************************************************************
235**
236** Function: nativeNfcSecureElement_doTransceive
237**
238** Description: Send data to the secure element; retrieve response.
239** e: JVM environment.
240** o: Java object.
241** handle: Secure element's handle.
242** data: Data to send.
243**
244** Returns: Buffer of received data.
245**
246*******************************************************************************/
247static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data)
248{
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530249 const int32_t recvBufferMaxSize = 0x8800;//1024; 34k
250 uint8_t recvBuffer [recvBufferMaxSize];
251 int32_t recvBufferActualSize = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530252 ScopedByteArrayRW bytes(e, data);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530253 LOG(INFO) << StringPrintf("%s: enter; handle=0x%X; buf len=%zu", __func__, handle, bytes.size());
254
255 SecureElement &se = SecureElement::getInstance();
256 if(!se.mIsWiredModeOpen)
257 return NULL;
258
Sreenivas426138e2018-04-04 14:56:08 +0530259 se.transceive(reinterpret_cast<uint8_t*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, se.SmbTransceiveTimeOutVal);
nxpandroid64fd68c2015-09-23 16:45:15 +0530260
nxpandroida9a68ba2016-01-14 21:12:17 +0530261 //copy results back to java
262 jbyteArray result = e->NewByteArray(recvBufferActualSize);
263 if (result != NULL)
nxpandroid7d44e572016-08-01 19:11:04 +0530264 {
nxpandroida9a68ba2016-01-14 21:12:17 +0530265 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
nxpandroid7d44e572016-08-01 19:11:04 +0530266 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530267
268 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroida9a68ba2016-01-14 21:12:17 +0530269 return result;
nxpandroid64fd68c2015-09-23 16:45:15 +0530270}
271
272/*****************************************************************************
273**
274** Description: JNI functions
275**
276*****************************************************************************/
277static JNINativeMethod gMethods[] =
278{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530279 {"doNativeOpenSecureElementConnection", "()I", (void *) nativeNfcSecureElement_doOpenSecureElementConnection},
nxpandroid64fd68c2015-09-23 16:45:15 +0530280 {"doNativeDisconnectSecureElementConnection", "(I)Z", (void *) nativeNfcSecureElement_doDisconnectSecureElementConnection},
281 {"doNativeResetSecureElement", "(I)Z", (void *) nativeNfcSecureElement_doResetSecureElement},
nxpandroid64fd68c2015-09-23 16:45:15 +0530282 {"doTransceive", "(I[B)[B", (void *) nativeNfcSecureElement_doTransceive},
283 {"doNativeGetAtr", "(I)[B", (void *) nativeNfcSecureElement_doGetAtr},
284};
285
286
287/*******************************************************************************
288**
289** Function: register_com_android_nfc_NativeNfcSecureElement
290**
291** Description: Regisgter JNI functions with Java Virtual Machine.
292** e: Environment of JVM.
293**
294** Returns: Status of registration.
295**
296*******************************************************************************/
297int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
298{
299 return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName,
300 gMethods, NELEM(gMethods));
301}
302
nxpandroid64fd68c2015-09-23 16:45:15 +0530303} // namespace android