blob: 226638234198e2ca996c2c2913d5f14f671c054d [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;
52 jint secElemHandle = EE_ERROR_INIT;
nxpandroid64fd68c2015-09-23 16:45:15 +053053 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid64fd68c2015-09-23 16:45:15 +053054 SecureElement &se = SecureElement::getInstance();
nxpandroid7d44e572016-08-01 19:11:04 +053055
nxf24591dc0bc2c2018-02-21 17:33:08 +053056 /* Tell the controller to power up to get ready for sec elem operations */
57 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
58 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED);
nxpandroid0f06fde2017-08-14 11:25:28 +053059
nxf24591dc0bc2c2018-02-21 17:33:08 +053060 /* If controller is not routing AND there is no pipe connected,
61 then turn on the sec elem */
62 stat = se.activate(SecureElement::ESE_ID); // It is to get the current activated handle.
nxpandroid0f06fde2017-08-14 11:25:28 +053063
nxpandroid64fd68c2015-09-23 16:45:15 +053064 if (stat)
65 {
nxpandroid0f06fde2017-08-14 11:25:28 +053066 secElemHandle = se.mActiveEeHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +053067 }
nxpandroid6fd9cdb2017-07-12 18:25:41 +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 {
nxf24591dc0bc2c2018-02-21 17:33:08 +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);
nxf24591dc0bc2c2018-02-21 17:33:08 +053081 se.mIsWiredModeOpen = true;
nxpandroid0f06fde2017-08-14 11:25:28 +053082 }
nxpandroid0f06fde2017-08-14 11:25:28 +053083
nxf24591dc0bc2c2018-02-21 17:33:08 +053084 /* if code fails to connect to the secure element, and nothing is active, then
85 * tell the controller to power down
86 */
87 if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)))
88 {
89 LOG(INFO) << StringPrintf("%s: stat fails; ", __func__);
90 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
91 se.deactivate(SecureElement::ESE_ID);
92 se.mIsWiredModeOpen = false;
93 stat = false;
94 }
95 LOG(INFO) << StringPrintf("%s: exit; return handle=0x%X", __func__, secElemHandle);
96 return secElemHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +053097}
98
99
100/*******************************************************************************
101**
102** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection
103**
104** Description: Disconnect from the secure element.
105** e: JVM environment.
106** o: Java object.
107** handle: Handle of secure element.
108**
109** Returns: True if ok.
110**
111*******************************************************************************/
112static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle)
113{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530114 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid64fd68c2015-09-23 16:45:15 +0530115 bool stat = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530116 NFCSTATUS status = NFCSTATUS_FAILED;
hariprasad nalacheruvuc72531a2018-03-23 15:36:52 +0530117 const int32_t recvBufferMaxSize = 1024;
118 uint8_t recvBuffer [recvBufferMaxSize];
119 int32_t recvBufferActualSize = 0;
nxpandroid34627bd2016-05-27 15:52:30 +0530120 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530121
nxf24591dc0bc2c2018-02-21 17:33:08 +0530122 if(!se.mIsWiredModeOpen)
123 return false;
nxpandroid7d44e572016-08-01 19:11:04 +0530124
nxf24591dc0bc2c2018-02-21 17:33:08 +0530125 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON);
126 if(status != NFA_STATUS_OK)
127 {
128 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530129 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530130 else
131 {
hariprasad nalacheruvuc72531a2018-03-23 15:36:52 +0530132 /*status = se.sendEvent(SecureElement::EVT_END_OF_APDU_TRANSFER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530133 if(status == NFA_STATUS_OK)
hariprasad nalacheruvuc72531a2018-03-23 15:36:52 +0530134 stat = true;*/
135 stat = se.getAtr(handle, recvBuffer, &recvBufferActualSize);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530136 }
nxpandroid64fd68c2015-09-23 16:45:15 +0530137
nxpandroid5d64ce92016-11-18 19:48:53 +0530138 /* if nothing is active after this, then tell the controller to power down */
nxpandroid64fd68c2015-09-23 16:45:15 +0530139 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))
140 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530141 LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530142
nxpandroid64fd68c2015-09-23 16:45:15 +0530143 return stat ? JNI_TRUE : JNI_FALSE;
144}
145/*******************************************************************************
146**
147** Function: nativeNfcSecureElement_doResetSecureElement
148**
149** Description: Reset the secure element.
150** e: JVM environment.
151** o: Java object.
152** handle: Handle of secure element.
153**
154** Returns: True if ok.
155**
156*******************************************************************************/
157static jboolean nativeNfcSecureElement_doResetSecureElement (JNIEnv*, jobject, jint handle)
158{
159 bool stat = false;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530160 NFCSTATUS status = NFCSTATUS_FAILED;
161 SecureElement &se = SecureElement::getInstance();
162 if(!se.mIsWiredModeOpen)
163 return false;
nxpandroidebf53fb2016-12-22 18:48:59 +0530164
nxf24591dc0bc2c2018-02-21 17:33:08 +0530165 if( nfcFL.nfcNxpEse) {
166 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid0f06fde2017-08-14 11:25:28 +0530167 if(!se.mIsWiredModeOpen)
168 {
nxf24591dc0bc2c2018-02-21 17:33:08 +0530169 LOG(ERROR) << StringPrintf("wired mode is not open");
nxpandroid0f06fde2017-08-14 11:25:28 +0530170 return stat;
171 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530172 status = se.setNfccPwrConfig(se.NFCC_DECIDES);
173 if(status != NFA_STATUS_OK)
nxpandroid5d64ce92016-11-18 19:48:53 +0530174 {
nxf24591dc0bc2c2018-02-21 17:33:08 +0530175 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid7d44e572016-08-01 19:11:04 +0530176 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530177 else {
nxpandroid82f7e9e2018-04-05 14:54:41 +0530178 stat = se.SecEle_Modeset(se.NFCEE_DISABLE);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530179 usleep(2000 * 1000);
nxpandroid6c999f02017-02-24 15:45:35 +0530180 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530181 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON|se.COMM_LINK_ACTIVE);
182 if(status != NFA_STATUS_OK)
183 {
184 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
185 }
186 else {
nxpandroid82f7e9e2018-04-05 14:54:41 +0530187 stat = se.SecEle_Modeset(se.NFCEE_ENABLE);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530188 usleep(2000 * 1000);
189 }
nxpandroid7d44e572016-08-01 19:11:04 +0530190 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530191LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530192return stat ? JNI_TRUE : JNI_FALSE;
nxpandroid64fd68c2015-09-23 16:45:15 +0530193}
194
195/*******************************************************************************
196**
197** Function: nativeNfcSecureElement_doGetAtr
198**
199** Description: GetAtr from the connected eSE.
200** e: JVM environment.
201** o: Java object.
202** handle: Handle of secure element.
203**
204** Returns: Buffer of received data.
205**
206*******************************************************************************/
207static jbyteArray nativeNfcSecureElement_doGetAtr (JNIEnv* e, jobject, jint handle)
208{
209 bool stat = false;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530210 const int32_t recvBufferMaxSize = 1024;
211 uint8_t recvBuffer [recvBufferMaxSize];
212 int32_t recvBufferActualSize = 0;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530213 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
214 SecureElement &se = SecureElement::getInstance();
215 if(!se.mIsWiredModeOpen)
216 return NULL;
nxpandroid64fd68c2015-09-23 16:45:15 +0530217
nxf24591dc0bc2c2018-02-21 17:33:08 +0530218 stat = se.getAtr(handle, recvBuffer, &recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530219
nxf24591dc0bc2c2018-02-21 17:33:08 +0530220 //copy results back to java
nxpandroid64fd68c2015-09-23 16:45:15 +0530221 jbyteArray result = e->NewByteArray(recvBufferActualSize);
222 if (result != NULL) {
223 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
224 }
225
nxf24591dc0bc2c2018-02-21 17:33:08 +0530226 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530227
228 return result;
229}
230
231/*******************************************************************************
232**
233** Function: nativeNfcSecureElement_doTransceive
234**
235** Description: Send data to the secure element; retrieve response.
236** e: JVM environment.
237** o: Java object.
238** handle: Secure element's handle.
239** data: Data to send.
240**
241** Returns: Buffer of received data.
242**
243*******************************************************************************/
244static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data)
245{
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530246 const int32_t recvBufferMaxSize = 0x8800;//1024; 34k
247 uint8_t recvBuffer [recvBufferMaxSize];
248 int32_t recvBufferActualSize = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530249 ScopedByteArrayRW bytes(e, data);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530250 LOG(INFO) << StringPrintf("%s: enter; handle=0x%X; buf len=%zu", __func__, handle, bytes.size());
251
252 SecureElement &se = SecureElement::getInstance();
253 if(!se.mIsWiredModeOpen)
254 return NULL;
255
Sreenivas426138e2018-04-04 14:56:08 +0530256 se.transceive(reinterpret_cast<uint8_t*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, se.SmbTransceiveTimeOutVal);
nxpandroid64fd68c2015-09-23 16:45:15 +0530257
nxpandroida9a68ba2016-01-14 21:12:17 +0530258 //copy results back to java
259 jbyteArray result = e->NewByteArray(recvBufferActualSize);
260 if (result != NULL)
nxpandroid7d44e572016-08-01 19:11:04 +0530261 {
nxpandroida9a68ba2016-01-14 21:12:17 +0530262 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
nxpandroid7d44e572016-08-01 19:11:04 +0530263 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530264
265 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroida9a68ba2016-01-14 21:12:17 +0530266 return result;
nxpandroid64fd68c2015-09-23 16:45:15 +0530267}
268
269/*****************************************************************************
270**
271** Description: JNI functions
272**
273*****************************************************************************/
274static JNINativeMethod gMethods[] =
275{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530276 {"doNativeOpenSecureElementConnection", "()I", (void *) nativeNfcSecureElement_doOpenSecureElementConnection},
nxpandroid64fd68c2015-09-23 16:45:15 +0530277 {"doNativeDisconnectSecureElementConnection", "(I)Z", (void *) nativeNfcSecureElement_doDisconnectSecureElementConnection},
278 {"doNativeResetSecureElement", "(I)Z", (void *) nativeNfcSecureElement_doResetSecureElement},
nxpandroid64fd68c2015-09-23 16:45:15 +0530279 {"doTransceive", "(I[B)[B", (void *) nativeNfcSecureElement_doTransceive},
280 {"doNativeGetAtr", "(I)[B", (void *) nativeNfcSecureElement_doGetAtr},
281};
282
283
284/*******************************************************************************
285**
286** Function: register_com_android_nfc_NativeNfcSecureElement
287**
288** Description: Regisgter JNI functions with Java Virtual Machine.
289** e: Environment of JVM.
290**
291** Returns: Status of registration.
292**
293*******************************************************************************/
294int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
295{
296 return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName,
297 gMethods, NELEM(gMethods));
298}
299
nxpandroid64fd68c2015-09-23 16:45:15 +0530300} // namespace android