diff options
Diffstat (limited to 'jni/com_android_nfc.cpp')
-rw-r--r-- | jni/com_android_nfc.cpp | 564 |
1 files changed, 0 insertions, 564 deletions
diff --git a/jni/com_android_nfc.cpp b/jni/com_android_nfc.cpp deleted file mode 100644 index d794d6e..0000000 --- a/jni/com_android_nfc.cpp +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> - -#include "errno.h" -#include "com_android_nfc.h" -#include "com_android_nfc_list.h" -#include "phLibNfcStatus.h" - -/* - * JNI Initialization - */ -jint JNI_OnLoad(JavaVM *jvm, void *reserved) -{ - JNIEnv *e; - - ALOGD("NFC Service : loading JNI\n"); - - // Check JNI version - if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) - return JNI_ERR; - - android::vm = jvm; - - if (android::register_com_android_nfc_NativeNfcManager(e) == -1) - return JNI_ERR; - if (android::register_com_android_nfc_NativeNfcTag(e) == -1) - return JNI_ERR; - if (android::register_com_android_nfc_NativeP2pDevice(e) == -1) - return JNI_ERR; - if (android::register_com_android_nfc_NativeLlcpSocket(e) == -1) - return JNI_ERR; - if (android::register_com_android_nfc_NativeLlcpConnectionlessSocket(e) == -1) - return JNI_ERR; - if (android::register_com_android_nfc_NativeLlcpServiceSocket(e) == -1) - return JNI_ERR; - if (android::register_com_android_nfc_NativeNfcSecureElement(e) == -1) - return JNI_ERR; - - return JNI_VERSION_1_6; -} - -namespace android { - -extern struct nfc_jni_native_data *exported_nat; - -JavaVM *vm; - -/* - * JNI Utils - */ -JNIEnv *nfc_get_env() -{ - JNIEnv *e; - if (vm->GetEnv((void **)&e, JNI_VERSION_1_6) != JNI_OK) { - ALOGE("Current thread is not attached to VM"); - phLibNfc_Mgt_Recovery(); - abort(); - } - return e; -} - -bool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext) -{ - /* Create semaphore */ - if(sem_init(&pCallbackData->sem, 0, 0) == -1) - { - ALOGE("Semaphore creation failed (errno=0x%08x)", errno); - return false; - } - - /* Set default status value */ - pCallbackData->status = NFCSTATUS_FAILED; - - /* Copy the context */ - pCallbackData->pContext = pContext; - - /* Add to active semaphore list */ - if (!listAdd(&nfc_jni_get_monitor()->sem_list, pCallbackData)) - { - ALOGE("Failed to add the semaphore to the list"); - } - - return true; -} - -void nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData) -{ - /* Destroy semaphore */ - if (sem_destroy(&pCallbackData->sem)) - { - ALOGE("Failed to destroy semaphore (errno=0x%08x)", errno); - } - - /* Remove from active semaphore list */ - if (!listRemove(&nfc_jni_get_monitor()->sem_list, pCallbackData)) - { - ALOGE("Failed to remove semaphore from the list"); - } - -} - -void nfc_cb_data_releaseAll() -{ - nfc_jni_callback_data* pCallbackData; - - while (listGetAndRemoveNext(&nfc_jni_get_monitor()->sem_list, (void**)&pCallbackData)) - { - pCallbackData->status = NFCSTATUS_FAILED; - sem_post(&pCallbackData->sem); - } -} - -int nfc_jni_cache_object(JNIEnv *e, const char *clsname, - jobject *cached_obj) -{ - jclass cls; - jobject obj; - jmethodID ctor; - - cls = e->FindClass(clsname); - if(cls == NULL) - { - return -1; - ALOGD("Find class error\n"); - } - - - ctor = e->GetMethodID(cls, "<init>", "()V"); - - obj = e->NewObject(cls, ctor); - if(obj == NULL) - { - return -1; - ALOGD("Create object error\n"); - } - - *cached_obj = e->NewGlobalRef(obj); - if(*cached_obj == NULL) - { - e->DeleteLocalRef(obj); - ALOGD("Global ref error\n"); - return -1; - } - - e->DeleteLocalRef(obj); - - return 0; -} - - -struct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - - /* Retrieve native structure address */ - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mNative", "I"); - return (struct nfc_jni_native_data*)e->GetIntField(o, f); -} - -struct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e) -{ - return exported_nat; -} - -static nfc_jni_native_monitor_t *nfc_jni_native_monitor = NULL; - -nfc_jni_native_monitor_t* nfc_jni_init_monitor(void) -{ - - pthread_mutexattr_t recursive_attr; - - pthread_mutexattr_init(&recursive_attr); - pthread_mutexattr_settype(&recursive_attr, PTHREAD_MUTEX_RECURSIVE_NP); - - if(nfc_jni_native_monitor == NULL) - { - nfc_jni_native_monitor = (nfc_jni_native_monitor_t*)malloc(sizeof(nfc_jni_native_monitor_t)); - } - - if(nfc_jni_native_monitor != NULL) - { - memset(nfc_jni_native_monitor, 0, sizeof(nfc_jni_native_monitor_t)); - - if(pthread_mutex_init(&nfc_jni_native_monitor->reentrance_mutex, &recursive_attr) == -1) - { - ALOGE("NFC Manager Reentrance Mutex creation returned 0x%08x", errno); - return NULL; - } - - if(pthread_mutex_init(&nfc_jni_native_monitor->concurrency_mutex, NULL) == -1) - { - ALOGE("NFC Manager Concurrency Mutex creation returned 0x%08x", errno); - return NULL; - } - - if(!listInit(&nfc_jni_native_monitor->sem_list)) - { - ALOGE("NFC Manager Semaphore List creation failed"); - return NULL; - } - - LIST_INIT(&nfc_jni_native_monitor->incoming_socket_head); - - if(pthread_mutex_init(&nfc_jni_native_monitor->incoming_socket_mutex, NULL) == -1) - { - ALOGE("NFC Manager incoming socket mutex creation returned 0x%08x", errno); - return NULL; - } - - if(pthread_cond_init(&nfc_jni_native_monitor->incoming_socket_cond, NULL) == -1) - { - ALOGE("NFC Manager incoming socket condition creation returned 0x%08x", errno); - return NULL; - } - -} - - return nfc_jni_native_monitor; -} - -nfc_jni_native_monitor_t* nfc_jni_get_monitor(void) -{ - return nfc_jni_native_monitor; -} - - -phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mHandle", "I"); - - return e->GetIntField(o, f); -} - -jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mMode", "S"); - - return e->GetShortField(o, f); -} - - -int nfc_jni_get_connected_tech_index(JNIEnv *e, jobject o) -{ - - jclass c; - jfieldID f; - - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mConnectedTechIndex", "I"); - - return e->GetIntField(o, f); - -} - -jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - int connectedTech = -1; - - int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o); - jintArray techTypes = nfc_jni_get_nfc_tag_type(e, o); - - if ((connectedTechIndex != -1) && (techTypes != NULL) && - (connectedTechIndex < e->GetArrayLength(techTypes))) { - jint* technologies = e->GetIntArrayElements(techTypes, 0); - if (technologies != NULL) { - connectedTech = technologies[connectedTechIndex]; - e->ReleaseIntArrayElements(techTypes, technologies, JNI_ABORT); - } - } - - return connectedTech; - -} - -jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - jint connectedLibNfcType = -1; - - int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o); - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mTechLibNfcTypes", "[I"); - jintArray libNfcTypes = (jintArray) e->GetObjectField(o, f); - - if ((connectedTechIndex != -1) && (libNfcTypes != NULL) && - (connectedTechIndex < e->GetArrayLength(libNfcTypes))) { - jint* types = e->GetIntArrayElements(libNfcTypes, 0); - if (types != NULL) { - connectedLibNfcType = types[connectedTechIndex]; - e->ReleaseIntArrayElements(libNfcTypes, types, JNI_ABORT); - } - } - return connectedLibNfcType; - -} - -phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mConnectedHandle", "I"); - - return e->GetIntField(o, f); -} - -phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mHandle", "I"); - - return e->GetIntField(o, f); -} - -jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o) -{ - jclass c; - jfieldID f; - jintArray techtypes; - - c = e->GetObjectClass(o); - f = e->GetFieldID(c, "mTechList","[I"); - - /* Read the techtypes */ - techtypes = (jintArray) e->GetObjectField(o, f); - - return techtypes; -} - - - -//Display status code -const char* nfc_jni_get_status_name(NFCSTATUS status) -{ - #define STATUS_ENTRY(status) { status, #status } - - struct status_entry { - NFCSTATUS code; - const char *name; - }; - - const struct status_entry sNameTable[] = { - STATUS_ENTRY(NFCSTATUS_SUCCESS), - STATUS_ENTRY(NFCSTATUS_FAILED), - STATUS_ENTRY(NFCSTATUS_INVALID_PARAMETER), - STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_RESOURCES), - STATUS_ENTRY(NFCSTATUS_TARGET_LOST), - STATUS_ENTRY(NFCSTATUS_INVALID_HANDLE), - STATUS_ENTRY(NFCSTATUS_MULTIPLE_TAGS), - STATUS_ENTRY(NFCSTATUS_ALREADY_REGISTERED), - STATUS_ENTRY(NFCSTATUS_FEATURE_NOT_SUPPORTED), - STATUS_ENTRY(NFCSTATUS_SHUTDOWN), - STATUS_ENTRY(NFCSTATUS_ABORTED), - STATUS_ENTRY(NFCSTATUS_REJECTED ), - STATUS_ENTRY(NFCSTATUS_NOT_INITIALISED), - STATUS_ENTRY(NFCSTATUS_PENDING), - STATUS_ENTRY(NFCSTATUS_BUFFER_TOO_SMALL), - STATUS_ENTRY(NFCSTATUS_ALREADY_INITIALISED), - STATUS_ENTRY(NFCSTATUS_BUSY), - STATUS_ENTRY(NFCSTATUS_TARGET_NOT_CONNECTED), - STATUS_ENTRY(NFCSTATUS_MULTIPLE_PROTOCOLS), - STATUS_ENTRY(NFCSTATUS_DESELECTED), - STATUS_ENTRY(NFCSTATUS_INVALID_DEVICE), - STATUS_ENTRY(NFCSTATUS_MORE_INFORMATION), - STATUS_ENTRY(NFCSTATUS_RF_TIMEOUT), - STATUS_ENTRY(NFCSTATUS_RF_ERROR), - STATUS_ENTRY(NFCSTATUS_BOARD_COMMUNICATION_ERROR), - STATUS_ENTRY(NFCSTATUS_INVALID_STATE), - STATUS_ENTRY(NFCSTATUS_NOT_REGISTERED), - STATUS_ENTRY(NFCSTATUS_RELEASED), - STATUS_ENTRY(NFCSTATUS_NOT_ALLOWED), - STATUS_ENTRY(NFCSTATUS_INVALID_REMOTE_DEVICE), - STATUS_ENTRY(NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED), - STATUS_ENTRY(NFCSTATUS_READ_FAILED), - STATUS_ENTRY(NFCSTATUS_WRITE_FAILED), - STATUS_ENTRY(NFCSTATUS_NO_NDEF_SUPPORT), - STATUS_ENTRY(NFCSTATUS_EOF_NDEF_CONTAINER_REACHED), - STATUS_ENTRY(NFCSTATUS_INVALID_RECEIVE_LENGTH), - STATUS_ENTRY(NFCSTATUS_INVALID_FORMAT), - STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_STORAGE), - STATUS_ENTRY(NFCSTATUS_FORMAT_ERROR), - }; - - int i = sizeof(sNameTable)/sizeof(status_entry); - - while(i>0) - { - i--; - if (sNameTable[i].code == PHNFCSTATUS(status)) - { - return sNameTable[i].name; - } - } - - return "UNKNOWN"; -} - -int addTechIfNeeded(int *techList, int* handleList, int* typeList, int listSize, - int maxListSize, int techToAdd, int handleToAdd, int typeToAdd) { - bool found = false; - for (int i = 0; i < listSize; i++) { - if (techList[i] == techToAdd) { - found = true; - break; - } - } - if (!found && listSize < maxListSize) { - techList[listSize] = techToAdd; - handleList[listSize] = handleToAdd; - typeList[listSize] = typeToAdd; - return listSize + 1; - } - else { - return listSize; - } -} - - -#define MAX_NUM_TECHNOLOGIES 32 - -/* - * Utility to get a technology tree and a corresponding handle list from a detected tag. - */ -void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList, - uint8_t count, jintArray* techList, jintArray* handleList, - jintArray* libnfcTypeList) -{ - int technologies[MAX_NUM_TECHNOLOGIES]; - int handles[MAX_NUM_TECHNOLOGIES]; - int libnfctypes[MAX_NUM_TECHNOLOGIES]; - - int index = 0; - // TODO: This counts from up to down because on multi-protocols, the - // ISO handle is usually the second, and we prefer the ISO. Should implement - // a method to find the "preferred handle order" and use that instead, - // since we shouldn't have dependencies on the tech list ordering. - for (int target = count - 1; target >= 0; target--) { - int type = devList[target].psRemoteDevInfo->RemDevType; - int handle = devList[target].hTargetDev; - switch (type) - { - case phNfc_eISO14443_A_PICC: - case phNfc_eISO14443_4A_PICC: - { - index = addTechIfNeeded(technologies, handles, libnfctypes, index, - MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type); - break; - } - case phNfc_eISO14443_4B_PICC: - { - index = addTechIfNeeded(technologies, handles, libnfctypes, index, - MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type); - index = addTechIfNeeded(technologies, handles, libnfctypes, index, - MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type); - }break; - case phNfc_eISO14443_3A_PICC: - { - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); - }break; - case phNfc_eISO14443_B_PICC: - { - // TODO a bug in libnfc will cause 14443-3B only cards - // to be returned as this type as well, but these cards - // are very rare. Hence assume it's -4B - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type); - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type); - }break; - case phNfc_eISO15693_PICC: - { - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO15693, handle, type); - }break; - case phNfc_eMifare_PICC: - { - // We don't want to be too clever here; libnfc has already determined - // it's a Mifare, so we only check for UL, for all other tags - // we assume it's a mifare classic. This should make us more - // future-proof. - int sak = devList[target].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; - switch(sak) - { - case 0x00: - // could be UL or UL-C - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_UL, handle, type); - break; - default: - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_CLASSIC, handle, type); - break; - } - }break; - case phNfc_eFelica_PICC: - { - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_FELICA, handle, type); - }break; - case phNfc_eJewel_PICC: - { - // Jewel represented as NfcA - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); - }break; - default: - { - index = addTechIfNeeded(technologies, handles, libnfctypes, - index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_UNKNOWN, handle, type); - } - } - } - - // Build the Java arrays - if (techList != NULL) { - *techList = e->NewIntArray(index); - e->SetIntArrayRegion(*techList, 0, index, technologies); - } - - if (handleList != NULL) { - *handleList = e->NewIntArray(index); - e->SetIntArrayRegion(*handleList, 0, index, handles); - } - - if (libnfcTypeList != NULL) { - *libnfcTypeList = e->NewIntArray(index); - e->SetIntArrayRegion(*libnfcTypeList, 0, index, libnfctypes); - } -} - -} // namespace android |