1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "OverrideLog.h" 17 #include "SecureElement.h" 18 #include "JavaClassConstants.h" 19 #include "PowerSwitch.h" 20 #include <ScopedPrimitiveArray.h> 21 22 namespace android 23 { 24 25 26 extern void com_android_nfc_NfcManager_disableDiscovery (JNIEnv* e, jobject o); 27 extern void com_android_nfc_NfcManager_enableDiscovery (JNIEnv* e, jobject o, jint mode); 28 extern int gGeneralTransceiveTimeout; 29 30 // These must match the EE_ERROR_ types in NfcService.java 31 static const int EE_ERROR_IO = -1; 32 static const int EE_ERROR_ALREADY_OPEN = -2; 33 static const int EE_ERROR_INIT = -3; 34 static const int EE_ERROR_LISTEN_MODE = -4; 35 static const int EE_ERROR_EXT_FIELD = -5; 36 static const int EE_ERROR_NFC_DISABLED = -6; 37 38 /******************************************************************************* 39 ** 40 ** Function: nativeNfcSecureElement_doOpenSecureElementConnection 41 ** 42 ** Description: Connect to the secure element. 43 ** e: JVM environment. 44 ** o: Java object. 45 ** 46 ** Returns: Handle of secure element. values < 0 represent failure. 47 ** 48 *******************************************************************************/ 49 static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject) 50 { 51 ALOGD("%s: enter", __FUNCTION__); 52 bool stat = true; 53 jint secElemHandle = EE_ERROR_INIT; 54 SecureElement &se = SecureElement::getInstance(); 55 56 if (se.isActivatedInListenMode()) { 57 ALOGD("Denying SE open due to SE listen mode active"); 58 secElemHandle = EE_ERROR_LISTEN_MODE; 59 goto TheEnd; 60 } 61 62 if (se.isRfFieldOn()) { 63 ALOGD("Denying SE open due to SE in active RF field"); 64 secElemHandle = EE_ERROR_EXT_FIELD; 65 goto TheEnd; 66 } 67 //tell the controller to power up to get ready for sec elem operations 68 PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER); 69 PowerSwitch::getInstance ().setModeOn (PowerSwitch::SE_CONNECTED); 70 71 //if controller is not routing AND there is no pipe connected, 72 //then turn on the sec elem 73 if (! se.isBusy()) 74 stat = se.activate(0); 75 76 if (stat) 77 { 78 //establish a pipe to sec elem 79 stat = se.connectEE(); 80 if (stat) 81 { 82 secElemHandle = se.mActiveEeHandle; 83 } 84 else 85 { 86 se.deactivate (0); 87 } 88 } 89 90 //if code fails to connect to the secure element, and nothing is active, then 91 //tell the controller to power down 92 if ((!stat) && (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED))) 93 { 94 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); 95 } 96 97 TheEnd: 98 ALOGD("%s: exit; return handle=0x%X", __FUNCTION__, secElemHandle); 99 return secElemHandle; 100 } 101 102 103 /******************************************************************************* 104 ** 105 ** Function: nativeNfcSecureElement_doDisconnectSecureElementConnection 106 ** 107 ** Description: Disconnect from the secure element. 108 ** e: JVM environment. 109 ** o: Java object. 110 ** handle: Handle of secure element. 111 ** 112 ** Returns: True if ok. 113 ** 114 *******************************************************************************/ 115 static jboolean nativeNfcSecureElement_doDisconnectSecureElementConnection (JNIEnv*, jobject, jint handle) 116 { 117 ALOGD("%s: enter; handle=0x%04x", __FUNCTION__, handle); 118 bool stat = false; 119 120 stat = SecureElement::getInstance().disconnectEE (handle); 121 122 //if controller is not routing AND there is no pipe connected, 123 //then turn off the sec elem 124 if (! SecureElement::getInstance().isBusy()) 125 SecureElement::getInstance().deactivate (handle); 126 127 //if nothing is active after this, then tell the controller to power down 128 if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::SE_CONNECTED)) 129 PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); 130 131 ALOGD("%s: exit", __FUNCTION__); 132 return stat ? JNI_TRUE : JNI_FALSE; 133 } 134 135 136 /******************************************************************************* 137 ** 138 ** Function: nativeNfcSecureElement_doTransceive 139 ** 140 ** Description: Send data to the secure element; retrieve response. 141 ** e: JVM environment. 142 ** o: Java object. 143 ** handle: Secure element's handle. 144 ** data: Data to send. 145 ** 146 ** Returns: Buffer of received data. 147 ** 148 *******************************************************************************/ 149 static jbyteArray nativeNfcSecureElement_doTransceive (JNIEnv* e, jobject, jint handle, jbyteArray data) 150 { 151 const INT32 recvBufferMaxSize = 1024; 152 UINT8 recvBuffer [recvBufferMaxSize]; 153 INT32 recvBufferActualSize = 0; 154 155 ScopedByteArrayRW bytes(e, data); 156 157 ALOGD("%s: enter; handle=0x%X; buf len=%zu", __FUNCTION__, handle, bytes.size()); 158 SecureElement::getInstance().transceive(reinterpret_cast<UINT8*>(&bytes[0]), bytes.size(), recvBuffer, recvBufferMaxSize, recvBufferActualSize, gGeneralTransceiveTimeout); 159 160 //copy results back to java 161 jbyteArray result = e->NewByteArray(recvBufferActualSize); 162 if (result != NULL) { 163 e->SetByteArrayRegion(result, 0, recvBufferActualSize, (jbyte *) recvBuffer); 164 } 165 166 ALOGD("%s: exit: recv len=%ld", __FUNCTION__, recvBufferActualSize); 167 return result; 168 } 169 170 171 /******************************************************************************* 172 ** 173 ** Function: nativeNfcSecureElement_doGetUid 174 ** 175 ** Description: Get the secure element's unique ID. 176 ** e: JVM environment. 177 ** o: Java object. 178 ** handle: Handle of secure element. 179 ** 180 ** Returns: Secure element's unique ID. 181 ** 182 *******************************************************************************/ 183 static jbyteArray nativeNfcSecureElement_doGetUid (JNIEnv*, jobject, jint handle) 184 { 185 ALOGD("%s: enter; handle=0x%X", __FUNCTION__, handle); 186 jbyteArray secureElementUid = NULL; 187 188 SecureElement::getInstance ().getUiccId (handle, secureElementUid); 189 190 ALOGD("%s: exit", __FUNCTION__); 191 return secureElementUid; 192 } 193 194 195 /******************************************************************************* 196 ** 197 ** Function: nativeNfcSecureElement_doGetTechList 198 ** 199 ** Description: Get a list of technologies that the secure element supports. 200 ** e: JVM environment. 201 ** o: Java object. 202 ** handle: Handle of secure element. 203 ** 204 ** Returns: Array of technologies. 205 ** 206 *******************************************************************************/ 207 static jintArray nativeNfcSecureElement_doGetTechList (JNIEnv*, jobject, jint handle) 208 { 209 ALOGD("%s: enter; handle=0x%X", __FUNCTION__, handle); 210 jintArray techList = NULL; 211 212 SecureElement::getInstance().getTechnologyList (handle, techList); 213 214 ALOGD("%s: exit", __FUNCTION__); 215 return techList; 216 } 217 218 219 /***************************************************************************** 220 ** 221 ** Description: JNI functions 222 ** 223 *****************************************************************************/ 224 static JNINativeMethod gMethods[] = 225 { 226 {"doNativeOpenSecureElementConnection", "()I", (void *) nativeNfcSecureElement_doOpenSecureElementConnection}, 227 {"doNativeDisconnectSecureElementConnection", "(I)Z", (void *) nativeNfcSecureElement_doDisconnectSecureElementConnection}, 228 {"doTransceive", "(I[B)[B", (void *) nativeNfcSecureElement_doTransceive}, 229 {"doGetUid", "(I)[B", (void *) nativeNfcSecureElement_doGetUid}, 230 {"doGetTechList", "(I)[I", (void *) nativeNfcSecureElement_doGetTechList}, 231 }; 232 233 234 /******************************************************************************* 235 ** 236 ** Function: register_com_android_nfc_NativeNfcSecureElement 237 ** 238 ** Description: Regisgter JNI functions with Java Virtual Machine. 239 ** e: Environment of JVM. 240 ** 241 ** Returns: Status of registration. 242 ** 243 *******************************************************************************/ 244 int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e) 245 { 246 return jniRegisterNativeMethods(e, gNativeNfcSecureElementClassName, 247 gMethods, NELEM(gMethods)); 248 } 249 250 251 } // namespace android 252