blob: e29ce59286a64792b7cb8baf69ee386f77101fb9 [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*
nxp61433af447a52020-02-12 16:58:04 +053015* Copyright 2018-2020 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{
Himanshu Singh0147ad32019-11-08 18:44:02 +053036#define INVALID_LEN_SW1 0x64
37#define INVALID_LEN_SW2 0xFF
nxpandroid64fd68c2015-09-23 16:45:15 +053038static const int EE_ERROR_INIT = -3;
Suraj Uday Kotharkar93673fe2019-07-12 16:25:46 +053039extern bool nfcManager_isNfcActive();
nxpandroid64fd68c2015-09-23 16:45:15 +053040/*******************************************************************************
41**
42** Function: nativeNfcSecureElement_doOpenSecureElementConnection
43**
44** Description: Connect to the secure element.
45** e: JVM environment.
46** o: Java object.
47**
48** Returns: Handle of secure element. values < 0 represent failure.
49**
50*******************************************************************************/
51static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject)
52{
nxf24591dc0bc2c2018-02-21 17:33:08 +053053 LOG(INFO) << StringPrintf("%s: Enter; ", __func__);
nxpandroid64fd68c2015-09-23 16:45:15 +053054 bool stat = false;
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +053055 const int32_t recvBufferMaxSize = 1024;
56 uint8_t recvBuffer [recvBufferMaxSize];
57 int32_t recvBufferActualSize = 0;
58
nxpandroid64fd68c2015-09-23 16:45:15 +053059 jint secElemHandle = EE_ERROR_INIT;
nxpandroid64fd68c2015-09-23 16:45:15 +053060 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid64fd68c2015-09-23 16:45:15 +053061 SecureElement &se = SecureElement::getInstance();
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053062 se.mModeSetNtfstatus = NFA_STATUS_FAILED;
nxpandroid7d44e572016-08-01 19:11:04 +053063
Suraj Uday Kotharkare12d10f2019-04-17 15:44:08 +053064 NativeJniExtns::getInstance().notifyNfcEvent(__func__);
nxf24591dc0bc2c2018-02-21 17:33:08 +053065 /* Tell the controller to power up to get ready for sec elem operations */
66 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
67 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED);
nxpandroid0f06fde2017-08-14 11:25:28 +053068
nxf24591dc0bc2c2018-02-21 17:33:08 +053069 /* If controller is not routing AND there is no pipe connected,
70 then turn on the sec elem */
71 stat = se.activate(SecureElement::ESE_ID); // It is to get the current activated handle.
nxpandroid0f06fde2017-08-14 11:25:28 +053072
nxf24591dc0bc2c2018-02-21 17:33:08 +053073 if((stat) && (nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD))
nxpandroid0f06fde2017-08-14 11:25:28 +053074 {
nxf24591dc0bc2c2018-02-21 17:33:08 +053075 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON|se.COMM_LINK_ACTIVE);
nxpandroid7d44e572016-08-01 19:11:04 +053076 }
nxpandroid0f06fde2017-08-14 11:25:28 +053077 if(status != NFA_STATUS_OK)
78 {
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053079 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
80 stat =false;
nxpandroid0f06fde2017-08-14 11:25:28 +053081 }
82 else
83 {
nxpandroid82f7e9e2018-04-05 14:54:41 +053084 stat = se.SecEle_Modeset(se.NFCEE_ENABLE);
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053085 if(se.mModeSetNtfstatus != NFA_STATUS_OK)
86 {
87 stat = false;
88 LOG(INFO) << StringPrintf("%s: Mode set ntf STATUS_FAILED", __func__);
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +053089
hariprasad nalacheruvu7254b032018-11-13 15:43:47 +053090 SyncEventGuard guard (se.mEERecoveryComplete);
91 {
92 se.mEERecoveryComplete.wait();
93 LOG(INFO) << StringPrintf("%s: Recovery complete", __func__);
94 }
95 if(se.mErrorRecovery)
96 {
97 stat = true;
98 }
99 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530100 if(stat == true)
101 {
hariprasad nalacheruvuf0328142018-11-07 14:03:02 +0530102 se.mIsWiredModeOpen = true;
Suraj Uday Kotharkar9e250fb2018-06-08 21:06:52 +0530103 stat = se.apduGateReset(se.mActiveEeHandle, recvBuffer, &recvBufferActualSize);
104 if (stat)
105 {
106 secElemHandle = se.mActiveEeHandle;
107 }
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530108 }
nxpandroid0f06fde2017-08-14 11:25:28 +0530109 }
nxpandroid0f06fde2017-08-14 11:25:28 +0530110
nxf24591dc0bc2c2018-02-21 17:33:08 +0530111 /* if code fails to connect to the secure element, and nothing is active, then
112 * tell the controller to power down
113 */
114 if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)))
115 {
116 LOG(INFO) << StringPrintf("%s: stat fails; ", __func__);
117 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
118 se.deactivate(SecureElement::ESE_ID);
119 se.mIsWiredModeOpen = false;
120 stat = false;
121 }
122 LOG(INFO) << StringPrintf("%s: exit; return handle=0x%X", __func__, secElemHandle);
123 return secElemHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +0530124}
125
126
127/*******************************************************************************
128**
129** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection
130**
131** Description: Disconnect from the secure element.
132** e: JVM environment.
133** o: Java object.
134** handle: Handle of secure element.
135**
136** Returns: True if ok.
137**
138*******************************************************************************/
139static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle)
140{
nxf24591dc0bc2c2018-02-21 17:33:08 +0530141 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
nxpandroid64fd68c2015-09-23 16:45:15 +0530142 bool stat = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530143 NFCSTATUS status = NFCSTATUS_FAILED;
nxpandroid34627bd2016-05-27 15:52:30 +0530144 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530145
nxf24591dc0bc2c2018-02-21 17:33:08 +0530146 if(!se.mIsWiredModeOpen)
147 return false;
Sreenivas88ee6aa2018-05-14 13:17:57 +0530148 /* release any pending transceive wait */
149 se.releasePendingTransceive();
nxpandroid7d44e572016-08-01 19:11:04 +0530150
nxf24591dc0bc2c2018-02-21 17:33:08 +0530151 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON);
152 if(status != NFA_STATUS_OK)
153 {
154 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
nxpandroid0f06fde2017-08-14 11:25:28 +0530155 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530156 else
157 {
Sreenivasf83b8762018-04-09 16:09:49 +0530158 status = se.sendEvent(SecureElement::EVT_END_OF_APDU_TRANSFER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530159 if(status == NFA_STATUS_OK)
Sreenivasf83b8762018-04-09 16:09:49 +0530160 stat = true;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530161 }
Sreenivas88ee6aa2018-05-14 13:17:57 +0530162 se.mIsWiredModeOpen = false;
nxpandroid64fd68c2015-09-23 16:45:15 +0530163
nxpandroid5d64ce92016-11-18 19:48:53 +0530164 /* if nothing is active after this, then tell the controller to power down */
nxpandroid64fd68c2015-09-23 16:45:15 +0530165 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))
166 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530167 LOG(INFO) << StringPrintf("%s: exit", __func__);
nxpandroid64fd68c2015-09-23 16:45:15 +0530168 return stat ? JNI_TRUE : JNI_FALSE;
169}
170/*******************************************************************************
171**
Suraj Uday Kotharkarce445d82019-04-19 10:30:46 +0530172** Function: nativeNfcSecureElement_doResetForEseCosUpdate
nxpandroid64fd68c2015-09-23 16:45:15 +0530173**
174** Description: Reset the secure element.
175** e: JVM environment.
176** o: Java object.
177** handle: Handle of secure element.
178**
179** Returns: True if ok.
180**
181*******************************************************************************/
Suraj Uday Kotharkarce445d82019-04-19 10:30:46 +0530182static jboolean nativeNfcSecureElement_doResetForEseCosUpdate(JNIEnv*, jobject,
183 jint handle) {
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530184 bool stat = false;
185 int ret = -1;
186 NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
187 tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs ();
nxp61433af447a52020-02-12 16:58:04 +0530188
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530189 LOG(INFO) << StringPrintf("%s: Entry", __func__);
190 if(NULL == halFuncEntries) {
191 LOG(INFO) << StringPrintf("%s: halFuncEntries is NULL", __func__);
192 } else {
nxp61433af447a52020-02-12 16:58:04 +0530193 ret = theInstance.resetEse((uint64_t)NFA_ESE_HARD_RESET);
194 if(ret == 0) {
195 LOG(INFO) << StringPrintf("%s: reset IOCTL failed", __func__);
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530196 } else {
197 stat = true;
nxpandroid7d44e572016-08-01 19:11:04 +0530198 }
Suraj Uday Kotharkara09a2b72019-04-17 15:07:44 +0530199 }
200 LOG(INFO) << StringPrintf("%s: exit", __func__);
201 return stat;
nxpandroid64fd68c2015-09-23 16:45:15 +0530202}
203
204/*******************************************************************************
205**
206** Function: nativeNfcSecureElement_doGetAtr
207**
208** Description: GetAtr from the connected eSE.
209** e: JVM environment.
210** o: Java object.
211** handle: Handle of secure element.
212**
213** Returns: Buffer of received data.
214**
215*******************************************************************************/
216static jbyteArray nativeNfcSecureElement_doGetAtr (JNIEnv* e, jobject, jint handle)
217{
218 bool stat = false;
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530219 const int32_t recvBufferMaxSize = 1024;
220 uint8_t recvBuffer [recvBufferMaxSize];
221 int32_t recvBufferActualSize = 0;
nxf24591dc0bc2c2018-02-21 17:33:08 +0530222 LOG(INFO) << StringPrintf("%s: enter; handle=0x%04x", __func__, handle);
223 SecureElement &se = SecureElement::getInstance();
nxpandroid64fd68c2015-09-23 16:45:15 +0530224
hariprasad nalacheruvuba06cec2018-06-06 17:55:23 +0530225 stat = se.getAtr(recvBuffer, &recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530226
nxf24591dc0bc2c2018-02-21 17:33:08 +0530227 //copy results back to java
nxpandroid64fd68c2015-09-23 16:45:15 +0530228 jbyteArray result = e->NewByteArray(recvBufferActualSize);
229 if (result != NULL) {
230 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
231 }
232
nxf24591dc0bc2c2018-02-21 17:33:08 +0530233 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530234
235 return result;
236}
237
238/*******************************************************************************
239**
240** Function: nativeNfcSecureElement_doTransceive
241**
242** Description: Send data to the secure element; retrieve response.
243** e: JVM environment.
244** o: Java object.
245** handle: Secure element's handle.
246** data: Data to send.
247**
248** Returns: Buffer of received data.
249**
250*******************************************************************************/
251static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data)
252{
nxpandroid6fd9cdb2017-07-12 18:25:41 +0530253 const int32_t recvBufferMaxSize = 0x8800;//1024; 34k
254 uint8_t recvBuffer [recvBufferMaxSize];
255 int32_t recvBufferActualSize = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530256 ScopedByteArrayRW bytes(e, data);
nxf24591dc0bc2c2018-02-21 17:33:08 +0530257 LOG(INFO) << StringPrintf("%s: enter; handle=0x%X; buf len=%zu", __func__, handle, bytes.size());
Himanshu Singh0147ad32019-11-08 18:44:02 +0530258 if(bytes.size() > recvBufferMaxSize) {
259 LOG(ERROR) << StringPrintf("%s: datasize not supported", __func__);
260 uint8_t respBuf[] = {INVALID_LEN_SW1, INVALID_LEN_SW2};
261 jbyteArray resp = e->NewByteArray(sizeof(respBuf));
262 if (resp != NULL) {
263 e->SetByteArrayRegion(resp, 0, sizeof(respBuf), (jbyte *) respBuf);
264 }
265 return resp;
266 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530267
268 SecureElement &se = SecureElement::getInstance();
269 if(!se.mIsWiredModeOpen)
270 return NULL;
271
Sreenivas426138e2018-04-04 14:56:08 +0530272 se.transceive(reinterpret_cast<uint8_t*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, se.SmbTransceiveTimeOutVal);
nxpandroid64fd68c2015-09-23 16:45:15 +0530273
nxpandroida9a68ba2016-01-14 21:12:17 +0530274 //copy results back to java
275 jbyteArray result = e->NewByteArray(recvBufferActualSize);
276 if (result != NULL)
nxpandroid7d44e572016-08-01 19:11:04 +0530277 {
nxpandroida9a68ba2016-01-14 21:12:17 +0530278 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer);
nxpandroid7d44e572016-08-01 19:11:04 +0530279 }
nxf24591dc0bc2c2018-02-21 17:33:08 +0530280
281 LOG(INFO) << StringPrintf("%s: exit: recv len=%d", __func__, recvBufferActualSize);
nxpandroida9a68ba2016-01-14 21:12:17 +0530282 return result;
nxpandroid64fd68c2015-09-23 16:45:15 +0530283}
Suraj Uday Kotharkar93673fe2019-07-12 16:25:46 +0530284/*******************************************************************************
285**
286** Function: nfcManager_doactivateSeInterface
287**
288** Description: Activate SecureElement Interface
289**
290** Returns: Success/Failure
291** Success = 0x00
292** Failure = 0x03
293**
294*******************************************************************************/
295static jint nfcManager_doactivateSeInterface(JNIEnv* e, jobject o) {
296 jint ret = NFA_STATUS_FAILED;
297 tNFA_STATUS status = NFA_STATUS_FAILED;
298 SecureElement& se = SecureElement::getInstance();
299 se.mModeSetNtfstatus = NFA_STATUS_FAILED;
nxpandroid64fd68c2015-09-23 16:45:15 +0530300
Suraj Uday Kotharkar93673fe2019-07-12 16:25:46 +0530301 LOG(INFO) << StringPrintf("%s: enter", __func__);
302
303 if (!nfcManager_isNfcActive() || (!nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD)) {
304 LOG(INFO) << StringPrintf("%s: Not supported", __func__);
305 return ret;
306 }
307 if (se.mIsSeIntfActivated) {
308 LOG(INFO) << StringPrintf("%s: Already activated", __func__);
309 return NFA_STATUS_OK;
310 }
311 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON | se.COMM_LINK_ACTIVE);
312 if (status == NFA_STATUS_OK) {
313 status = se.SecEle_Modeset(se.NFCEE_ENABLE);
314 if (se.mModeSetNtfstatus != NFA_STATUS_OK) {
315 LOG(INFO) << StringPrintf("%s: Mode set ntf STATUS_FAILED", __func__);
316 SyncEventGuard guard(se.mEERecoveryComplete);
317 if (se.mEERecoveryComplete.wait(NFC_CMD_TIMEOUT)) {
318 LOG(INFO) << StringPrintf("%s: Recovery complete", __func__);
319 ret = NFA_STATUS_OK;
320 }
321 } else {
322 ret = NFA_STATUS_OK;
323 }
324 } else {
325 LOG(INFO) << StringPrintf("%s: power link command failed", __func__);
326 }
327
328 if (ret == NFA_STATUS_OK) se.mIsSeIntfActivated = true;
329 LOG(INFO) << StringPrintf("%s: Exit", __func__);
330 return ret;
331}
332/*******************************************************************************
333**
334** Function: nfcManager_dodeactivateSeInterface
335**
336** Description: Deactivate SecureElement Interface
337**
338** Returns: Success/Failure
339** Success = 0x00
340** Failure = 0x03
341**
342*******************************************************************************/
343static jint nfcManager_dodeactivateSeInterface(JNIEnv* e, jobject o) {
344 jint ret = NFA_STATUS_FAILED;
345 tNFA_STATUS status = NFA_STATUS_FAILED;
346 SecureElement& se = SecureElement::getInstance();
347 LOG(INFO) << StringPrintf("%s: enter", __func__);
348
349 if (!nfcManager_isNfcActive() || (!nfcFL.eseFL._NCI_NFCEE_PWR_LINK_CMD)) {
350 LOG(INFO) << StringPrintf("%s: Not supported", __func__);
351 return ret;
352 }
353 if (!se.mIsSeIntfActivated) {
354 LOG(INFO) << StringPrintf("%s: Already Deactivated or call activate first",
355 __func__);
356 return NFA_STATUS_OK;
357 }
358
359 status = se.setNfccPwrConfig(se.POWER_ALWAYS_ON);
360 if (status == NFA_STATUS_OK) {
361 LOG(INFO) << StringPrintf("%s: power link command success", __func__);
362 se.mIsSeIntfActivated = false;
363 ret = NFA_STATUS_OK;
364 }
365 LOG(INFO) << StringPrintf("%s: Exit, status =0x02%u", __func__, status);
366 return ret;
367}
nxpandroid64fd68c2015-09-23 16:45:15 +0530368/*****************************************************************************
369**
370** Description: JNI functions
371**
372*****************************************************************************/
Suraj Uday Kotharkarce445d82019-04-19 10:30:46 +0530373static JNINativeMethod gMethods[] = {
374 {"doNativeOpenSecureElementConnection", "()I",
375 (void*)nativeNfcSecureElement_doOpenSecureElementConnection},
376 {"doNativeDisconnectSecureElementConnection", "(I)Z",
377 (void*)nativeNfcSecureElement_doDisconnectSecureElementConnection},
378 {"doResetForEseCosUpdate", "(I)Z",
379 (void*)nativeNfcSecureElement_doResetForEseCosUpdate},
380 {"doTransceive", "(I[B)[B", (void*)nativeNfcSecureElement_doTransceive},
381 {"doNativeGetAtr", "(I)[B", (void*)nativeNfcSecureElement_doGetAtr},
Suraj Uday Kotharkar93673fe2019-07-12 16:25:46 +0530382 {"doactivateSeInterface", "()I", (void*)nfcManager_doactivateSeInterface},
383 {"dodeactivateSeInterface", "()I",
384 (void*)nfcManager_dodeactivateSeInterface},
nxpandroid64fd68c2015-09-23 16:45:15 +0530385};
386
nxpandroid64fd68c2015-09-23 16:45:15 +0530387/*******************************************************************************
388**
389** Function: register_com_android_nfc_NativeNfcSecureElement
390**
391** Description: Regisgter JNI functions with Java Virtual Machine.
392** e: Environment of JVM.
393**
394** Returns: Status of registration.
395**
396*******************************************************************************/
397int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e)
398{
399 return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName,
400 gMethods, NELEM(gMethods));
401}
402
nxpandroid64fd68c2015-09-23 16:45:15 +0530403} // namespace android