diff options
author | Martijn Coenen <maco@google.com> | 2012-07-25 08:56:11 -0700 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2012-07-25 08:57:34 -0700 |
commit | 4bbd47e5507d4c47a4d722216606307e45195a0a (patch) | |
tree | 5a28cbb02a1b5cadfcac4648d89afe3cec7b1e11 /jni | |
parent | ff94ceff4c2715134c85a84c75d47a5835f1a598 (diff) | |
download | packages_apps_nfc-4bbd47e5507d4c47a4d722216606307e45195a0a.zip packages_apps_nfc-4bbd47e5507d4c47a4d722216606307e45195a0a.tar.gz packages_apps_nfc-4bbd47e5507d4c47a4d722216606307e45195a0a.tar.bz2 |
Move NXP JNI and DeviceHost implementation into separate dir.
Preparation for the new NCI stack. The idea is to
build either the NXP or the NCI stack, triggered
by a makefile switch. To that end, move the
DeviceHost and JNI implementations in their own
directory, so we can build them only if needed.
Change-Id: I8579ec30ceb1908e4cd180cfbd10224aa4bddb8d
Diffstat (limited to 'jni')
-rw-r--r-- | jni/Android.mk | 35 | ||||
-rw-r--r-- | jni/com_android_nfc.cpp | 564 | ||||
-rw-r--r-- | jni/com_android_nfc.h | 261 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp | 253 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeLlcpServiceSocket.cpp | 227 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeLlcpSocket.cpp | 468 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeNfcManager.cpp | 2623 | ||||
-rwxr-xr-x | jni/com_android_nfc_NativeNfcSecureElement.cpp | 770 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeNfcTag.cpp | 1255 | ||||
-rw-r--r-- | jni/com_android_nfc_NativeP2pDevice.cpp | 490 | ||||
-rw-r--r-- | jni/com_android_nfc_list.cpp | 210 | ||||
-rw-r--r-- | jni/com_android_nfc_list.h | 49 |
12 files changed, 0 insertions, 7205 deletions
diff --git a/jni/Android.mk b/jni/Android.mk deleted file mode 100644 index 8ae792a..0000000 --- a/jni/Android.mk +++ /dev/null @@ -1,35 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - - - -LOCAL_SRC_FILES:= \ - com_android_nfc_NativeLlcpConnectionlessSocket.cpp \ - com_android_nfc_NativeLlcpServiceSocket.cpp \ - com_android_nfc_NativeLlcpSocket.cpp \ - com_android_nfc_NativeNfcManager.cpp \ - com_android_nfc_NativeNfcTag.cpp \ - com_android_nfc_NativeP2pDevice.cpp \ - com_android_nfc_NativeNfcSecureElement.cpp \ - com_android_nfc_list.cpp \ - com_android_nfc.cpp - -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) \ - external/libnfc-nxp/src \ - external/libnfc-nxp/inc - -LOCAL_SHARED_LIBRARIES := \ - libnativehelper \ - libcutils \ - libutils \ - libnfc \ - libhardware - -#LOCAL_CFLAGS += -O0 -g - -LOCAL_MODULE := libnfc_jni -LOCAL_MODULE_TAGS := optional - -include $(BUILD_SHARED_LIBRARY) 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 diff --git a/jni/com_android_nfc.h b/jni/com_android_nfc.h deleted file mode 100644 index b876dad..0000000 --- a/jni/com_android_nfc.h +++ /dev/null @@ -1,261 +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. - */ - -#ifndef __COM_ANDROID_NFC_JNI_H__ -#define __COM_ANDROID_NFC_JNI_H__ - -#define LOG_TAG "NFCJNI" - -#include <JNIHelp.h> -#include <jni.h> - -#include <pthread.h> -#include <sys/queue.h> - -extern "C" { -#include <phNfcStatus.h> -#include <phNfcTypes.h> -#include <phNfcIoctlCode.h> -#include <phLibNfc.h> -#include <phDal4Nfc_messageQueueLib.h> -#include <phFriNfc_NdefMap.h> -#include <cutils/log.h> -#include <com_android_nfc_list.h> -#include <semaphore.h> - -} -#include <cutils/properties.h> // for property_get - - -/* Discovery modes -- keep in sync with NFCManager.DISCOVERY_MODE_* */ -#define DISCOVERY_MODE_TAG_READER 0 -#define DISCOVERY_MODE_NFCIP1 1 -#define DISCOVERY_MODE_CARD_EMULATION 2 - -#define DISCOVERY_MODE_TABLE_SIZE 3 - -#define DISCOVERY_MODE_DISABLED 0 -#define DISCOVERY_MODE_ENABLED 1 - -#define MODE_P2P_TARGET 0 -#define MODE_P2P_INITIATOR 1 - -/* Properties values */ -#define PROPERTY_LLCP_LTO 0 -#define PROPERTY_LLCP_MIU 1 -#define PROPERTY_LLCP_WKS 2 -#define PROPERTY_LLCP_OPT 3 -#define PROPERTY_NFC_DISCOVERY_A 4 -#define PROPERTY_NFC_DISCOVERY_B 5 -#define PROPERTY_NFC_DISCOVERY_F 6 -#define PROPERTY_NFC_DISCOVERY_15693 7 -#define PROPERTY_NFC_DISCOVERY_NCFIP 8 - -/* Error codes */ -#define ERROR_BUFFER_TOO_SMALL -12 -#define ERROR_INSUFFICIENT_RESOURCES -9 - -/* Pre-defined card read/write state values. These must match the values in - * Ndef.java in the framework. - */ - -#define NDEF_UNKNOWN_TYPE -1 -#define NDEF_TYPE1_TAG 1 -#define NDEF_TYPE2_TAG 2 -#define NDEF_TYPE3_TAG 3 -#define NDEF_TYPE4_TAG 4 -#define NDEF_MIFARE_CLASSIC_TAG 101 -#define NDEF_ICODE_SLI_TAG 102 - -/* Pre-defined tag type values. These must match the values in - * Ndef.java in the framework. - */ - -#define NDEF_MODE_READ_ONLY 1 -#define NDEF_MODE_READ_WRITE 2 -#define NDEF_MODE_UNKNOWN 3 - - -/* Name strings for target types. These *must* match the values in TagTechnology.java */ -#define TARGET_TYPE_UNKNOWN -1 -#define TARGET_TYPE_ISO14443_3A 1 -#define TARGET_TYPE_ISO14443_3B 2 -#define TARGET_TYPE_ISO14443_4 3 -#define TARGET_TYPE_FELICA 4 -#define TARGET_TYPE_ISO15693 5 -#define TARGET_TYPE_NDEF 6 -#define TARGET_TYPE_NDEF_FORMATABLE 7 -#define TARGET_TYPE_MIFARE_CLASSIC 8 -#define TARGET_TYPE_MIFARE_UL 9 - -#define SMX_SECURE_ELEMENT_ID 11259375 - -/* Maximum byte length of an AID. */ -#define AID_MAXLEN 16 - -/* Utility macros for logging */ -#define GET_LEVEL(status) ((status)==NFCSTATUS_SUCCESS)?ANDROID_LOG_DEBUG:ANDROID_LOG_WARN - -#if 0 - #define LOG_CALLBACK(funcName, status) LOG_PRI(GET_LEVEL(status), LOG_TAG, "Callback: %s() - status=0x%04x[%s]", funcName, status, nfc_jni_get_status_name(status)); - #define TRACE(...) ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__) - #define TRACE_ENABLED 1 -#else - #define LOG_CALLBACK(...) - #define TRACE(...) - #define TRACE_ENABLED 0 -#endif - -struct nfc_jni_native_data -{ - /* Thread handle */ - pthread_t thread; - int running; - - /* Our VM */ - JavaVM *vm; - int env_version; - - /* Reference to the NFCManager instance */ - jobject manager; - - /* Cached objects */ - jobject cached_NfcTag; - jobject cached_P2pDevice; - - /* Target discovery configuration */ - int discovery_modes_state[DISCOVERY_MODE_TABLE_SIZE]; - phLibNfc_sADD_Cfg_t discovery_cfg; - phLibNfc_Registry_Info_t registry_info; - - /* Secure Element selected */ - int seId; - - /* LLCP params */ - int lto; - int miu; - int wks; - int opt; - - /* Tag detected */ - jobject tag; - - /* Lib Status */ - NFCSTATUS status; - - /* p2p modes */ - int p2p_initiator_modes; - int p2p_target_modes; - -}; - -typedef struct nfc_jni_native_monitor -{ - /* Mutex protecting native library against reentrance */ - pthread_mutex_t reentrance_mutex; - - /* Mutex protecting native library against concurrency */ - pthread_mutex_t concurrency_mutex; - - /* List used to track pending semaphores waiting for callback */ - struct listHead sem_list; - - /* List used to track incoming socket requests (and associated sync variables) */ - LIST_HEAD(, nfc_jni_listen_data) incoming_socket_head; - pthread_mutex_t incoming_socket_mutex; - pthread_cond_t incoming_socket_cond; - -} nfc_jni_native_monitor_t; - -typedef struct nfc_jni_callback_data -{ - /* Semaphore used to wait for callback */ - sem_t sem; - - /* Used to store the status sent by the callback */ - NFCSTATUS status; - - /* Used to provide a local context to the callback */ - void* pContext; - -} nfc_jni_callback_data_t; - -typedef struct nfc_jni_listen_data -{ - /* LLCP server socket receiving the connection request */ - phLibNfc_Handle pServerSocket; - - /* LLCP socket created from the connection request */ - phLibNfc_Handle pIncomingSocket; - - /* List entries */ - LIST_ENTRY(nfc_jni_listen_data) entries; - -} nfc_jni_listen_data_t; - -/* TODO: treat errors and add traces */ -#define REENTRANCE_LOCK() pthread_mutex_lock(&nfc_jni_get_monitor()->reentrance_mutex) -#define REENTRANCE_UNLOCK() pthread_mutex_unlock(&nfc_jni_get_monitor()->reentrance_mutex) -#define CONCURRENCY_LOCK() pthread_mutex_lock(&nfc_jni_get_monitor()->concurrency_mutex) -#define CONCURRENCY_UNLOCK() pthread_mutex_unlock(&nfc_jni_get_monitor()->concurrency_mutex) - -namespace android { - -extern JavaVM *vm; - -JNIEnv *nfc_get_env(); - -bool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext); -void nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData); -void nfc_cb_data_releaseAll(); - -const char* nfc_jni_get_status_name(NFCSTATUS status); -int nfc_jni_cache_object(JNIEnv *e, const char *clsname, - jobject *cached_obj); -struct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o); -struct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e); -nfc_jni_native_monitor_t* nfc_jni_init_monitor(void); -nfc_jni_native_monitor_t* nfc_jni_get_monitor(void); - -int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak); -void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList, - uint8_t count, jintArray* techList, jintArray* handleList, - jintArray* typeList); - -/* P2P */ -phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o); -jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o); - -/* TAG */ -jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o); -jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o); -phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o); -jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o); - -/* LLCP */ -phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o); - -int register_com_android_nfc_NativeNfcManager(JNIEnv *e); -int register_com_android_nfc_NativeNfcTag(JNIEnv *e); -int register_com_android_nfc_NativeP2pDevice(JNIEnv *e); -int register_com_android_nfc_NativeLlcpConnectionlessSocket(JNIEnv *e); -int register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv *e); -int register_com_android_nfc_NativeLlcpSocket(JNIEnv *e); -int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e); - -} // namespace android - -#endif diff --git a/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp b/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp deleted file mode 100644 index 188edb4..0000000 --- a/jni/com_android_nfc_NativeLlcpConnectionlessSocket.cpp +++ /dev/null @@ -1,253 +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 <semaphore.h> -#include <errno.h> - -#include "com_android_nfc.h" - -namespace android { - -/* - * Callbacks - */ - -static void nfc_jni_receive_callback(void* pContext, uint8_t ssap, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_receiveFrom_callback", status); - - if(status == NFCSTATUS_SUCCESS) - { - pCallbackData->pContext = (void*)ssap; - TRACE("RECEIVE UI_FRAME FROM SAP %d OK \n", ssap); - } - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_send_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_sendTo_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -/* -* Methods -*/ -static jboolean com_android_nfc_NativeLlcpConnectionlessSocket_doSendTo(JNIEnv *e, jobject o, jint nsap, jbyteArray data) -{ - NFCSTATUS ret; - struct timespec ts; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - phNfc_sData_t sSendBuffer = {NULL, 0}; - struct nfc_jni_callback_data cb_data; - jboolean result = JNI_FALSE; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - sSendBuffer.buffer = (uint8_t*)e->GetByteArrayElements(data, NULL); - sSendBuffer.length = (uint32_t)e->GetArrayLength(data); - - TRACE("phLibNfc_Llcp_SendTo()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_SendTo(hRemoteDevice, - hLlcpSocket, - nsap, - &sSendBuffer, - nfc_jni_send_callback, - (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Llcp_SendTo() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_SendTo() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - if (sSendBuffer.buffer != NULL) - { - e->ReleaseByteArrayElements(data, (jbyte*)sSendBuffer.buffer, JNI_ABORT); - } - nfc_cb_data_deinit(&cb_data); - return result; -} - -static jobject com_android_nfc_NativeLlcpConnectionlessSocket_doReceiveFrom(JNIEnv *e, jobject o, jint linkMiu) -{ - NFCSTATUS ret; - struct timespec ts; - uint8_t ssap; - jobject llcpPacket = NULL; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - phNfc_sData_t sReceiveBuffer; - jclass clsLlcpPacket; - jfieldID f; - jbyteArray receivedData = NULL; - struct nfc_jni_callback_data cb_data; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Create new LlcpPacket object */ - if(nfc_jni_cache_object(e,"com/android/nfc/LlcpPacket",&(llcpPacket)) == -1) - { - ALOGE("Find LlcpPacket class error"); - goto clean_and_return; - } - - /* Get NativeConnectionless class object */ - clsLlcpPacket = e->GetObjectClass(llcpPacket); - if(e->ExceptionCheck()) - { - ALOGE("Get Object class error"); - goto clean_and_return; - } - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - TRACE("phLibNfc_Llcp_RecvFrom(), Socket Handle = 0x%02x, Link LIU = %d", hLlcpSocket, linkMiu); - - sReceiveBuffer.buffer = (uint8_t*)malloc(linkMiu); - sReceiveBuffer.length = linkMiu; - - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_RecvFrom(hRemoteDevice, - hLlcpSocket, - &sReceiveBuffer, - nfc_jni_receive_callback, - &cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Llcp_RecvFrom() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_RecvFrom() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - ssap = (uint32_t)cb_data.pContext; - TRACE("Data Received From SSAP = %d\n, length = %d", ssap, sReceiveBuffer.length); - - /* Set Llcp Packet remote SAP */ - f = e->GetFieldID(clsLlcpPacket, "mRemoteSap", "I"); - e->SetIntField(llcpPacket, f,(jbyte)ssap); - - /* Set Llcp Packet Buffer */ - ALOGD("Set LlcpPacket Data Buffer\n"); - f = e->GetFieldID(clsLlcpPacket, "mDataBuffer", "[B"); - receivedData = e->NewByteArray(sReceiveBuffer.length); - e->SetByteArrayRegion(receivedData, 0, sReceiveBuffer.length,(jbyte *)sReceiveBuffer.buffer); - e->SetObjectField(llcpPacket, f, receivedData); - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - return llcpPacket; -} - -static jboolean com_android_nfc_NativeLlcpConnectionlessSocket_doClose(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - phLibNfc_Handle hLlcpSocket; - TRACE("Close Connectionless socket"); - - /* Retrieve socket handle */ - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - TRACE("phLibNfc_Llcp_Close()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); - REENTRANCE_UNLOCK(); - if(ret == NFCSTATUS_SUCCESS) - { - TRACE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return TRUE; - } - else - { - ALOGE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return FALSE; - } -} - - -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doSendTo", "(I[B)Z", (void *)com_android_nfc_NativeLlcpConnectionlessSocket_doSendTo}, - - {"doReceiveFrom", "(I)Lcom/android/nfc/LlcpPacket;", (void *)com_android_nfc_NativeLlcpConnectionlessSocket_doReceiveFrom}, - - {"doClose", "()Z", (void *)com_android_nfc_NativeLlcpConnectionlessSocket_doClose}, -}; - - -int register_com_android_nfc_NativeLlcpConnectionlessSocket(JNIEnv *e) -{ - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeLlcpConnectionlessSocket", - gMethods, NELEM(gMethods)); -} - -} // android namespace diff --git a/jni/com_android_nfc_NativeLlcpServiceSocket.cpp b/jni/com_android_nfc_NativeLlcpServiceSocket.cpp deleted file mode 100644 index 92de3e4..0000000 --- a/jni/com_android_nfc_NativeLlcpServiceSocket.cpp +++ /dev/null @@ -1,227 +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 <semaphore.h> -#include <errno.h> - -#include "com_android_nfc.h" - -namespace android { - -extern void nfc_jni_llcp_transport_socket_err_callback(void* pContext, - uint8_t nErrCode); -/* - * Callbacks - */ -static void nfc_jni_llcp_accept_socket_callback(void* pContext, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_llcp_accept_socket_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - - -/* - * Utils - */ - -static phLibNfc_Handle getIncomingSocket(nfc_jni_native_monitor_t * pMonitor, - phLibNfc_Handle hServerSocket) -{ - nfc_jni_listen_data_t * pListenData; - phLibNfc_Handle pIncomingSocket = NULL; - - /* Look for a pending incoming connection on the current server */ - LIST_FOREACH(pListenData, &pMonitor->incoming_socket_head, entries) - { - if (pListenData->pServerSocket == hServerSocket) - { - pIncomingSocket = pListenData->pIncomingSocket; - LIST_REMOVE(pListenData, entries); - free(pListenData); - break; - } - } - - return pIncomingSocket; -} - -/* - * Methods - */ -static jobject com_NativeLlcpServiceSocket_doAccept(JNIEnv *e, jobject o, jint miu, jint rw, jint linearBufferLength) -{ - NFCSTATUS ret = NFCSTATUS_SUCCESS; - struct timespec ts; - phLibNfc_Llcp_sSocketOptions_t sOptions; - phNfc_sData_t sWorkingBuffer; - jfieldID f; - jclass clsNativeLlcpSocket; - jobject clientSocket = NULL; - struct nfc_jni_callback_data cb_data; - phLibNfc_Handle hIncomingSocket, hServerSocket; - nfc_jni_native_monitor_t * pMonitor = nfc_jni_get_monitor(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Get server socket */ - hServerSocket = nfc_jni_get_nfc_socket_handle(e,o); - - /* Set socket options with the socket options of the service */ - sOptions.miu = miu; - sOptions.rw = rw; - - /* Allocate Working buffer length */ - sWorkingBuffer.buffer = (uint8_t*)malloc((miu*rw)+miu+linearBufferLength); - sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; - - while(cb_data.status != NFCSTATUS_SUCCESS) - { - /* Wait for tag Notification */ - pthread_mutex_lock(&pMonitor->incoming_socket_mutex); - while ((hIncomingSocket = getIncomingSocket(pMonitor, hServerSocket)) == NULL) { - pthread_cond_wait(&pMonitor->incoming_socket_cond, &pMonitor->incoming_socket_mutex); - } - pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); - - /* Accept the incomming socket */ - TRACE("phLibNfc_Llcp_Accept()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Accept( hIncomingSocket, - &sOptions, - &sWorkingBuffer, - nfc_jni_llcp_transport_socket_err_callback, - nfc_jni_llcp_accept_socket_callback, - (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING) - { - // NOTE: This may happen if link went down since incoming socket detected, then - // just drop it and start a new accept loop. - ALOGD("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - continue; - } - TRACE("phLibNfc_Llcp_Accept() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - /* NOTE: Do not generate an error if the accept failed to avoid error in server application */ - ALOGD("Failed to accept incoming socket 0x%04x[%s]", cb_data.status, nfc_jni_get_status_name(cb_data.status)); - } - } - - /* Create new LlcpSocket object */ - if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpSocket",&(clientSocket)) == -1) - { - ALOGD("LLCP Socket creation error"); - goto clean_and_return; - } - - /* Get NativeConnectionOriented class object */ - clsNativeLlcpSocket = e->GetObjectClass(clientSocket); - if(e->ExceptionCheck()) - { - ALOGD("LLCP Socket get class object error"); - goto clean_and_return; - } - - /* Set socket handle */ - f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); - e->SetIntField(clientSocket, f,(jint)hIncomingSocket); - - /* Set socket MIU */ - f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); - e->SetIntField(clientSocket, f,(jint)miu); - - /* Set socket RW */ - f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); - e->SetIntField(clientSocket, f,(jint)rw); - - TRACE("socket handle 0x%02x: MIU = %d, RW = %d\n",hIncomingSocket, miu, rw); - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - return clientSocket; -} - -static jboolean com_NativeLlcpServiceSocket_doClose(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - phLibNfc_Handle hLlcpSocket; - nfc_jni_native_monitor_t * pMonitor = nfc_jni_get_monitor(); - - TRACE("Close Service socket"); - - /* Retrieve socket handle */ - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - pthread_mutex_lock(&pMonitor->incoming_socket_mutex); - /* TODO: implement accept abort */ - pthread_cond_broadcast(&pMonitor->incoming_socket_cond); - pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); - - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); - REENTRANCE_UNLOCK(); - if(ret == NFCSTATUS_SUCCESS) - { - TRACE("Close Service socket OK"); - return TRUE; - } - else - { - ALOGD("Close Service socket KO"); - return FALSE; - } -} - - -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doAccept", "(III)Lcom/android/nfc/nxp/NativeLlcpSocket;", - (void *)com_NativeLlcpServiceSocket_doAccept}, - - {"doClose", "()Z", - (void *)com_NativeLlcpServiceSocket_doClose}, -}; - - -int register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv *e) -{ - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeLlcpServiceSocket", - gMethods, NELEM(gMethods)); -} - -} // namespace android diff --git a/jni/com_android_nfc_NativeLlcpSocket.cpp b/jni/com_android_nfc_NativeLlcpSocket.cpp deleted file mode 100644 index 0c0b830..0000000 --- a/jni/com_android_nfc_NativeLlcpSocket.cpp +++ /dev/null @@ -1,468 +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 <semaphore.h> -#include <errno.h> - -#include "com_android_nfc.h" - -namespace android { - -/* - * Callbacks - */ - -static void nfc_jni_disconnect_callback(void* pContext, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_disconnect_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - - -static void nfc_jni_connect_callback(void* pContext, uint8_t nErrCode, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_llcp_connect_callback", status); - - if(status == NFCSTATUS_SUCCESS) - { - TRACE("Socket connected\n"); - } - else - { - ALOGD("Socket not connected:"); - switch(nErrCode) - { - case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_ACTIVE: - { - ALOGD("> SAP NOT ACTIVE\n"); - }break; - - case PHFRINFC_LLCP_DM_OPCODE_SAP_NOT_FOUND: - { - ALOGD("> SAP NOT FOUND\n"); - }break; - - case PHFRINFC_LLCP_DM_OPCODE_CONNECT_REJECTED: - { - ALOGD("> CONNECT REJECTED\n"); - }break; - - case PHFRINFC_LLCP_DM_OPCODE_CONNECT_NOT_ACCEPTED: - { - ALOGD("> CONNECT NOT ACCEPTED\n"); - }break; - - case PHFRINFC_LLCP_DM_OPCODE_SOCKET_NOT_AVAILABLE: - { - ALOGD("> SOCKET NOT AVAILABLE\n"); - }break; - } - } - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - - - - -static void nfc_jni_receive_callback(void* pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_llcp_receive_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_send_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_llcp_send_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -/* - * Methods - */ -static jboolean com_android_nfc_NativeLlcpSocket_doConnect(JNIEnv *e, jobject o, jint nSap) -{ - NFCSTATUS ret; - struct timespec ts; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - struct nfc_jni_callback_data cb_data; - jboolean result = JNI_FALSE; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - TRACE("phLibNfc_Llcp_Connect(%d)",nSap); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Connect(hRemoteDevice, - hLlcpSocket, - nSap, - nfc_jni_connect_callback, - (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_Connect(%d) returned 0x%04x[%s]", nSap, ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGW("LLCP Connect request failed"); - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - return result; -} - -static jboolean com_android_nfc_NativeLlcpSocket_doConnectBy(JNIEnv *e, jobject o, jstring sn) -{ - NFCSTATUS ret; - struct timespec ts; - phNfc_sData_t serviceName = {0}; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - struct nfc_jni_callback_data cb_data; - jboolean result = JNI_FALSE; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Service socket */ - serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); - serviceName.length = (uint32_t)e->GetStringUTFLength(sn); - - TRACE("phLibNfc_Llcp_ConnectByUri()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_ConnectByUri(hRemoteDevice, - hLlcpSocket, - &serviceName, - nfc_jni_connect_callback, - (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_ConnectByUri() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - if (serviceName.buffer != NULL) { - e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); - } - nfc_cb_data_deinit(&cb_data); - return result; -} - -static jboolean com_android_nfc_NativeLlcpSocket_doClose(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - phLibNfc_Handle hLlcpSocket; - - /* Retrieve socket handle */ - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - TRACE("phLibNfc_Llcp_Close()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return FALSE; - } - TRACE("phLibNfc_Llcp_Close() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return TRUE; -} - -static jboolean com_android_nfc_NativeLlcpSocket_doSend(JNIEnv *e, jobject o, jbyteArray data) -{ - NFCSTATUS ret; - struct timespec ts; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - phNfc_sData_t sSendBuffer = {NULL, 0}; - struct nfc_jni_callback_data cb_data; - jboolean result = JNI_FALSE; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - sSendBuffer.buffer = (uint8_t*)e->GetByteArrayElements(data, NULL); - sSendBuffer.length = (uint32_t)e->GetArrayLength(data); - - TRACE("phLibNfc_Llcp_Send()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Send(hRemoteDevice, - hLlcpSocket, - &sSendBuffer, - nfc_jni_send_callback, - (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_Send() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - if (sSendBuffer.buffer != NULL) - { - e->ReleaseByteArrayElements(data, (jbyte*)sSendBuffer.buffer, JNI_ABORT); - } - nfc_cb_data_deinit(&cb_data); - return result; -} - -static jint com_android_nfc_NativeLlcpSocket_doReceive(JNIEnv *e, jobject o, jbyteArray buffer) -{ - NFCSTATUS ret; - struct timespec ts; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - phNfc_sData_t sReceiveBuffer = {NULL, 0}; - struct nfc_jni_callback_data cb_data; - jint result = -1; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - sReceiveBuffer.buffer = (uint8_t*)e->GetByteArrayElements(buffer, NULL); - sReceiveBuffer.length = (uint32_t)e->GetArrayLength(buffer); - - TRACE("phLibNfc_Llcp_Recv()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Recv(hRemoteDevice, - hLlcpSocket, - &sReceiveBuffer, - nfc_jni_receive_callback, - (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(ret == NFCSTATUS_PENDING) - { - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status == NFCSTATUS_SUCCESS) - { - result = sReceiveBuffer.length; - } - } - else if (ret == NFCSTATUS_SUCCESS) - { - result = sReceiveBuffer.length; - } - else - { - /* Return status should be either SUCCESS or PENDING */ - ALOGE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_Recv() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - -clean_and_return: - if (sReceiveBuffer.buffer != NULL) - { - e->ReleaseByteArrayElements(buffer, (jbyte*)sReceiveBuffer.buffer, 0); - } - nfc_cb_data_deinit(&cb_data); - return result; -} - -static jint com_android_nfc_NativeLlcpSocket_doGetRemoteSocketMIU(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - phLibNfc_Llcp_sSocketOptions_t remoteSocketOption; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(MIU)"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_SocketGetRemoteOptions(hRemoteDevice, - hLlcpSocket, - &remoteSocketOption); - REENTRANCE_UNLOCK(); - if(ret == NFCSTATUS_SUCCESS) - { - TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(MIU) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return remoteSocketOption.miu; - } - else - { - ALOGW("phLibNfc_Llcp_SocketGetRemoteOptions(MIU) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return 0; - } -} - -static jint com_android_nfc_NativeLlcpSocket_doGetRemoteSocketRW(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - phLibNfc_Handle hRemoteDevice; - phLibNfc_Handle hLlcpSocket; - phLibNfc_Llcp_sSocketOptions_t remoteSocketOption; - - /* Retrieve handles */ - hRemoteDevice = nfc_jni_get_p2p_device_handle(e,o); - hLlcpSocket = nfc_jni_get_nfc_socket_handle(e,o); - - TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(RW)"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_SocketGetRemoteOptions(hRemoteDevice, - hLlcpSocket, - &remoteSocketOption); - REENTRANCE_UNLOCK(); - if(ret == NFCSTATUS_SUCCESS) - { - TRACE("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return remoteSocketOption.rw; - } - else - { - ALOGW("phLibNfc_Llcp_SocketGetRemoteOptions(RW) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return 0; - } -} - - -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doConnect", "(I)Z", - (void *)com_android_nfc_NativeLlcpSocket_doConnect}, - - {"doConnectBy", "(Ljava/lang/String;)Z", - (void *)com_android_nfc_NativeLlcpSocket_doConnectBy}, - - {"doClose", "()Z", - (void *)com_android_nfc_NativeLlcpSocket_doClose}, - - {"doSend", "([B)Z", - (void *)com_android_nfc_NativeLlcpSocket_doSend}, - - {"doReceive", "([B)I", - (void *)com_android_nfc_NativeLlcpSocket_doReceive}, - - {"doGetRemoteSocketMiu", "()I", - (void *)com_android_nfc_NativeLlcpSocket_doGetRemoteSocketMIU}, - - {"doGetRemoteSocketRw", "()I", - (void *)com_android_nfc_NativeLlcpSocket_doGetRemoteSocketRW}, -}; - - -int register_com_android_nfc_NativeLlcpSocket(JNIEnv *e) -{ - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeLlcpSocket",gMethods, NELEM(gMethods)); -} - -} // namespace android diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp deleted file mode 100644 index e6da0fa..0000000 --- a/jni/com_android_nfc_NativeNfcManager.cpp +++ /dev/null @@ -1,2623 +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 <errno.h> -#include <pthread.h> -#include <semaphore.h> -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <sys/queue.h> -#include <hardware/hardware.h> -#include <hardware/nfc.h> -#include <cutils/properties.h> - -#include "com_android_nfc.h" - -#define ERROR_BUFFER_TOO_SMALL -12 -#define ERROR_INSUFFICIENT_RESOURCES -9 - -extern uint32_t libnfc_llc_error_count; - -static phLibNfc_sConfig_t gDrvCfg; -void *gHWRef; -static phNfc_sData_t gInputParam; -static phNfc_sData_t gOutputParam; - -uint8_t device_connected_flag; -static bool driverConfigured = FALSE; - -static phLibNfc_Handle hLlcpHandle; -static NFCSTATUS lastErrorStatus = NFCSTATUS_FAILED; -static phLibNfc_Llcp_eLinkStatus_t g_eLinkStatus = phFriNfc_LlcpMac_eLinkDefault; - -static jmethodID cached_NfcManager_notifyNdefMessageListeners; -static jmethodID cached_NfcManager_notifyTransactionListeners; -static jmethodID cached_NfcManager_notifyLlcpLinkActivation; -static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated; -static jmethodID cached_NfcManager_notifyTargetDeselected; - -static jmethodID cached_NfcManager_notifySeFieldActivated; -static jmethodID cached_NfcManager_notifySeFieldDeactivated; - -static jmethodID cached_NfcManager_notifySeApduReceived; -static jmethodID cached_NfcManager_notifySeMifareAccess; -static jmethodID cached_NfcManager_notifySeEmvCardRemoval; - -namespace android { - -phLibNfc_Handle storedHandle = 0; - -struct nfc_jni_native_data *exported_nat = NULL; - -/* Internal functions declaration */ -static void *nfc_jni_client_thread(void *arg); -static void nfc_jni_init_callback(void *pContext, NFCSTATUS status); -static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status); -static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status); -static void nfc_jni_se_set_mode_callback(void *context, - phLibNfc_Handle handle, NFCSTATUS status); -static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status); -static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume); -static void nfc_jni_Discovery_notification_callback(void *pContext, - phLibNfc_RemoteDevList_t *psRemoteDevList, - uint8_t uNofRemoteDev, NFCSTATUS status); -static void nfc_jni_transaction_callback(void *context, - phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle, - phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status); -static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock); - -/* - * Deferred callback called when client thread must be exited - */ -static void client_kill_deferred_call(void* arg) -{ - struct nfc_jni_native_data *nat = (struct nfc_jni_native_data *)arg; - - nat->running = FALSE; -} - -static void kill_client(nfc_jni_native_data *nat) -{ - phDal4Nfc_Message_Wrapper_t wrapper; - phLibNfc_DeferredCall_t *pMsg; - - usleep(50000); - - ALOGD("Terminating client thread..."); - - pMsg = (phLibNfc_DeferredCall_t*)malloc(sizeof(phLibNfc_DeferredCall_t)); - pMsg->pCallback = client_kill_deferred_call; - pMsg->pParameter = (void*)nat; - - wrapper.msg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG; - wrapper.msg.pMsgData = pMsg; - wrapper.msg.Size = sizeof(phLibNfc_DeferredCall_t); - - phDal4Nfc_msgsnd(gDrvCfg.nClientId, (struct msgbuf *)&wrapper, sizeof(phLibNfc_Message_t), 0); -} - -static void nfc_jni_ioctl_callback(void *pContext, phNfc_sData_t *pOutput, NFCSTATUS status) { - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_ioctl_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_deinit_download_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_deinit_download_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static int nfc_jni_download_locked(struct nfc_jni_native_data *nat, uint8_t update) -{ - uint8_t OutputBuffer[1]; - uint8_t InputBuffer[1]; - struct timespec ts; - NFCSTATUS status = NFCSTATUS_FAILED; - phLibNfc_StackCapabilities_t caps; - struct nfc_jni_callback_data cb_data; - bool result; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - if(update) - { - //deinit - TRACE("phLibNfc_Mgt_DeInitialize() (download)"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_download_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if (status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Mgt_DeInitialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - } - - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 5; - - /* Wait for callback response */ - if(sem_timedwait(&cb_data.sem, &ts)) - { - ALOGW("Deinitialization timed out (download)"); - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGW("Deinitialization FAILED (download)"); - } - TRACE("Deinitialization SUCCESS (download)"); - } - - result = performDownload(nat, false); - - if (!result) { - status = NFCSTATUS_FAILED; - goto clean_and_return; - } - - TRACE("phLibNfc_Mgt_Initialize()"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Mgt_Initialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - status = NFCSTATUS_FAILED; - goto clean_and_return; - } - - /* Initialization Status */ - if(cb_data.status != NFCSTATUS_SUCCESS) - { - status = cb_data.status; - goto clean_and_return; - } - - /* ====== CAPABILITIES ======= */ - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat); - REENTRANCE_UNLOCK(); - if (status != NFCSTATUS_SUCCESS) - { - ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - } - else - { - ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d", - caps.psDevCapabilities.hal_version, - caps.psDevCapabilities.fw_version, - caps.psDevCapabilities.hw_version, - caps.psDevCapabilities.model_id, - caps.psDevCapabilities.hci_version, - caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1], - caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2], - caps.psDevCapabilities.firmware_update_info); - } - - /*Download is successful*/ - status = NFCSTATUS_SUCCESS; - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - return status; -} - -static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat) -{ - char value[PROPERTY_VALUE_MAX]; - int result = FALSE; - NFCSTATUS status; - - /* ====== CONFIGURE DRIVER ======= */ - /* Configure hardware link */ - gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600); - - TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x)", gDrvCfg.nClientId); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef); - REENTRANCE_UNLOCK(); - if(status == NFCSTATUS_ALREADY_INITIALISED) { - ALOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - } - else if(status != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0) - { - ALOGE("pthread_create failed"); - goto clean_and_return; - } - - driverConfigured = TRUE; - -clean_and_return: - return result; -} - -static int nfc_jni_unconfigure_driver(struct nfc_jni_native_data *nat) -{ - int result = FALSE; - NFCSTATUS status; - - /* Unconfigure driver */ - TRACE("phLibNfc_Mgt_UnConfigureDriver()"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_UnConfigureDriver(gHWRef); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Mgt_UnConfigureDriver() returned error 0x%04x[%s] -- this should never happen", status, nfc_jni_get_status_name( status)); - } - else - { - ALOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - result = TRUE; - } - - driverConfigured = FALSE; - - return result; -} - -/* Initialization function */ -static int nfc_jni_initialize(struct nfc_jni_native_data *nat) { - struct timespec ts; - uint8_t resp[16]; - NFCSTATUS status; - phLibNfc_StackCapabilities_t caps; - phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; - uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0; - phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo; - struct nfc_jni_callback_data cb_data; - uint8_t firmware_status; - uint8_t update = TRUE; - int result = JNI_FALSE; - const hw_module_t* hw_module; - nfc_pn544_device_t* pn544_dev = NULL; - int ret = 0; - ALOGD("Start Initialization\n"); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - /* Get EEPROM values and device port from product-specific settings */ - ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module); - if (ret) { - ALOGE("hw_get_module() failed."); - goto clean_and_return; - } - ret = nfc_pn544_open(hw_module, &pn544_dev); - if (ret) { - ALOGE("Could not open pn544 hw_module."); - goto clean_and_return; - } - if (pn544_dev->num_eeprom_settings == 0 || pn544_dev->eeprom_settings == NULL) { - ALOGE("Could not load EEPROM settings"); - goto clean_and_return; - } - - /* Reset device connected handle */ - device_connected_flag = 0; - - /* Reset stored handle */ - storedHandle = 0; - - /* Initialize Driver */ - if(!driverConfigured) - { - nfc_jni_configure_driver(nat); - } - - /* ====== INITIALIZE ======= */ - - TRACE("phLibNfc_Mgt_Initialize()"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - update = FALSE; - goto force_download; - } - TRACE("phLibNfc_Mgt_Initialize returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - /* Initialization Status */ - if(cb_data.status != NFCSTATUS_SUCCESS) - { - update = FALSE; - goto force_download; - } - - /* ====== CAPABILITIES ======= */ - - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat); - REENTRANCE_UNLOCK(); - if (status != NFCSTATUS_SUCCESS) - { - ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - } - else - { - ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d", - caps.psDevCapabilities.hal_version, - caps.psDevCapabilities.fw_version, - caps.psDevCapabilities.hw_version, - caps.psDevCapabilities.model_id, - caps.psDevCapabilities.hci_version, - caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1], - caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2], - caps.psDevCapabilities.firmware_update_info); - } - - /* ====== FIRMWARE VERSION ======= */ - if(caps.psDevCapabilities.firmware_update_info) - { -force_download: - for (i=0; i<3; i++) - { - TRACE("Firmware version not UpToDate"); - status = nfc_jni_download_locked(nat, update); - if(status == NFCSTATUS_SUCCESS) - { - ALOGI("Firmware update SUCCESS"); - break; - } - ALOGW("Firmware update FAILED"); - update = FALSE; - } - if(i>=3) - { - ALOGE("Unable to update firmware, giving up"); - goto clean_and_return; - } - } - else - { - TRACE("Firmware version UpToDate"); - } - /* ====== EEPROM SETTINGS ======= */ - - // Update EEPROM settings - TRACE("****** START EEPROM SETTINGS UPDATE ******"); - for (i = 0; i < pn544_dev->num_eeprom_settings; i++) - { - char eeprom_property[PROPERTY_KEY_MAX]; - char eeprom_value[PROPERTY_VALUE_MAX]; - uint8_t* eeprom_base = &(pn544_dev->eeprom_settings[i*4]); - TRACE("> EEPROM SETTING: %d", i); - - // Check for override of this EEPROM value in properties - snprintf(eeprom_property, sizeof(eeprom_property), "debug.nfc.eeprom.%02X%02X", - eeprom_base[1], eeprom_base[2]); - TRACE(">> Checking property: %s", eeprom_property); - if (property_get(eeprom_property, eeprom_value, "") == 2) { - int eeprom_value_num = (int)strtol(eeprom_value, (char**)NULL, 16); - ALOGD(">> Override EEPROM addr 0x%02X%02X with value %02X", - eeprom_base[1], eeprom_base[2], eeprom_value_num); - eeprom_base[3] = eeprom_value_num; - } - - TRACE(">> Addr: 0x%02X%02X set to: 0x%02X", eeprom_base[1], eeprom_base[2], - eeprom_base[3]); - gInputParam.buffer = eeprom_base; - gInputParam.length = 0x04; - gOutputParam.buffer = resp; - - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_IoCtl(gHWRef, NFC_MEM_WRITE, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if (status != NFCSTATUS_PENDING) { - ALOGE("phLibNfc_Mgt_IoCtl() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - /* Initialization Status */ - if (cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - } - TRACE("****** ALL EEPROM SETTINGS UPDATED ******"); - - /* ====== SECURE ELEMENTS ======= */ - - REENTRANCE_LOCK(); - ALOGD("phLibNfc_SE_GetSecureElementList()"); - status = phLibNfc_SE_GetSecureElementList(SE_List, &No_SE); - REENTRANCE_UNLOCK(); - if (status != NFCSTATUS_SUCCESS) - { - ALOGD("phLibNfc_SE_GetSecureElementList(): Error"); - goto clean_and_return; - } - - ALOGD("\n> Number of Secure Element(s) : %d\n", No_SE); - /* Display Secure Element information */ - for (i = 0; i < No_SE; i++) - { - if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) { - ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected, handle=%p", (void*)SE_List[i].hSecureElement); - } else if (SE_List[i].eSE_Type == phLibNfc_SE_Type_UICC) { - ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected, handle=%p", (void*)SE_List[i].hSecureElement); - } - - /* Set SE mode - Off */ - REENTRANCE_LOCK(); - status = phLibNfc_SE_SetMode(SE_List[i].hSecureElement, - phLibNfc_SE_ActModeOff, nfc_jni_se_set_mode_callback, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - if (status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, - nfc_jni_get_status_name(status)); - goto clean_and_return; - } - ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status, - nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - } - - /* ====== LLCP ======= */ - - /* LLCP Params */ - TRACE("****** NFC Config Mode NFCIP1 - LLCP ******"); - LlcpConfigInfo.miu = nat->miu; - LlcpConfigInfo.lto = nat->lto; - LlcpConfigInfo.wks = nat->wks; - LlcpConfigInfo.option = nat->opt; - - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_SetLlcp_ConfigParams(&LlcpConfigInfo, - nfc_jni_llcpcfg_callback, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status, - nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status, - nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - /* ===== DISCOVERY ==== */ - nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator - nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target - nat->discovery_cfg.Duration = 300000; /* in ms */ - nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; - - /* Register for the card emulation mode */ - REENTRANCE_LOCK(); - ret = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",ret); - goto clean_and_return; - } - TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", ret); - - - /* ====== END ======= */ - - ALOGI("NFC Initialized"); - - result = TRUE; - -clean_and_return: - if (result != TRUE) - { - if(nat) - { - kill_client(nat); - } - } - if (pn544_dev != NULL) { - nfc_pn544_close(pn544_dev); - } - nfc_cb_data_deinit(&cb_data); - - return result; -} - -static int is_user_build() { - char value[PROPERTY_VALUE_MAX]; - property_get("ro.build.type", value, ""); - return !strncmp("user", value, PROPERTY_VALUE_MAX); -} - -/* - * Last-chance fallback when there is no clean way to recover - * Performs a software reset - */ -void emergency_recovery(struct nfc_jni_native_data *nat) { - if (!is_user_build()) { - ALOGE("emergency_recovery: force restart of NFC service"); - } else { - // dont recover immediately, so we can debug - unsigned int t; - for (t=1; t < 1000000; t <<= 1) { - ALOGE("emergency_recovery: NFC stack dead-locked"); - sleep(t); - } - } - phLibNfc_Mgt_Recovery(); - abort(); // force a noisy crash -} - -void nfc_jni_reset_timeout_values() -{ - REENTRANCE_LOCK(); - phLibNfc_SetIsoXchgTimeout(NXP_ISO_XCHG_TIMEOUT); - phLibNfc_SetHciTimeout(NXP_NFC_HCI_TIMEOUT); - phLibNfc_SetFelicaTimeout(NXP_FELICA_XCHG_TIMEOUT); - phLibNfc_SetMifareRawTimeout(NXP_MIFARE_XCHG_TIMEOUT); - REENTRANCE_UNLOCK(); -} - -/* - * Restart the polling loop when unable to perform disconnect - */ -void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat) -{ - nfc_jni_start_discovery_locked(nat, true); -} - - /* - * Utility to recover UID from target infos - */ -static phNfc_sData_t get_target_uid(phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo) -{ - phNfc_sData_t uid; - - switch(psRemoteDevInfo->RemDevType) - { - case phNfc_eISO14443_A_PICC: - case phNfc_eISO14443_4A_PICC: - case phNfc_eISO14443_3A_PICC: - case phNfc_eMifare_PICC: - uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid; - uid.length = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength; - break; - case phNfc_eISO14443_B_PICC: - case phNfc_eISO14443_4B_PICC: - uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi; - uid.length = sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi); - break; - case phNfc_eFelica_PICC: - uid.buffer = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm; - uid.length = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength; - break; - case phNfc_eJewel_PICC: - uid.buffer = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid; - uid.length = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength; - break; - case phNfc_eISO15693_PICC: - uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid; - uid.length = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength; - break; - case phNfc_eNfcIP1_Target: - case phNfc_eNfcIP1_Initiator: - uid.buffer = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID; - uid.length = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID_Length; - break; - default: - uid.buffer = NULL; - uid.length = 0; - break; - } - - return uid; -} - -/* - * NFC stack message processing - */ -static void *nfc_jni_client_thread(void *arg) -{ - struct nfc_jni_native_data *nat; - JNIEnv *e; - JavaVMAttachArgs thread_args; - phDal4Nfc_Message_Wrapper_t wrapper; - - nat = (struct nfc_jni_native_data *)arg; - - thread_args.name = "NFC Message Loop"; - thread_args.version = nat->env_version; - thread_args.group = NULL; - - nat->vm->AttachCurrentThread(&e, &thread_args); - pthread_setname_np(pthread_self(), "message"); - - TRACE("NFC client started"); - nat->running = TRUE; - while(nat->running == TRUE) - { - /* Fetch next message from the NFC stack message queue */ - if(phDal4Nfc_msgrcv(gDrvCfg.nClientId, (void *)&wrapper, - sizeof(phLibNfc_Message_t), 0, 0) == -1) - { - ALOGE("NFC client received bad message"); - continue; - } - - switch(wrapper.msg.eMsgType) - { - case PH_LIBNFC_DEFERREDCALL_MSG: - { - phLibNfc_DeferredCall_t *msg = - (phLibNfc_DeferredCall_t *)(wrapper.msg.pMsgData); - - REENTRANCE_LOCK(); - msg->pCallback(msg->pParameter); - REENTRANCE_UNLOCK(); - - break; - } - } - } - TRACE("NFC client stopped"); - - nat->vm->DetachCurrentThread(); - - return NULL; -} - -extern uint8_t nfc_jni_is_ndef; -extern uint8_t *nfc_jni_ndef_buf; -extern uint32_t nfc_jni_ndef_buf_len; - -static phLibNfc_sNfcIPCfg_t nfc_jni_nfcip1_cfg = -{ - 3, - { 0x46, 0x66, 0x6D } -}; - -/* - * Callbacks - */ - -/* P2P - LLCP callbacks */ -static void nfc_jni_llcp_linkStatus_callback(void *pContext, - phFriNfc_LlcpMac_eLinkStatus_t eLinkStatus) -{ - phFriNfc_Llcp_sLinkParameters_t sLinkParams; - JNIEnv *e; - NFCSTATUS status; - - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - struct nfc_jni_native_data *nat = (nfc_jni_native_data *)pContextData->pContext; - - nfc_jni_listen_data_t * pListenData = NULL; - nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor(); - - TRACE("Callback: nfc_jni_llcp_linkStatus_callback()"); - - nat->vm->GetEnv( (void **)&e, nat->env_version); - - /* Update link status */ - g_eLinkStatus = eLinkStatus; - - if(eLinkStatus == phFriNfc_LlcpMac_eLinkActivated) - { - REENTRANCE_LOCK(); - status = phLibNfc_Llcp_GetRemoteInfo(hLlcpHandle, &sLinkParams); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_SUCCESS) - { - ALOGW("GetRemote Info failded - Status = %02x",status); - } - else - { - ALOGI("LLCP Link activated (LTO=%d, MIU=%d, OPTION=0x%02x, WKS=0x%02x)",sLinkParams.lto, - sLinkParams.miu, - sLinkParams.option, - sLinkParams.wks); - device_connected_flag = 1; - } - } - else if(eLinkStatus == phFriNfc_LlcpMac_eLinkDeactivated) - { - ALOGI("LLCP Link deactivated"); - free(pContextData); - /* Reset device connected flag */ - device_connected_flag = 0; - - /* Reset incoming socket list */ - while (!LIST_EMPTY(&pMonitor->incoming_socket_head)) - { - pListenData = LIST_FIRST(&pMonitor->incoming_socket_head); - LIST_REMOVE(pListenData, entries); - free(pListenData); - } - - /* Notify manager that the LLCP is lost or deactivated */ - e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkDeactivated, nat->tag); - if(e->ExceptionCheck()) - { - ALOGE("Exception occured"); - kill_client(nat); - } - } -} - -static void nfc_jni_checkLlcp_callback(void *context, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)context; - - LOG_CALLBACK("nfc_jni_checkLlcp_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_llcpcfg_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_llcp_transport_listen_socket_callback(void *pContext, - phLibNfc_Handle hIncomingSocket) -{ - phLibNfc_Handle hServiceSocket = (phLibNfc_Handle)pContext; - nfc_jni_listen_data_t * pListenData = NULL; - nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor(); - - TRACE("nfc_jni_llcp_transport_listen_socket_callback socket handle = %p", (void*)hIncomingSocket); - - pthread_mutex_lock(&pMonitor->incoming_socket_mutex); - - /* Store the connection request */ - pListenData = (nfc_jni_listen_data_t*)malloc(sizeof(nfc_jni_listen_data_t)); - if (pListenData == NULL) - { - ALOGE("Failed to create structure to handle incoming LLCP connection request"); - goto clean_and_return; - } - pListenData->pServerSocket = hServiceSocket; - pListenData->pIncomingSocket = hIncomingSocket; - LIST_INSERT_HEAD(&pMonitor->incoming_socket_head, pListenData, entries); - - /* Signal pending accept operations that the list is updated */ - pthread_cond_broadcast(&pMonitor->incoming_socket_cond); - -clean_and_return: - pthread_mutex_unlock(&pMonitor->incoming_socket_mutex); -} - -void nfc_jni_llcp_transport_socket_err_callback(void* pContext, - uint8_t nErrCode) -{ - PHNFC_UNUSED_VARIABLE(pContext); - - TRACE("Callback: nfc_jni_llcp_transport_socket_err_callback()"); - - if(nErrCode == PHFRINFC_LLCP_ERR_FRAME_REJECTED) - { - ALOGW("Frame Rejected - Disconnected"); - } - else if(nErrCode == PHFRINFC_LLCP_ERR_DISCONNECTED) - { - ALOGD("Socket Disconnected"); - } -} - - -static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("nfc_jni_discover_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -static uint8_t find_preferred_target(phLibNfc_RemoteDevList_t *psRemoteDevList, - uint8_t uNoOfRemoteDev) -{ - // Always prefer p2p targets over other targets. Otherwise, select the first target - // reported. - uint8_t preferred_index = 0; - for (uint8_t i = 0; i < uNoOfRemoteDev; i++) { - if((psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) - || (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Target)) { - preferred_index = i; - } - } - return preferred_index; -} - -static void nfc_jni_Discovery_notification_callback(void *pContext, - phLibNfc_RemoteDevList_t *psRemoteDevList, - uint8_t uNofRemoteDev, NFCSTATUS status) -{ - JNIEnv *e; - NFCSTATUS ret; - jclass tag_cls = NULL; - jobject target_array; - jobject tag; - jmethodID ctor; - jfieldID f; - const char * typeName; - jbyteArray tagUid; - jbyteArray generalBytes = NULL; - struct nfc_jni_native_data *nat; - struct timespec ts; - phNfc_sData_t data; - int i; - int target_index = 0; // Target that will be reported (if multiple can be >0) - - nat = (struct nfc_jni_native_data *)pContext; - - nat->vm->GetEnv( (void **)&e, nat->env_version); - - if(status == NFCSTATUS_DESELECTED) - { - LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status); - - /* Notify manager that a target was deselected */ - e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected); - if(e->ExceptionCheck()) - { - ALOGE("Exception occured"); - kill_client(nat); - } - } - else - { - LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status); - TRACE("Discovered %d tags", uNofRemoteDev); - - target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev); - - /* Reset device connected flag */ - device_connected_flag = 1; - phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo; - phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev; - if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) - || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) - { - - tag_cls = e->GetObjectClass(nat->cached_P2pDevice); - if(e->ExceptionCheck()) - { - ALOGE("Get Object Class Error"); - kill_client(nat); - return; - } - - /* New target instance */ - ctor = e->GetMethodID(tag_cls, "<init>", "()V"); - tag = e->NewObject(tag_cls, ctor); - - /* Set P2P Target mode */ - f = e->GetFieldID(tag_cls, "mMode", "I"); - - if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) - { - ALOGD("Discovered P2P Initiator"); - e->SetIntField(tag, f, (jint)MODE_P2P_INITIATOR); - } - else - { - ALOGD("Discovered P2P Target"); - e->SetIntField(tag, f, (jint)MODE_P2P_TARGET); - } - - if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) - { - /* Set General Bytes */ - f = e->GetFieldID(tag_cls, "mGeneralBytes", "[B"); - - TRACE("General Bytes length ="); - for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++) - { - ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]); - } - - generalBytes = e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length); - - e->SetByteArrayRegion(generalBytes, 0, - remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length, - (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo); - - e->SetObjectField(tag, f, generalBytes); - } - - /* Set tag handle */ - f = e->GetFieldID(tag_cls, "mHandle", "I"); - e->SetIntField(tag, f,(jint)remDevHandle); - TRACE("Target handle = 0x%08x",remDevHandle); - } - else - { - tag_cls = e->GetObjectClass(nat->cached_NfcTag); - if(e->ExceptionCheck()) - { - kill_client(nat); - return; - } - - /* New tag instance */ - ctor = e->GetMethodID(tag_cls, "<init>", "()V"); - tag = e->NewObject(tag_cls, ctor); - - bool multi_protocol = false; - - if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) - { - TRACE("Multiple Protocol TAG detected\n"); - multi_protocol = true; - } - - /* Set tag UID */ - f = e->GetFieldID(tag_cls, "mUid", "[B"); - data = get_target_uid(remDevInfo); - tagUid = e->NewByteArray(data.length); - if(data.length > 0) - { - e->SetByteArrayRegion(tagUid, 0, data.length, (jbyte *)data.buffer); - } - e->SetObjectField(tag, f, tagUid); - - /* Generate technology list */ - jintArray techList; - jintArray handleList; - jintArray typeList; - nfc_jni_get_technology_tree(e, psRemoteDevList, - multi_protocol ? uNofRemoteDev : 1, - &techList, &handleList, &typeList); - - /* Push the technology list into the java object */ - f = e->GetFieldID(tag_cls, "mTechList", "[I"); - e->SetObjectField(tag, f, techList); - - f = e->GetFieldID(tag_cls, "mTechHandles", "[I"); - e->SetObjectField(tag, f, handleList); - - f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I"); - e->SetObjectField(tag, f, typeList); - - f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I"); - e->SetIntField(tag, f,(jint)-1); - - f = e->GetFieldID(tag_cls, "mConnectedHandle", "I"); - e->SetIntField(tag, f,(jint)-1); - } - - storedHandle = remDevHandle; - if (nat->tag != NULL) { - e->DeleteGlobalRef(nat->tag); - } - nat->tag = e->NewGlobalRef(tag); - - /* Notify the service */ - TRACE("Notify Nfc Service"); - if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator) - || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target)) - { - /* Store the hanlde of the P2P device */ - hLlcpHandle = remDevHandle; - - /* Notify manager that new a P2P device was found */ - e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag); - if(e->ExceptionCheck()) - { - ALOGE("Exception occured"); - kill_client(nat); - } - } - else - { - /* Notify manager that new a tag was found */ - e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag); - if(e->ExceptionCheck()) - { - ALOGE("Exception occured"); - kill_client(nat); - } - } - e->DeleteLocalRef(tag); - } -} - -static void nfc_jni_init_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("nfc_jni_init_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("nfc_jni_deinit_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -/* Set Secure Element mode callback*/ -static void nfc_jni_smartMX_setModeCb (void* pContext, - phLibNfc_Handle hSecureElement, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -/* Card Emulation callback */ -static void nfc_jni_transaction_callback(void *context, - phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle, - phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status) -{ - JNIEnv *e; - jobject tmp_array = NULL; - jobject mifare_block = NULL; - struct nfc_jni_native_data *nat; - phNfc_sData_t *aid; - phNfc_sData_t *mifare_command; - struct nfc_jni_callback_data *pCallbackData; - int i=0; - - LOG_CALLBACK("nfc_jni_transaction_callback", status); - - nat = (struct nfc_jni_native_data *)context; - - nat->vm->GetEnv( (void **)&e, nat->env_version); - - if(status == NFCSTATUS_SUCCESS) - { - switch(evt_type) - { - case phLibNfc_eSE_EvtStartTransaction: - { - TRACE("> SE EVT_START_TRANSACTION"); - if(evt_info->UiccEvtInfo.aid.length <= AID_MAXLEN) - { - aid = &(evt_info->UiccEvtInfo.aid); - - ALOGD("> AID DETECTED"); - - if(aid != NULL) - { - if (TRACE_ENABLED == 1) { - char aid_str[AID_MAXLEN * 2 + 1]; - aid_str[0] = '\0'; - for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) { - snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]); - } - ALOGD("> AID: %s", aid_str); - } - tmp_array = e->NewByteArray(aid->length); - if (tmp_array == NULL) - { - goto error; - } - - e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer); - if(e->ExceptionCheck()) - { - goto error; - } - } - else - { - goto error; - } - - TRACE("Notify Nfc Service"); - /* Notify manager that a new event occurred on a SE */ - e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array); - if(e->ExceptionCheck()) - { - goto error; - } - } - else - { - ALOGD("> NO AID DETECTED"); - } - }break; - - case phLibNfc_eSE_EvtApduReceived: - { - phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid); - TRACE("> SE EVT_APDU_RECEIVED"); - - if (apdu != NULL) { - TRACE(" APDU length=%d", apdu->length); - tmp_array = e->NewByteArray(apdu->length); - if (tmp_array == NULL) { - goto error; - } - e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer); - if (e->ExceptionCheck()) { - goto error; - } - } else { - TRACE(" APDU EMPTY"); - } - - TRACE("Notify Nfc Service"); - e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array); - }break; - - case phLibNfc_eSE_EvtCardRemoval: - { - TRACE("> SE EVT_EMV_CARD_REMOVAL"); - TRACE("Notify Nfc Service"); - e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval); - }break; - - case phLibNfc_eSE_EvtMifareAccess: - { - TRACE("> SE EVT_MIFARE_ACCESS"); - mifare_command = &(evt_info->UiccEvtInfo.aid); - TRACE("> MIFARE Block: %d",mifare_command->buffer[1]); - tmp_array = e->NewByteArray(2); - if (tmp_array == NULL) - { - goto error; - } - - e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer); - if(e->ExceptionCheck()) - { - goto error; - } - TRACE("Notify Nfc Service"); - e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block); - }break; - - case phLibNfc_eSE_EvtFieldOn: - { - TRACE("> SE EVT_FIELD_ON"); - TRACE("Notify Nfc Service"); - e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldActivated); - }break; - - case phLibNfc_eSE_EvtFieldOff: - { - TRACE("> SE EVT_FIELD_OFF"); - TRACE("Notify Nfc Service"); - e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldDeactivated); - }break; - - default: - { - TRACE("Unknown SE event"); - }break; - } - } - else - { - ALOGE("SE transaction notification error"); - goto error; - } - - /* Function finished, now clean and return */ - goto clean_and_return; - - error: - /* In case of error, just discard the notification */ - ALOGE("Failed to send SE transaction notification"); - e->ExceptionClear(); - - clean_and_return: - if(tmp_array != NULL) - { - e->DeleteLocalRef(tmp_array); - } -} - -static void nfc_jni_se_set_mode_callback(void *pContext, - phLibNfc_Handle handle, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("nfc_jni_se_set_mode_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -/* - * NFCManager methods - */ - -static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume) -{ - NFCSTATUS ret; - struct nfc_jni_callback_data cb_data; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - /* Reset the PN544 ISO XCHG / sw watchdog timeouts */ - nfc_jni_reset_timeout_values(); - - /* Reload the p2p modes */ - nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes; //initiator - nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes; //target - nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE; - - /* Reset device connected flag */ - device_connected_flag = 0; - - /* Start Polling loop */ - TRACE("****** Start NFC Discovery ******"); - REENTRANCE_LOCK(); - ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG, - nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", - nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", - nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret); - - if(ret != NFCSTATUS_PENDING) - { - emergency_recovery(nat); - goto clean_and_return; - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - -clean_and_return: - nfc_cb_data_deinit(&cb_data); -} - -static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat) -{ - phLibNfc_sADD_Cfg_t discovery_cfg; - NFCSTATUS ret; - struct nfc_jni_callback_data cb_data; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - discovery_cfg.PollDevInfo.PollEnabled = 0; - discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode; - discovery_cfg.NfcIP_Target_Mode = 0; - discovery_cfg.NfcIP_Tgt_Disable = TRUE; - - /* Start Polling loop */ - TRACE("****** Stop NFC Discovery ******"); - REENTRANCE_LOCK(); - ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n", - discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"", - discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"", - discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"", - discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"", - discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"", - discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"", - discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"", - discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret); - - if(ret != NFCSTATUS_PENDING) - { - emergency_recovery(nat); - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - -clean_and_return: - nfc_cb_data_deinit(&cb_data); -} - - -static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o) -{ - struct nfc_jni_native_data *nat; - - CONCURRENCY_LOCK(); - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - nfc_jni_stop_discovery_locked(nat); - - CONCURRENCY_UNLOCK(); - -} - -static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) { - NFCSTATUS ret; - struct nfc_jni_native_data *nat; - - CONCURRENCY_LOCK(); - - nat = nfc_jni_get_nat(e, o); - - /* Register callback for remote device notifications. - * Must re-register every time we turn on discovery, since other operations - * (such as opening the Secure Element) can change the remote device - * notification callback*/ - REENTRANCE_LOCK(); - ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n", - nat->registry_info.Jewel==TRUE?"J":"", - nat->registry_info.MifareUL==TRUE?"UL":"", - nat->registry_info.MifareStd==TRUE?"Mi":"", - nat->registry_info.Felica==TRUE?"F":"", - nat->registry_info.ISO14443_4A==TRUE?"4A":"", - nat->registry_info.ISO14443_4B==TRUE?"4B":"", - nat->registry_info.NFC==TRUE?"P2P":"", - nat->registry_info.ISO15693==TRUE?"R":"", ret); - - nfc_jni_start_discovery_locked(nat, false); -clean_and_return: - CONCURRENCY_UNLOCK(); -} - -static void com_android_nfc_NfcManager_doResetTimeouts( JNIEnv *e, jobject o) { - CONCURRENCY_LOCK(); - nfc_jni_reset_timeout_values(); - CONCURRENCY_UNLOCK(); -} - -static void setFelicaTimeout(jint timeout) { - // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms. - // It can be set to 0 to disable the timeout altogether, in which case we - // use the sw watchdog as a fallback. - if (timeout <= 255) { - phLibNfc_SetFelicaTimeout(timeout); - } else { - // Disable hw timeout, use sw watchdog for timeout - phLibNfc_SetFelicaTimeout(0); - phLibNfc_SetHciTimeout(timeout); - } - -} -// Calculates ceiling log2 of value -static unsigned int log2(int value) { - unsigned int ret = 0; - bool isPowerOf2 = ((value & (value - 1)) == 0); - while ( (value >> ret) > 1 ) ret++; - if (!isPowerOf2) ret++; - return ret; -} - -// The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X -// spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X -// -// We keep the constant part of the formula in a static; note the factor -// 1000 off, which is due to the fact that the formula calculates seconds, -// but this method gets milliseconds as an argument. -static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0; - -static int calcTimeout(int timeout_in_ms) { - // timeout = (256 * 16 / 13560000) * 2 ^ X - // First find the first X for which timeout > requested timeout - return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor))); -} - -static void setIsoDepTimeout(jint timeout) { - if (timeout <= 4900) { - int value = calcTimeout(timeout); - // Then re-compute the actual timeout based on X - double actual_timeout = nxp_nfc_timeout_factor * (1 << value); - // Set the sw watchdog a bit longer (The PN544 timeout is very accurate, - // but it will take some time to get back through the sw layers. - // 500 ms should be enough). - phLibNfc_SetHciTimeout(ceil(actual_timeout + 500)); - value |= 0x10; // bit 4 to enable timeout - phLibNfc_SetIsoXchgTimeout(value); - } - else { - // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout - // must be disabled completely, to prevent the PN544 from aborting - // the transaction. We reuse the HCI sw watchdog to catch the timeout - // in that case. - phLibNfc_SetIsoXchgTimeout(0x00); - phLibNfc_SetHciTimeout(timeout); - } -} - -static void setNfcATimeout(jint timeout) { - if (timeout <= 4900) { - int value = calcTimeout(timeout); - phLibNfc_SetMifareRawTimeout(value); - } - else { - // Disable mifare raw timeout, use HCI sw watchdog instead - phLibNfc_SetMifareRawTimeout(0x00); - phLibNfc_SetHciTimeout(timeout); - } -} - -static bool com_android_nfc_NfcManager_doSetTimeout( JNIEnv *e, jobject o, - jint tech, jint timeout) { - bool success = false; - CONCURRENCY_LOCK(); - if (timeout <= 0) { - ALOGE("Timeout must be positive."); - return false; - } else { - switch (tech) { - case TARGET_TYPE_MIFARE_CLASSIC: - case TARGET_TYPE_MIFARE_UL: - // Intentional fall-through, Mifare UL, Classic - // transceive just uses raw 3A frames - case TARGET_TYPE_ISO14443_3A: - setNfcATimeout(timeout); - success = true; - break; - case TARGET_TYPE_ISO14443_4: - setIsoDepTimeout(timeout); - success = true; - break; - case TARGET_TYPE_FELICA: - setFelicaTimeout(timeout); - success = true; - break; - default: - ALOGW("doSetTimeout: Timeout not supported for tech %d", tech); - success = false; - } - } - CONCURRENCY_UNLOCK(); - return success; -} - -static jint com_android_nfc_NfcManager_doGetTimeout( JNIEnv *e, jobject o, - jint tech) { - int timeout = -1; - CONCURRENCY_LOCK(); - switch (tech) { - case TARGET_TYPE_MIFARE_CLASSIC: - case TARGET_TYPE_MIFARE_UL: - // Intentional fall-through, Mifare UL, Classic - // transceive just uses raw 3A frames - case TARGET_TYPE_ISO14443_3A: - timeout = phLibNfc_GetMifareRawTimeout(); - if (timeout == 0) { - timeout = phLibNfc_GetHciTimeout(); - } else { - // Timeout returned from libnfc needs conversion to ms - timeout = (nxp_nfc_timeout_factor * (1 << timeout)); - } - break; - case TARGET_TYPE_ISO14443_4: - timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only - if (timeout == 0) { - timeout = phLibNfc_GetHciTimeout(); - } else { - // Timeout returned from libnfc needs conversion to ms - timeout = (nxp_nfc_timeout_factor * (1 << timeout)); - } - break; - case TARGET_TYPE_FELICA: - timeout = phLibNfc_GetFelicaTimeout(); - if (timeout == 0) { - timeout = phLibNfc_GetHciTimeout(); - } else { - // Felica timeout already in ms - } - break; - default: - ALOGW("doGetTimeout: Timeout not supported for tech %d", tech); - break; - } - CONCURRENCY_UNLOCK(); - return timeout; -} - - -static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o) -{ - NFCSTATUS status; - struct nfc_jni_native_data *nat = NULL; - jclass cls; - jobject obj; - jfieldID f; - - TRACE("****** Init Native Structure ******"); - - /* Initialize native structure */ - nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data)); - if(nat == NULL) - { - ALOGD("malloc of nfc_jni_native_data failed"); - return FALSE; - } - memset(nat, 0, sizeof(*nat)); - e->GetJavaVM(&(nat->vm)); - nat->env_version = e->GetVersion(); - nat->manager = e->NewGlobalRef(o); - - cls = e->GetObjectClass(o); - f = e->GetFieldID(cls, "mNative", "I"); - e->SetIntField(o, f, (jint)nat); - - /* Initialize native cached references */ - cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls, - "notifyNdefMessageListeners","(Lcom/android/nfc/nxp/NativeNfcTag;)V"); - - cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls, - "notifyTransactionListeners", "([B)V"); - - cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls, - "notifyLlcpLinkActivation","(Lcom/android/nfc/nxp/NativeP2pDevice;)V"); - - cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls, - "notifyLlcpLinkDeactivated","(Lcom/android/nfc/nxp/NativeP2pDevice;)V"); - - cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls, - "notifyTargetDeselected","()V"); - - cached_NfcManager_notifySeFieldActivated = e->GetMethodID(cls, - "notifySeFieldActivated", "()V"); - - cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls, - "notifySeFieldDeactivated", "()V"); - - cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls, - "notifySeApduReceived", "([B)V"); - - cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls, - "notifySeMifareAccess", "([B)V"); - - cached_NfcManager_notifySeEmvCardRemoval = e->GetMethodID(cls, - "notifySeEmvCardRemoval", "()V"); - - if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeNfcTag",&(nat->cached_NfcTag)) == -1) - { - ALOGD("Native Structure initialization failed"); - return FALSE; - } - - if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1) - { - ALOGD("Native Structure initialization failed"); - return FALSE; - } - TRACE("****** Init Native Structure OK ******"); - return TRUE; - -} - -/* Init/Deinit method */ -static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o) -{ - struct nfc_jni_native_data *nat = NULL; - int init_result = JNI_FALSE; -#ifdef TNFC_EMULATOR_ONLY - char value[PROPERTY_VALUE_MAX]; -#endif - jboolean result; - - CONCURRENCY_LOCK(); - -#ifdef TNFC_EMULATOR_ONLY - if (!property_get("ro.kernel.qemu", value, 0)) - { - ALOGE("NFC Initialization failed: not running in an emulator\n"); - goto clean_and_return; - } -#endif - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - nat->seId = SMX_SECURE_ELEMENT_ID; - - nat->lto = 150; // LLCP_LTO - nat->miu = 128; // LLCP_MIU - // WKS indicates well-known services; 1 << sap for each supported SAP. - // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4) - nat->wks = 0x13; // LLCP_WKS - nat->opt = 0; // LLCP_OPT - nat->p2p_initiator_modes = phNfc_eP2P_ALL; - nat->p2p_target_modes = 0x0E; // All passive except 106, active - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE; - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE; - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE; - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE; - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE; - nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE; - nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE; - - nat->registry_info.MifareUL = TRUE; - nat->registry_info.MifareStd = TRUE; - nat->registry_info.ISO14443_4A = TRUE; - nat->registry_info.ISO14443_4B = TRUE; - nat->registry_info.Jewel = TRUE; - nat->registry_info.Felica = TRUE; - nat->registry_info.NFC = TRUE; - nat->registry_info.ISO15693 = TRUE; - - exported_nat = nat; - - /* Perform the initialization */ - init_result = nfc_jni_initialize(nat); - -clean_and_return: - CONCURRENCY_UNLOCK(); - - /* Convert the result and return */ - return (init_result==TRUE)?JNI_TRUE:JNI_FALSE; -} - -static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o) -{ - struct timespec ts; - NFCSTATUS status; - int result = JNI_FALSE; - struct nfc_jni_native_data *nat; - int bStackReset = FALSE; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Clear previous configuration */ - memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t)); - memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t)); - - /* Create the local semaphore */ - if (nfc_cb_data_init(&cb_data, NULL)) - { - TRACE("phLibNfc_Mgt_DeInitialize()"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if (status == NFCSTATUS_PENDING) - { - TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += 5; - - /* Wait for callback response */ - if(sem_timedwait(&cb_data.sem, &ts) == -1) - { - ALOGW("Operation timed out"); - bStackReset = TRUE; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("Failed to deinit the stack"); - bStackReset = TRUE; - } - } - else - { - TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - bStackReset = TRUE; - } - nfc_cb_data_deinit(&cb_data); - } - else - { - ALOGE("Failed to create semaphore (errno=0x%08x)", errno); - bStackReset = TRUE; - } - - kill_client(nat); - - if(bStackReset == TRUE) - { - /* Complete deinit. failed, try hard restart of NFC */ - ALOGW("Reseting stack..."); - emergency_recovery(nat); - } - - result = nfc_jni_unconfigure_driver(nat); - - TRACE("NFC Deinitialized"); - - CONCURRENCY_UNLOCK(); - - return TRUE; -} - -/* Secure Element methods */ -static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jobject o) { - NFCSTATUS ret; - jintArray list= NULL; - phLibNfc_SE_List_t se_list[PHLIBNFC_MAXNO_OF_SE]; - uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE; - - TRACE("****** Get Secure Element List ******"); - - TRACE("phLibNfc_SE_GetSecureElementList()"); - REENTRANCE_LOCK(); - ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count); - REENTRANCE_UNLOCK(); - if (ret != NFCSTATUS_SUCCESS) { - ALOGE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret, - nfc_jni_get_status_name(ret)); - return list; - } - TRACE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret, - nfc_jni_get_status_name(ret)); - - TRACE("Nb SE: %d", se_count); - list =e->NewIntArray(se_count); - for (i = 0; i < se_count; i++) { - if (se_list[i].eSE_Type == phLibNfc_SE_Type_SmartMX) { - ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected"); - ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement); - } else if(se_list[i].eSE_Type == phLibNfc_SE_Type_UICC) { - ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected"); - ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement); - } - e->SetIntArrayRegion(list, i, 1, (jint*)&se_list[i].hSecureElement); - } - - e->DeleteLocalRef(list); - - return list; -} - -static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject o) { - NFCSTATUS ret; - struct nfc_jni_native_data *nat; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) { - goto clean_and_return; - } - - TRACE("****** Select Secure Element ******"); - - TRACE("phLibNfc_SE_SetMode()"); - /* Set SE mode - Virtual */ - REENTRANCE_LOCK(); - ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeVirtualVolatile, nfc_jni_se_set_mode_callback, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - if (ret != NFCSTATUS_PENDING) { - ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if (sem_wait(&cb_data.sem)) { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - clean_and_return: - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); -} - -static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) { - NFCSTATUS ret; - struct nfc_jni_native_data *nat; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) { - goto clean_and_return; - } - - TRACE("****** Deselect Secure Element ******"); - - TRACE("phLibNfc_SE_SetMode()"); - /* Set SE mode - Default */ - REENTRANCE_LOCK(); - ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault, - nfc_jni_se_set_mode_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - - TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret); - if (ret != NFCSTATUS_PENDING) { - ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if (sem_wait(&cb_data.sem)) { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - clean_and_return: - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); -} - -/* Llcp methods */ - -static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - bool freeData = false; - jboolean result = JNI_FALSE; - struct nfc_jni_native_data *nat; - struct nfc_jni_callback_data *cb_data; - - - CONCURRENCY_LOCK(); - - /* Memory allocation for cb_data - * This is on the heap because it is used by libnfc - * even after this call has succesfully finished. It is only freed - * upon link closure in nfc_jni_llcp_linkStatus_callback. - */ - cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data)); - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(cb_data, (void*)nat)) - { - goto clean_and_return; - } - - /* Check LLCP compliancy */ - TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle, - nfc_jni_checkLlcp_callback, - nfc_jni_llcp_linkStatus_callback, - (void*)cb_data); - REENTRANCE_UNLOCK(); - /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol - * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */ - if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - freeData = true; - goto clean_and_return; - } - TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data->sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data->status == NFCSTATUS_SUCCESS) - { - result = JNI_TRUE; - } - -clean_and_return: - nfc_cb_data_deinit(cb_data); - if (freeData) { - free(cb_data); - } - CONCURRENCY_UNLOCK(); - return result; -} - -static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Activate(hLlcpHandle); - REENTRANCE_UNLOCK(); - if(ret == NFCSTATUS_SUCCESS) - { - TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return JNI_TRUE; - } - else - { - ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - return JNI_FALSE; - } -} - - - -static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o, - jint nSap, jstring sn) -{ - NFCSTATUS ret; - jobject connectionlessSocket = NULL; - phLibNfc_Handle hLlcpSocket; - struct nfc_jni_native_data *nat; - phNfc_sData_t sWorkingBuffer = {NULL, 0}; - phNfc_sData_t serviceName = {NULL, 0}; - phLibNfc_Llcp_sLinkParameters_t sParams; - jclass clsNativeConnectionlessSocket; - jfieldID f; - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Allocate Working buffer length */ - phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams); - sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP - sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); - - /* Create socket */ - TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess, - NULL, - &sWorkingBuffer, - &hLlcpSocket, - nfc_jni_llcp_transport_socket_err_callback, - (void*)nat); - REENTRANCE_UNLOCK(); - - if(ret != NFCSTATUS_SUCCESS) - { - lastErrorStatus = ret; - ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto error; - } - TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Service socket */ - if (sn == NULL) { - serviceName.buffer = NULL; - serviceName.length = 0; - } else { - serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); - serviceName.length = (uint32_t)e->GetStringUTFLength(sn); - } - - /* Bind socket */ - TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - lastErrorStatus = ret; - ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - /* Close socket created */ - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); - REENTRANCE_UNLOCK(); - goto error; - } - TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - - /* Create new NativeLlcpConnectionlessSocket object */ - if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1) - { - goto error; - } - - /* Get NativeConnectionless class object */ - clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket); - if(e->ExceptionCheck()) - { - goto error; - } - - /* Set socket handle */ - f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I"); - e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket); - TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket); - - /* Set the miu link of the connectionless socket */ - f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I"); - e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT); - TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT); - - /* Set socket SAP */ - f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I"); - e->SetIntField(connectionlessSocket, f,(jint)nSap); - TRACE("Connectionless socket SAP = %d\n",nSap); - - return connectionlessSocket; -error: - if (serviceName.buffer != NULL) { - e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); - } - - if (sWorkingBuffer.buffer != NULL) { - free(sWorkingBuffer.buffer); - } - - return NULL; -} - -static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength) -{ - NFCSTATUS ret; - phLibNfc_Handle hLlcpSocket; - phLibNfc_Llcp_sSocketOptions_t sOptions; - phNfc_sData_t sWorkingBuffer; - phNfc_sData_t serviceName; - struct nfc_jni_native_data *nat; - jobject serviceSocket = NULL; - jclass clsNativeLlcpServiceSocket; - jfieldID f; - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Set Connection Oriented socket options */ - sOptions.miu = miu; - sOptions.rw = rw; - - /* Allocate Working buffer length */ - sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; - sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); - - - /* Create socket */ - TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, - &sOptions, - &sWorkingBuffer, - &hLlcpSocket, - nfc_jni_llcp_transport_socket_err_callback, - (void*)nat); - REENTRANCE_UNLOCK(); - - if(ret != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - lastErrorStatus = ret; - goto error; - } - TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Service socket */ - if (sn == NULL) { - serviceName.buffer = NULL; - serviceName.length = 0; - } else { - serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL); - serviceName.length = (uint32_t)e->GetStringUTFLength(sn); - } - - /* Bind socket */ - TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - lastErrorStatus = ret; - ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - /* Close socket created */ - ret = phLibNfc_Llcp_Close(hLlcpSocket); - goto error; - } - TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Listen( hLlcpSocket, - nfc_jni_llcp_transport_listen_socket_callback, - (void*)hLlcpSocket); - REENTRANCE_UNLOCK(); - - if(ret != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - lastErrorStatus = ret; - /* Close created socket */ - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); - REENTRANCE_UNLOCK(); - goto error; - } - TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Create new NativeLlcpServiceSocket object */ - if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpServiceSocket",&(serviceSocket)) == -1) - { - ALOGE("Llcp Socket object creation error"); - goto error; - } - - /* Get NativeLlcpServiceSocket class object */ - clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket); - if(e->ExceptionCheck()) - { - ALOGE("Llcp Socket get object class error"); - goto error; - } - - /* Set socket handle */ - f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I"); - e->SetIntField(serviceSocket, f,(jint)hLlcpSocket); - TRACE("Service socket Handle = %02x\n",hLlcpSocket); - - /* Set socket linear buffer length */ - f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I"); - e->SetIntField(serviceSocket, f,(jint)linearBufferLength); - TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength); - - /* Set socket MIU */ - f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I"); - e->SetIntField(serviceSocket, f,(jint)miu); - TRACE("Service socket MIU = %d\n",miu); - - /* Set socket RW */ - f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I"); - e->SetIntField(serviceSocket, f,(jint)rw); - TRACE("Service socket RW = %d\n",rw); - - return serviceSocket; -error: - if (serviceName.buffer != NULL) { - e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer); - } - return NULL; -} - -static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength) -{ - jobject clientSocket = NULL; - NFCSTATUS ret; - phLibNfc_Handle hLlcpSocket; - phLibNfc_Llcp_sSocketOptions_t sOptions; - phNfc_sData_t sWorkingBuffer; - struct nfc_jni_native_data *nat; - jclass clsNativeLlcpSocket; - jfieldID f; - - /* Retrieve native structure address */ - nat = nfc_jni_get_nat(e, o); - - /* Set Connection Oriented socket options */ - sOptions.miu = miu; - sOptions.rw = rw; - - /* Allocate Working buffer length */ - sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength; - sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length); - - /* Create socket */ - TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)"); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented, - &sOptions, - &sWorkingBuffer, - &hLlcpSocket, - nfc_jni_llcp_transport_socket_err_callback, - (void*)nat); - REENTRANCE_UNLOCK(); - - if(ret != NFCSTATUS_SUCCESS) - { - ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - lastErrorStatus = ret; - return NULL; - } - TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Create new NativeLlcpSocket object */ - if(nfc_jni_cache_object(e,"com/android/nfc/nxp/NativeLlcpSocket",&(clientSocket)) == -1) - { - ALOGE("Llcp socket object creation error"); - return NULL; - } - - /* Get NativeConnectionless class object */ - clsNativeLlcpSocket = e->GetObjectClass(clientSocket); - if(e->ExceptionCheck()) - { - ALOGE("Get class object error"); - return NULL; - } - - /* Test if an SAP number is present */ - if(nSap != 0) - { - /* Bind socket */ - TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap); - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - lastErrorStatus = ret; - ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - /* Close socket created */ - REENTRANCE_LOCK(); - ret = phLibNfc_Llcp_Close(hLlcpSocket); - REENTRANCE_UNLOCK(); - return NULL; - } - TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Set socket SAP */ - f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I"); - e->SetIntField(clientSocket, f,(jint)nSap); - TRACE("socket SAP = %d\n",nSap); - } - - /* Set socket handle */ - f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I"); - e->SetIntField(clientSocket, f,(jint)hLlcpSocket); - TRACE("socket Handle = %02x\n",hLlcpSocket); - - /* Set socket MIU */ - f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I"); - e->SetIntField(clientSocket, f,(jint)miu); - TRACE("socket MIU = %d\n",miu); - - /* Set socket RW */ - f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I"); - e->SetIntField(clientSocket, f,(jint)rw); - TRACE("socket RW = %d\n",rw); - - - return clientSocket; -} - -static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o) -{ - TRACE("Last Error Status = 0x%02x",lastErrorStatus); - - if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL) - { - return ERROR_BUFFER_TOO_SMALL; - } - else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES) - { - return ERROR_INSUFFICIENT_RESOURCES; - } - else - { - return lastErrorStatus; - } -} - -static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o) -{ - emergency_recovery(NULL); -} - -static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o, - jint modes) -{ - ALOGE("Setting init modes to %x", modes); - struct nfc_jni_native_data *nat = NULL; - nat = nfc_jni_get_nat(e, o); - nat->p2p_initiator_modes = modes; -} - -static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o, - jint modes) -{ - ALOGE("Setting target modes to %x", modes); - struct nfc_jni_native_data *nat = NULL; - nat = nfc_jni_get_nat(e, o); - nat->p2p_target_modes = modes; -} - -static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) { - bool result = FALSE; - int load_result; - bool wasDisabled = FALSE; - uint8_t OutputBuffer[1]; - uint8_t InputBuffer[1]; - NFCSTATUS status = NFCSTATUS_FAILED; - struct nfc_jni_callback_data cb_data; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - result = FALSE; - goto clean_and_return; - } - - if (takeLock) - { - CONCURRENCY_LOCK(); - } - - /* Initialize Driver */ - if(!driverConfigured) - { - result = nfc_jni_configure_driver(nat); - wasDisabled = TRUE; - } - TRACE("com_android_nfc_NfcManager_doDownload()"); - - TRACE("Go in Download Mode"); - phLibNfc_Download_Mode(); - - TRACE("Load new Firmware Image"); - load_result = phLibNfc_Load_Firmware_Image(); - if(load_result != 0) - { - TRACE("Load new Firmware Image - status = %d",load_result); - result = FALSE; - goto clean_and_return; - } - - // Download - gInputParam.buffer = InputBuffer; - gInputParam.length = 0x01; - gOutputParam.buffer = OutputBuffer; - gOutputParam.length = 0x01; - - ALOGD("Download new Firmware"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - result = FALSE; - goto clean_and_return; - } - TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - result = FALSE; - goto clean_and_return; - } - - /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we - try to download an old-style firmware on top of a new-style - firmware. Hence, this is expected behavior, and not an - error condition. */ - if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED) - { - TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - result = FALSE; - goto clean_and_return; - } - - if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED) - { - ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip."); - } - - /*Download is successful*/ - result = TRUE; -clean_and_return: - TRACE("phLibNfc_HW_Reset()"); - phLibNfc_HW_Reset(); - /* Deinitialize Driver */ - if(wasDisabled) - { - result = nfc_jni_unconfigure_driver(nat); - } - if (takeLock) - { - CONCURRENCY_UNLOCK(); - } - nfc_cb_data_deinit(&cb_data); - return result; -} - -static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o) -{ - struct nfc_jni_native_data *nat = NULL; - nat = nfc_jni_get_nat(e, o); - return performDownload(nat, true); -} - -static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject o) -{ - char buffer[100]; - snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count); - return e->NewStringUTF(buffer); -} - -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doDownload", "()Z", - (void *)com_android_nfc_NfcManager_doDownload}, - - {"initializeNativeStructure", "()Z", - (void *)com_android_nfc_NfcManager_init_native_struc}, - - {"doInitialize", "()Z", - (void *)com_android_nfc_NfcManager_initialize}, - - {"doDeinitialize", "()Z", - (void *)com_android_nfc_NfcManager_deinitialize}, - - {"enableDiscovery", "()V", - (void *)com_android_nfc_NfcManager_enableDiscovery}, - - {"doGetSecureElementList", "()[I", - (void *)com_android_nfc_NfcManager_doGetSecureElementList}, - - {"doSelectSecureElement", "()V", - (void *)com_android_nfc_NfcManager_doSelectSecureElement}, - - {"doDeselectSecureElement", "()V", - (void *)com_android_nfc_NfcManager_doDeselectSecureElement}, - - {"doCheckLlcp", "()Z", - (void *)com_android_nfc_NfcManager_doCheckLlcp}, - - {"doActivateLlcp", "()Z", - (void *)com_android_nfc_NfcManager_doActivateLlcp}, - - {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/nxp/NativeLlcpConnectionlessSocket;", - (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket}, - - {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/nxp/NativeLlcpServiceSocket;", - (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket}, - - {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/nxp/NativeLlcpSocket;", - (void *)com_android_nfc_NfcManager_doCreateLlcpSocket}, - - {"doGetLastError", "()I", - (void *)com_android_nfc_NfcManager_doGetLastError}, - - {"disableDiscovery", "()V", - (void *)com_android_nfc_NfcManager_disableDiscovery}, - - {"doSetTimeout", "(II)Z", - (void *)com_android_nfc_NfcManager_doSetTimeout}, - - {"doGetTimeout", "(I)I", - (void *)com_android_nfc_NfcManager_doGetTimeout}, - - {"doResetTimeouts", "()V", - (void *)com_android_nfc_NfcManager_doResetTimeouts}, - - {"doAbort", "()V", - (void *)com_android_nfc_NfcManager_doAbort}, - - {"doSetP2pInitiatorModes","(I)V", - (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes}, - - {"doSetP2pTargetModes","(I)V", - (void *)com_android_nfc_NfcManager_doSetP2pTargetModes}, - - {"doDump", "()Ljava/lang/String;", - (void *)com_android_nfc_NfcManager_doDump}, -}; - - -int register_com_android_nfc_NativeNfcManager(JNIEnv *e) -{ - nfc_jni_native_monitor_t *nfc_jni_native_monitor; - - nfc_jni_native_monitor = nfc_jni_init_monitor(); - if(nfc_jni_native_monitor == NULL) - { - ALOGE("NFC Manager cannot recover native monitor %x\n", errno); - return -1; - } - - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeNfcManager", - gMethods, NELEM(gMethods)); -} - -} /* namespace android */ diff --git a/jni/com_android_nfc_NativeNfcSecureElement.cpp b/jni/com_android_nfc_NativeNfcSecureElement.cpp deleted file mode 100755 index bf0bffc..0000000 --- a/jni/com_android_nfc_NativeNfcSecureElement.cpp +++ /dev/null @@ -1,770 +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 <semaphore.h> - -#include "com_android_nfc.h" - -static phNfc_sData_t *com_android_nfc_jni_transceive_buffer; -static phNfc_sData_t *com_android_nfc_jni_ioctl_buffer; -static phNfc_sRemoteDevInformation_t* SecureElementInfo; -static int secureElementHandle; -extern void *gHWRef; -static int SecureElementTech; -extern uint8_t device_connected_flag; - -namespace android { - -static void com_android_nfc_jni_ioctl_callback ( void* pContext, - phNfc_sData_t* Outparam_Cb, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - if (status == NFCSTATUS_SUCCESS ) - { - LOG_CALLBACK("> IOCTL successful",status); - } - else - { - LOG_CALLBACK("> IOCTL error",status); - } - - com_android_nfc_jni_ioctl_buffer = Outparam_Cb; - pContextData->status = status; - sem_post(&pContextData->sem); -} - -static void com_android_nfc_jni_transceive_callback(void *pContext, - phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("com_android_nfc_jni_transceive_callback", status); - - com_android_nfc_jni_transceive_buffer = pResBuffer; - pContextData->status = status; - sem_post(&pContextData->sem); -} - - -static void com_android_nfc_jni_connect_callback(void *pContext, - phLibNfc_Handle hRemoteDev, - phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("com_android_nfc_jni_connect_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -static void com_android_nfc_jni_disconnect_callback(void *pContext, - phLibNfc_Handle hRemoteDev, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - LOG_CALLBACK("com_android_nfc_jni_disconnect_callback", status); - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -/* Set Secure Element mode callback*/ -static void com_android_nfc_jni_smartMX_setModeCb (void* pContext, - phLibNfc_Handle hSecureElement, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - - if(status==NFCSTATUS_SUCCESS) - { - LOG_CALLBACK("SE Set Mode is Successful",status); - TRACE("SE Handle: %lu", hSecureElement); - } - else - { - LOG_CALLBACK("SE Set Mode is failed\n ",status); - } - - pContextData->status = status; - sem_post(&pContextData->sem); -} - -static void com_android_nfc_jni_open_secure_element_notification_callback(void *pContext, - phLibNfc_RemoteDevList_t *psRemoteDevList, - uint8_t uNofRemoteDev, - NFCSTATUS status) -{ - struct nfc_jni_callback_data * pContextData = (struct nfc_jni_callback_data*)pContext; - NFCSTATUS ret; - int i; - JNIEnv *e = nfc_get_env(); - - if(status == NFCSTATUS_DESELECTED) - { - LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback: Target deselected", status); - } - else - { - LOG_CALLBACK("com_android_nfc_jni_open_secure_element_notification_callback", status); - TRACE("Discovered %d secure elements", uNofRemoteDev); - - if(status == NFCSTATUS_MULTIPLE_PROTOCOLS) - { - bool foundHandle = false; - TRACE("Multiple Protocol supported\n"); - for (i=0; i<uNofRemoteDev; i++) { - // Always open the phNfc_eISO14443_A_PICC protocol - TRACE("Protocol %d handle=%x type=%d", i, psRemoteDevList[i].hTargetDev, - psRemoteDevList[i].psRemoteDevInfo->RemDevType); - if (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC) { - secureElementHandle = psRemoteDevList[i].hTargetDev; - foundHandle = true; - } - } - if (!foundHandle) { - ALOGE("Could not find ISO-DEP secure element"); - status = NFCSTATUS_FAILED; - goto clean_and_return; - } - } - else - { - secureElementHandle = psRemoteDevList->hTargetDev; - } - - TRACE("Secure Element Handle: 0x%08x", secureElementHandle); - - /* Set type name */ - jintArray techList; - nfc_jni_get_technology_tree(e, psRemoteDevList,uNofRemoteDev, &techList, NULL, NULL); - - // TODO: Should use the "connected" technology, for now use the first - if ((techList != NULL) && e->GetArrayLength(techList) > 0) { - e->GetIntArrayRegion(techList, 0, 1, &SecureElementTech); - TRACE("Store Secure Element Info\n"); - SecureElementInfo = psRemoteDevList->psRemoteDevInfo; - - TRACE("Discovered secure element: tech=%d", SecureElementTech); - } - else { - ALOGE("Discovered secure element, but could not resolve tech"); - status = NFCSTATUS_FAILED; - } - - // This thread may not return to the virtual machine for a long time - // so make sure to delete the local refernce to the tech list. - e->DeleteLocalRef(techList); - } - -clean_and_return: - pContextData->status = status; - sem_post(&pContextData->sem); -} - - -static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection(JNIEnv *e, jobject o) -{ - NFCSTATUS ret; - int semResult; - - phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; - uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; - phLibNfc_sADD_Cfg_t discovery_cfg; - phLibNfc_Registry_Info_t registry_info; - phNfc_sData_t InParam; - phNfc_sData_t OutParam; - uint8_t ExternalRFDetected[3] = {0x00, 0xFC, 0x01}; - uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; - uint8_t GpioSetValue[4]; - uint8_t gpioValue; - uint8_t Output_Buff[10]; - uint8_t reg_value; - uint8_t mask_value; - struct nfc_jni_callback_data cb_data; - struct nfc_jni_callback_data cb_data_SE_Notification; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data_SE_Notification, NULL)) - { - goto clean_and_return; - } - - /* Registery */ - registry_info.MifareUL = TRUE; - registry_info.MifareStd = TRUE; - registry_info.ISO14443_4A = TRUE; - registry_info.ISO14443_4B = TRUE; - registry_info.Jewel = TRUE; - registry_info.Felica = TRUE; - registry_info.NFC = FALSE; - - CONCURRENCY_LOCK(); - - TRACE("Open Secure Element"); - - /* Check if NFC device is already connected to a tag or P2P peer */ - if (device_connected_flag == 1) - { - ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag"); - goto clean_and_return; - } - - /* Test if External RF field is detected */ - InParam.buffer = ExternalRFDetected; - InParam.length = 3; - OutParam.buffer = Output_Buff; - TRACE("phLibNfc_Mgt_IoCtl()"); - REENTRANCE_LOCK(); - ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(ret!=NFCSTATUS_PENDING) - { - ALOGE("IOCTL status error"); - goto clean_and_return; - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("IOCTL semaphore error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("READ MEM ERROR"); - goto clean_and_return; - } - - /* Check the value */ - reg_value = com_android_nfc_jni_ioctl_buffer->buffer[0]; - mask_value = reg_value & 0x40; - - if(mask_value == 0x40) - { - // There is an external RF field present, fail the open request - ALOGD("Unable to open SE connection, external RF Field detected"); - goto clean_and_return; - } - - /* Get Secure Element List */ - TRACE("phLibNfc_SE_GetSecureElementList()"); - ret = phLibNfc_SE_GetSecureElementList( SE_List, &No_SE); - if (ret == NFCSTATUS_SUCCESS) - { - TRACE("\n> Number of Secure Element(s) : %d\n", No_SE); - /* Display Secure Element information */ - for (i = 0; i<No_SE; i++) - { - if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) - { - TRACE("> SMX detected"); - TRACE("> Secure Element Handle : %d\n", SE_List[i].hSecureElement); - /* save SMARTMX index */ - SmartMX_detected = 1; - SmartMX_index = i; - } - } - - if(SmartMX_detected) - { - REENTRANCE_LOCK(); - TRACE("phLibNfc_RemoteDev_NtfRegister()"); - ret = phLibNfc_RemoteDev_NtfRegister(®istry_info, - com_android_nfc_jni_open_secure_element_notification_callback, - (void *)&cb_data_SE_Notification); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_SUCCESS) - { - ALOGE("Register Notification error"); - goto clean_and_return; - } - - /* Set wired mode */ - REENTRANCE_LOCK(); - TRACE("phLibNfc_SE_SetMode: Wired mode"); - ret = phLibNfc_SE_SetMode( SE_List[SmartMX_index].hSecureElement, - phLibNfc_SE_ActModeWired, - com_android_nfc_jni_smartMX_setModeCb, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - if (ret != NFCSTATUS_PENDING ) - { - ALOGE("\n> SE Set SmartMX mode ERROR \n" ); - goto clean_and_return; - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Secure Element opening error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("SE set mode failed"); - goto clean_and_return; - } - - TRACE("Waiting for notification"); - /* Wait for callback response */ - if(sem_wait(&cb_data_SE_Notification.sem)) - { - ALOGE("Secure Element opening error"); - goto clean_and_return; - } - - if(cb_data_SE_Notification.status != NFCSTATUS_SUCCESS && - cb_data_SE_Notification.status != NFCSTATUS_MULTIPLE_PROTOCOLS) - { - ALOGE("SE detection failed"); - goto clean_and_return; - } - CONCURRENCY_UNLOCK(); - - /* Connect Tag */ - CONCURRENCY_LOCK(); - TRACE("phLibNfc_RemoteDev_Connect(SMX)"); - REENTRANCE_LOCK(); - ret = phLibNfc_RemoteDev_Connect(secureElementHandle, com_android_nfc_jni_connect_callback,(void *)&cb_data); - REENTRANCE_UNLOCK(); - if(ret != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Connect(SMX) returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("CONNECT semaphore error"); - goto clean_and_return; - } - - /* Connect Status */ - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("Secure Element connect error"); - goto clean_and_return; - } - - CONCURRENCY_UNLOCK(); - - /* Get GPIO information */ - CONCURRENCY_LOCK(); - InParam.buffer = GpioGetValue; - InParam.length = 3; - OutParam.buffer = Output_Buff; - TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); - REENTRANCE_LOCK(); - ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(ret!=NFCSTATUS_PENDING) - { - ALOGE("IOCTL status error"); - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("IOCTL semaphore error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("READ MEM ERROR"); - goto clean_and_return; - } - - gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; - TRACE("GpioValue = Ox%02x",gpioValue); - - /* Set GPIO information */ - GpioSetValue[0] = 0x00; - GpioSetValue[1] = 0xF8; - GpioSetValue[2] = 0x2B; - GpioSetValue[3] = (gpioValue | 0x40); - - TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); - - for(i=0;i<4;i++) - { - TRACE("0x%02x",GpioSetValue[i]); - } - - InParam.buffer = GpioSetValue; - InParam.length = 4; - OutParam.buffer = Output_Buff; - TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); - REENTRANCE_LOCK(); - ret = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(ret!=NFCSTATUS_PENDING) - { - ALOGE("IOCTL status error"); - goto clean_and_return; - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("IOCTL semaphore error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("READ MEM ERROR"); - goto clean_and_return; - } - CONCURRENCY_UNLOCK(); - - nfc_cb_data_deinit(&cb_data); - nfc_cb_data_deinit(&cb_data_SE_Notification); - - /* Return the Handle of the SecureElement */ - return secureElementHandle; - } - else - { - ALOGE("phLibNfc_SE_GetSecureElementList(): No SMX detected"); - goto clean_and_return; - } - } - else - { - ALOGE("phLibNfc_SE_GetSecureElementList(): Error"); - goto clean_and_return; - } - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - nfc_cb_data_deinit(&cb_data_SE_Notification); - - CONCURRENCY_UNLOCK(); - return 0; -} - - -static jboolean com_android_nfc_NativeNfcSecureElement_doDisconnect(JNIEnv *e, jobject o, jint handle) -{ - jclass cls; - jfieldID f; - NFCSTATUS status; - jboolean result = JNI_FALSE; - phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE]; - uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0; - uint32_t SmartMX_Handle; - struct nfc_jni_callback_data cb_data; - phNfc_sData_t InParam; - phNfc_sData_t OutParam; - uint8_t Output_Buff[10]; - uint8_t GpioGetValue[3] = {0x00, 0xF8, 0x2B}; - uint8_t GpioSetValue[4]; - uint8_t gpioValue; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - TRACE("Close Secure element function "); - - CONCURRENCY_LOCK(); - /* Disconnect */ - TRACE("Disconnecting from SMX (handle = 0x%x)", handle); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Disconnect(handle, - NFC_SMARTMX_RELEASE, - com_android_nfc_jni_disconnect_callback, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Disconnect(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - goto clean_and_return; - } - - /* Disconnect Status */ - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("\n> Disconnect SE ERROR \n" ); - goto clean_and_return; - } - CONCURRENCY_UNLOCK(); - - /* Get GPIO information */ - CONCURRENCY_LOCK(); - InParam.buffer = GpioGetValue; - InParam.length = 3; - OutParam.buffer = Output_Buff; - TRACE("phLibNfc_Mgt_IoCtl()- GPIO Get Value"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_READ,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status!=NFCSTATUS_PENDING) - { - ALOGE("IOCTL status error"); - goto clean_and_return; - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("IOCTL semaphore error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("READ MEM ERROR"); - goto clean_and_return; - } - - gpioValue = com_android_nfc_jni_ioctl_buffer->buffer[0]; - TRACE("GpioValue = Ox%02x",gpioValue); - - /* Set GPIO information */ - GpioSetValue[0] = 0x00; - GpioSetValue[1] = 0xF8; - GpioSetValue[2] = 0x2B; - GpioSetValue[3] = (gpioValue & 0xBF); - - TRACE("GpioValue to be set = Ox%02x",GpioSetValue[3]); - - for(i=0;i<4;i++) - { - TRACE("0x%02x",GpioSetValue[i]); - } - - InParam.buffer = GpioSetValue; - InParam.length = 4; - OutParam.buffer = Output_Buff; - TRACE("phLibNfc_Mgt_IoCtl()- GPIO Set Value"); - REENTRANCE_LOCK(); - status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_MEM_WRITE,&InParam, &OutParam,com_android_nfc_jni_ioctl_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status!=NFCSTATUS_PENDING) - { - ALOGE("IOCTL status error"); - goto clean_and_return; - } - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("IOCTL semaphore error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("READ MEM ERROR"); - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - - CONCURRENCY_UNLOCK(); - return result; -} - -static jbyteArray com_android_nfc_NativeNfcSecureElement_doTransceive(JNIEnv *e, - jobject o,jint handle, jbyteArray data) -{ - uint8_t offset = 0; - uint8_t *buf; - uint32_t buflen; - phLibNfc_sTransceiveInfo_t transceive_info; - jbyteArray result = NULL; - int res; - - int tech = SecureElementTech; - NFCSTATUS status; - struct nfc_jni_callback_data cb_data; - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - TRACE("Exchange APDU function "); - - CONCURRENCY_LOCK(); - - TRACE("Secure Element tech: %d\n", tech); - - buf = (uint8_t *)e->GetByteArrayElements(data, NULL); - buflen = (uint32_t)e->GetArrayLength(data); - - /* Prepare transceive info structure */ - if(tech == TARGET_TYPE_MIFARE_CLASSIC || tech == TARGET_TYPE_MIFARE_UL) - { - offset = 2; - transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; - transceive_info.addr = (uint8_t)buf[1]; - } - else if(tech == TARGET_TYPE_ISO14443_4) - { - transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw; - transceive_info.addr = 0; - } - - transceive_info.sSendData.buffer = buf + offset; - transceive_info.sSendData.length = buflen - offset; - transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); - transceive_info.sRecvData.length = 1024; - - if(transceive_info.sRecvData.buffer == NULL) - { - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_Transceive(SMX)"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, - com_android_nfc_jni_transceive_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Transceive(SMX) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("TRANSCEIVE semaphore error"); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - ALOGE("TRANSCEIVE error"); - goto clean_and_return; - } - - /* Copy results back to Java */ - result = e->NewByteArray(com_android_nfc_jni_transceive_buffer->length); - if(result != NULL) - { - e->SetByteArrayRegion(result, 0, - com_android_nfc_jni_transceive_buffer->length, - (jbyte *)com_android_nfc_jni_transceive_buffer->buffer); - } - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - - if(transceive_info.sRecvData.buffer != NULL) - { - free(transceive_info.sRecvData.buffer); - } - - e->ReleaseByteArrayElements(data, - (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT); - - CONCURRENCY_UNLOCK(); - - return result; -} - -static jbyteArray com_android_nfc_NativeNfcSecureElement_doGetUid(JNIEnv *e, jobject o, jint handle) -{ - TRACE("Get Secure element UID function "); - jbyteArray SecureElementUid; - - if(handle == secureElementHandle) - { - SecureElementUid = e->NewByteArray(SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength); - e->SetByteArrayRegion(SecureElementUid, 0, SecureElementInfo->RemoteDevInfo.Iso14443A_Info.UidLength,(jbyte *)SecureElementInfo->RemoteDevInfo.Iso14443A_Info.Uid); - return SecureElementUid; - } - else - { - return NULL; - } -} - -static jintArray com_android_nfc_NativeNfcSecureElement_doGetTechList(JNIEnv *e, jobject o, jint handle) -{ - jintArray techList; - TRACE("Get Secure element Type function "); - - if(handle == secureElementHandle) - { - techList = e->NewIntArray(1); - e->SetIntArrayRegion(techList, 0, 1, &SecureElementTech); - return techList; - } - else - { - return NULL; - } -} - - -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doNativeOpenSecureElementConnection", "()I", - (void *)com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection}, - {"doNativeDisconnectSecureElementConnection", "(I)Z", - (void *)com_android_nfc_NativeNfcSecureElement_doDisconnect}, - {"doTransceive", "(I[B)[B", - (void *)com_android_nfc_NativeNfcSecureElement_doTransceive}, - {"doGetUid", "(I)[B", - (void *)com_android_nfc_NativeNfcSecureElement_doGetUid}, - {"doGetTechList", "(I)[I", - (void *)com_android_nfc_NativeNfcSecureElement_doGetTechList}, -}; - -int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e) -{ - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeNfcSecureElement", - gMethods, NELEM(gMethods)); -} - -} // namespace android diff --git a/jni/com_android_nfc_NativeNfcTag.cpp b/jni/com_android_nfc_NativeNfcTag.cpp deleted file mode 100644 index dbf8dc9..0000000 --- a/jni/com_android_nfc_NativeNfcTag.cpp +++ /dev/null @@ -1,1255 +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 <semaphore.h> -#include <errno.h> - -#include "com_android_nfc.h" -#include "phNfcHalTypes.h" - -static phLibNfc_Data_t nfc_jni_ndef_rw; -static phLibNfc_Handle handle; -uint8_t *nfc_jni_ndef_buf = NULL; -uint32_t nfc_jni_ndef_buf_len = 0; - -extern uint8_t device_connected_flag; - -namespace android { - -extern phLibNfc_Handle storedHandle; - -extern void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat); -extern void nfc_jni_reset_timeout_values(); - -/* - * Callbacks - */ - static void nfc_jni_tag_rw_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_tag_rw_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_connect_callback(void *pContext, - phLibNfc_Handle hRemoteDev, - phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_connect_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - if (pCallbackData->pContext != NULL) { - // Store the remote dev info ptr in the callback context - // Note that this ptr will remain valid, it is tied to a statically - // allocated buffer in libnfc. - phLibNfc_sRemoteDevInformation_t** ppRemoteDevInfo = - (phLibNfc_sRemoteDevInformation_t**)pCallbackData->pContext; - *ppRemoteDevInfo = psRemoteDevInfo; - } - - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_checkndef_callback(void *pContext, - phLibNfc_ChkNdef_Info_t info, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_checkndef_callback", status); - phLibNfc_ChkNdef_Info_t* pNdefInfo = (phLibNfc_ChkNdef_Info_t*) (pCallbackData->pContext); - if(status == NFCSTATUS_OK) - { - if(nfc_jni_ndef_buf) - { - free(nfc_jni_ndef_buf); - } - nfc_jni_ndef_buf_len = info.MaxNdefMsgLength; - nfc_jni_ndef_buf = (uint8_t*)malloc(nfc_jni_ndef_buf_len); - if (pNdefInfo != NULL) *pNdefInfo = info; - } - else { - if (pNdefInfo != NULL) { - memset(pNdefInfo, 0, sizeof(*pNdefInfo)); - } - } - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_disconnect_callback(void *pContext, - phLibNfc_Handle hRemoteDev, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_disconnect_callback", status); - - if(nfc_jni_ndef_buf) - { - free(nfc_jni_ndef_buf); - } - nfc_jni_ndef_buf = NULL; - nfc_jni_ndef_buf_len = 0; - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_async_disconnect_callback(void *pContext, - phLibNfc_Handle hRemoteDev, NFCSTATUS status) -{ - LOG_CALLBACK("nfc_jni_async_disconnect_callback", status); - - if(nfc_jni_ndef_buf) - { - free(nfc_jni_ndef_buf); - } - nfc_jni_ndef_buf = NULL; - nfc_jni_ndef_buf_len = 0; -} - -static phNfc_sData_t *nfc_jni_transceive_buffer; - -static void nfc_jni_transceive_callback(void *pContext, - phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_transceive_callback", status); - - nfc_jni_transceive_buffer = pResBuffer; - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_presencecheck_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_presencecheck_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_formatndef_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_formatndef_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_readonly_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_readonly_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -/* Functions */ -static jbyteArray com_android_nfc_NativeNfcTag_doRead(JNIEnv *e, - jobject o) -{ - NFCSTATUS status; - phLibNfc_Handle handle = 0; - jbyteArray buf = NULL; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - handle = nfc_jni_get_connected_handle(e, o); - - nfc_jni_ndef_rw.length = nfc_jni_ndef_buf_len; - nfc_jni_ndef_rw.buffer = nfc_jni_ndef_buf; - - TRACE("phLibNfc_Ndef_Read()"); - REENTRANCE_LOCK(); - status = phLibNfc_Ndef_Read(handle, &nfc_jni_ndef_rw, - phLibNfc_Ndef_EBegin, - nfc_jni_tag_rw_callback, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - buf = e->NewByteArray(nfc_jni_ndef_rw.length); - e->SetByteArrayRegion(buf, 0, nfc_jni_ndef_rw.length, - (jbyte *)nfc_jni_ndef_rw.buffer); - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - - return buf; -} - - -static jboolean com_android_nfc_NativeNfcTag_doWrite(JNIEnv *e, - jobject o, jbyteArray buf) -{ - NFCSTATUS status; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - - phLibNfc_Handle handle = nfc_jni_get_connected_handle(e, o); - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - nfc_jni_ndef_rw.length = (uint32_t)e->GetArrayLength(buf); - nfc_jni_ndef_rw.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL); - - TRACE("phLibNfc_Ndef_Write()"); - TRACE("Ndef Handle :0x%x\n",handle); - TRACE("Ndef buffer length : %d", nfc_jni_ndef_rw.length); - REENTRANCE_LOCK(); - status = phLibNfc_Ndef_Write(handle, &nfc_jni_ndef_rw,nfc_jni_tag_rw_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - e->ReleaseByteArrayElements(buf, (jbyte *)nfc_jni_ndef_rw.buffer, JNI_ABORT); - - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} - -/* - * Utility to recover poll bytes from target infos - */ -static void set_target_pollBytes(JNIEnv *e, jobject tag, - phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo) -{ - jclass tag_cls = e->GetObjectClass(tag); - jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B"); - - jobjectArray existingPollBytes = (jobjectArray) e->GetObjectField(tag, f); - - if (existingPollBytes != NULL) { - return; - } - - jfieldID techListField = e->GetFieldID(tag_cls, "mTechList", "[I"); - jintArray techList = (jintArray) e->GetObjectField(tag, techListField); - jint *techId = e->GetIntArrayElements(techList, 0); - int techListLength = e->GetArrayLength(techList); - - jbyteArray pollBytes = e->NewByteArray(0); - jobjectArray techPollBytes = e->NewObjectArray(techListLength, - e->GetObjectClass(pollBytes), 0); - - for (int tech = 0; tech < techListLength; tech++) { - switch(techId[tech]) - { - /* ISO14443-3A: ATQA/SENS_RES */ - case TARGET_TYPE_ISO14443_3A: - if (psRemoteDevInfo->RemDevType == phNfc_eJewel_PICC) { - // Jewel ATQA is not read and stored by the PN544, but it is fixed - // at {0x00, 0x0C} in the spec. So eJewel can safely be - // translated to {0x00, 0x0C}. - const static jbyte JewelAtqA[2] = {0x00, 0x0C}; - pollBytes = e->NewByteArray(2); - e->SetByteArrayRegion(pollBytes, 0, 2, (jbyte*) JewelAtqA); - } - else { - pollBytes = e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA)); - e->SetByteArrayRegion(pollBytes, 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA), - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AtqA); - } - break; - /* ISO14443-3B: Application data (4 bytes) and Protocol Info (3 bytes) from ATQB/SENSB_RES */ - case TARGET_TYPE_ISO14443_3B: - pollBytes = e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData) - + sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.ProtInfo)); - e->SetByteArrayRegion(pollBytes, 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData), - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData); - e->SetByteArrayRegion(pollBytes, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.AppData), - sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.ProtInfo), - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.ProtInfo); - break; - /* JIS_X_6319_4: PAD0 (2 byte), PAD1 (2 byte), MRTI(2 byte), PAD2 (1 byte), RC (2 byte) */ - case TARGET_TYPE_FELICA: - pollBytes = e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm) - + sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode)); - e->SetByteArrayRegion(pollBytes, 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm), - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm); - e->SetByteArrayRegion(pollBytes, sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm), - sizeof(psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode), - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode); - break; - /* ISO15693: response flags (1 byte), DSFID (1 byte) */ - case TARGET_TYPE_ISO15693: - pollBytes = e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags) - + sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid)); - e->SetByteArrayRegion(pollBytes, 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), - (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags); - e->SetByteArrayRegion(pollBytes, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), - sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid), - (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid); - break; - default: - pollBytes = e->NewByteArray(0); - break; - } - e->SetObjectArrayElement(techPollBytes, tech, pollBytes); - } - - e->SetObjectField(tag, f, techPollBytes); - - e->ReleaseIntArrayElements(techList, techId, 0); - -} - -/* - * Utility to recover activation bytes from target infos - */ -static void set_target_activationBytes(JNIEnv *e, jobject tag, - phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo) -{ - jclass tag_cls = e->GetObjectClass(tag); - - jfieldID f = e->GetFieldID(tag_cls, "mTechActBytes", "[[B"); - jobjectArray existingActBytes = (jobjectArray) e->GetObjectField(tag, f); - - if (existingActBytes != NULL) { - return; - } - - jfieldID techListField = e->GetFieldID(tag_cls, "mTechList", "[I"); - jintArray techList = (jintArray) e->GetObjectField(tag, techListField); - int techListLength = e->GetArrayLength(techList); - jint *techId = e->GetIntArrayElements(techList, 0); - - jbyteArray actBytes = e->NewByteArray(0); - jobjectArray techActBytes = e->NewObjectArray(techListLength, - e->GetObjectClass(actBytes), 0); - - for (int tech = 0; tech < techListLength; tech++) { - switch(techId[tech]) { - - /* ISO14443-3A: SAK/SEL_RES */ - case TARGET_TYPE_ISO14443_3A: - actBytes = e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak)); - e->SetByteArrayRegion(actBytes, 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak), - (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak); - break; - /* ISO14443-3A & ISO14443-4: SAK/SEL_RES, historical bytes from ATS */ - /* ISO14443-3B & ISO14443-4: HiLayerResp */ - case TARGET_TYPE_ISO14443_4: - // Determine whether -A or -B - if (psRemoteDevInfo->RemDevType == phNfc_eISO14443_B_PICC || - psRemoteDevInfo->RemDevType == phNfc_eISO14443_4B_PICC) { - actBytes = e->NewByteArray(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.HiLayerRespLength); - e->SetByteArrayRegion(actBytes, 0, psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.HiLayerRespLength, - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.HiLayerResp); - } - else if (psRemoteDevInfo->RemDevType == phNfc_eISO14443_A_PICC || - psRemoteDevInfo->RemDevType == phNfc_eISO14443_4A_PICC) { - actBytes = e->NewByteArray(psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AppDataLength); - e->SetByteArrayRegion(actBytes, 0, - psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AppDataLength, - (jbyte *)psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.AppData); - } - break; - /* ISO15693: response flags (1 byte), DSFID (1 byte) */ - case TARGET_TYPE_ISO15693: - actBytes = e->NewByteArray(sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags) - + sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid)); - e->SetByteArrayRegion(actBytes, 0, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), - (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags); - e->SetByteArrayRegion(actBytes, sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Flags), - sizeof(psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid), - (jbyte *)&psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Dsfid); - break; - default: - actBytes = e->NewByteArray(0); - break; - } - e->SetObjectArrayElement(techActBytes, tech, actBytes); - } - e->SetObjectField(tag, f, techActBytes); - - e->ReleaseIntArrayElements(techList, techId, 0); -} - -static jint com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e, - jobject o, phLibNfc_Handle handle) -{ - jclass cls; - jfieldID f; - jint status; - struct nfc_jni_callback_data cb_data; - phLibNfc_sRemoteDevInformation_t* pRemDevInfo = NULL; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, &pRemDevInfo)) - { - status = NFCSTATUS_NOT_ENOUGH_MEMORY; - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_Connect(RW)"); - REENTRANCE_LOCK(); - storedHandle = handle; - status = phLibNfc_RemoteDev_Connect(handle, nfc_jni_connect_callback,(void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - status = NFCSTATUS_ABORTED; - goto clean_and_return; - } - - status = cb_data.status; - TRACE("phLibNfc_RemoteDev_Connect() - Status code = %d", status); - - /* Connect Status */ - if(status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - // Success, set poll & act bytes - set_target_pollBytes(e, o, pRemDevInfo); - set_target_activationBytes(e, o, pRemDevInfo); - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return status; -} - -static jint com_android_nfc_NativeNfcTag_doHandleReconnect(JNIEnv *e, - jobject o, phLibNfc_Handle handle) -{ - jclass cls; - jfieldID f; - jint status; - struct nfc_jni_callback_data cb_data; - phLibNfc_sRemoteDevInformation_t* pRemDevInfo = NULL; - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, &pRemDevInfo)) - { - status = NFCSTATUS_NOT_ENOUGH_MEMORY; - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_ReConnect(RW)"); - REENTRANCE_LOCK(); - storedHandle = handle; - status = phLibNfc_RemoteDev_ReConnect(handle, nfc_jni_connect_callback,(void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_ReConnect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_ReConnect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - status = NFCSTATUS_ABORTED; - goto clean_and_return; - } - - status = cb_data.status; - - /* Connect Status */ - if(status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return status; -} - -static jint com_android_nfc_NativeNfcTag_doReconnect(JNIEnv *e, - jobject o) -{ - // Reconnect is provided by libnfc by just calling connect again - // on the same handle. - int libNfcType = nfc_jni_get_connected_technology_libnfc_type(e, o); - if (libNfcType != -1) { - // Note that some tag types are stateless, hence we do not reconnect - // those. Currently those are the Jewel and Iso15693 technologies. - if ((libNfcType != phNfc_eJewel_PICC) && (libNfcType != phNfc_eISO15693_PICC)) { - phLibNfc_Handle handle = nfc_jni_get_connected_handle(e,o); - return com_android_nfc_NativeNfcTag_doConnect(e, o, handle); - } - else { - return NFCSTATUS_SUCCESS; - } - } - else { - return NFCSTATUS_REJECTED; - } -} - - -static jboolean com_android_nfc_NativeNfcTag_doDisconnect(JNIEnv *e, jobject o) -{ - phLibNfc_Handle handle = 0; - jclass cls; - jfieldID f; - NFCSTATUS status; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - handle = nfc_jni_get_connected_handle(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Reset the stored handle */ - storedHandle = 0; - - nfc_jni_reset_timeout_values(); - - /* Disconnect */ - TRACE("Disconnecting from tag (%x)", handle); - - if (handle == -1) { - // Was never connected to any tag, exit - result = JNI_TRUE; - ALOGE("doDisconnect() - Target already disconnected"); - nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_Disconnect(%x)", handle); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE, - nfc_jni_disconnect_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - - if(status == NFCSTATUS_TARGET_NOT_CONNECTED) - { - result = JNI_TRUE; - TRACE("phLibNfc_RemoteDev_Disconnect() - Target already disconnected"); - goto clean_and_return; - } - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Disconnect(%x) returned 0x%04x[%s]", handle, status, nfc_jni_get_status_name(status)); - nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Disconnect(%x) returned 0x%04x[%s]", handle, status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - /* Disconnect Status */ - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - /* Reset device connected flag */ - device_connected_flag = 0; - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} - -static uint16_t -crc_16_ccitt1( uint8_t* msg, size_t len, uint16_t init ) -{ - uint16_t b, crc = init; - - do { - b = *msg++ ^ (crc & 0xFF); - b ^= (b << 4) & 0xFF; - crc = (crc >> 8) ^ (b << 8) ^ (b << 3) ^ (b >> 4); - } while( --len ); - - return crc; -} - -static void -nfc_insert_crc_a( uint8_t* msg, size_t len ) -{ - uint16_t crc; - - crc = crc_16_ccitt1( msg, len, 0x6363 ); - msg[len] = crc & 0xFF; - msg[len + 1] = (crc >> 8) & 0xFF; -} - -static void -nfc_get_crc_a( uint8_t* msg, size_t len, uint8_t* byte1, uint8_t* byte2) -{ - uint16_t crc; - - crc = crc_16_ccitt1( msg, len, 0x6363 ); - *byte1 = crc & 0xFF; - *byte2 = (crc >> 8) & 0xFF; -} - -static bool -crc_valid( uint8_t* msg, size_t len) -{ - uint8_t crcByte1, crcByte2; - - nfc_get_crc_a(nfc_jni_transceive_buffer->buffer, - len - 2, &crcByte1, &crcByte2); - - if (msg[len - 2] == crcByte1 && - msg[len - 1] == crcByte2) { - return true; - } - else { - return false; - } - -} - -static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e, - jobject o, jbyteArray data, jboolean raw, jintArray statusTargetLost) -{ - uint8_t offset = 0; - // buf is the pointer to the JNI array and never overwritten, - // outbuf is passed into the transceive - it may be pointed to new memory - // to be extended with CRC. - uint8_t *buf = NULL; - uint32_t buflen; - - uint8_t *outbuf = NULL; - uint32_t outlen; - phLibNfc_sTransceiveInfo_t transceive_info; - jbyteArray result = NULL; - int res; - phLibNfc_Handle handle = nfc_jni_get_connected_handle(e, o); - NFCSTATUS status; - struct nfc_jni_callback_data cb_data; - int selectedTech = 0; - int selectedLibNfcType = 0; - jint* technologies = NULL; - bool checkResponseCrc = false; - - jint *targetLost; - if (statusTargetLost != NULL) { - targetLost = e->GetIntArrayElements(statusTargetLost, 0); - if (targetLost != NULL) { - *targetLost = 0; - } - } else { - targetLost = NULL; - } - - memset(&transceive_info, 0, sizeof(transceive_info)); - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - selectedTech = nfc_jni_get_connected_technology(e, o); - selectedLibNfcType = nfc_jni_get_connected_technology_libnfc_type(e, o); - - buf = outbuf = (uint8_t *)e->GetByteArrayElements(data, NULL); - buflen = outlen = (uint32_t)e->GetArrayLength(data); - - switch (selectedTech) { - case TARGET_TYPE_FELICA: - transceive_info.cmd.FelCmd = phNfc_eFelica_Raw; - transceive_info.addr = 0; - break; - case TARGET_TYPE_MIFARE_CLASSIC: - case TARGET_TYPE_MIFARE_UL: - if (raw) { - transceive_info.cmd.MfCmd = phHal_eMifareRaw; - transceive_info.addr = 0; - // Need to add in the crc here - outbuf = (uint8_t*)malloc(buflen + 2); - outlen += 2; - memcpy(outbuf, buf, buflen); - nfc_insert_crc_a(outbuf, buflen); - - checkResponseCrc = true; - } else { - offset = 2; - transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; - transceive_info.addr = (uint8_t)buf[1]; - } - break; - case TARGET_TYPE_ISO14443_3A: - // Check which libnfc type - if (selectedLibNfcType == phNfc_eJewel_PICC) { - // For the Jewel pipe, CRC is automatically computed - transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw; - transceive_info.addr = 0; - } else { - if (raw) { - // Use Mifare Raw to implement a standard - // ISO14443-3A transceive, with CRC added - transceive_info.cmd.MfCmd = phHal_eMifareRaw; - transceive_info.addr = 0; - // Need to add in the crc here - outbuf = (uint8_t*)malloc(buflen + 2); - outlen += 2; - memcpy(outbuf, buf, buflen); - nfc_insert_crc_a(outbuf, buflen); - - checkResponseCrc = true; - } else { - // Use the mifare pipe - offset = 2; - transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0]; - transceive_info.addr = (uint8_t)buf[1]; - } - - } - break; - case TARGET_TYPE_ISO14443_4: - transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw; - transceive_info.addr = 0; - break; - case TARGET_TYPE_ISO15693: - transceive_info.cmd.Iso15693Cmd = phNfc_eIso15693_Cmd; - transceive_info.addr = 0; - break; - case TARGET_TYPE_UNKNOWN: - case TARGET_TYPE_ISO14443_3B: - // Not supported - goto clean_and_return; - default: - break; - } - - transceive_info.sSendData.buffer = outbuf + offset; - transceive_info.sSendData.length = outlen - offset; - transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); - transceive_info.sRecvData.length = 1024; - if(transceive_info.sRecvData.buffer == NULL) - { - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_Transceive()"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, - nfc_jni_transceive_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - if ((targetLost != NULL) && (status == NFCSTATUS_TARGET_LOST)) { - *targetLost = 1; - } - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - if ((targetLost != NULL) && (cb_data.status == NFCSTATUS_TARGET_LOST)) { - *targetLost = 1; - } - goto clean_and_return; - } - - /* Copy results back to Java * - * In case of NfcA and raw, also check the CRC in the response - * and cut it off in the returned data. - */ - if ((nfc_jni_transceive_buffer->length > 2) && checkResponseCrc) { - if (crc_valid(nfc_jni_transceive_buffer->buffer, nfc_jni_transceive_buffer->length)) { - result = e->NewByteArray(nfc_jni_transceive_buffer->length - 2); - if (result != NULL) { - e->SetByteArrayRegion(result, 0, - nfc_jni_transceive_buffer->length - 2, - (jbyte *)nfc_jni_transceive_buffer->buffer); - } - } - } else { - result = e->NewByteArray(nfc_jni_transceive_buffer->length); - if (result != NULL) { - e->SetByteArrayRegion(result, 0, - nfc_jni_transceive_buffer->length, - (jbyte *)nfc_jni_transceive_buffer->buffer); - } - } -clean_and_return: - if(transceive_info.sRecvData.buffer != NULL) - { - free(transceive_info.sRecvData.buffer); - } - - if ((outbuf != buf) && (outbuf != NULL)) { - // Buf was extended and re-alloced with crc bytes, free separately - free(outbuf); - } - - e->ReleaseByteArrayElements(data, - (jbyte *)buf, JNI_ABORT); - - if (targetLost != NULL) { - e->ReleaseIntArrayElements(statusTargetLost, targetLost, 0); - } - - nfc_cb_data_deinit(&cb_data); - - CONCURRENCY_UNLOCK(); - - return result; -} - -static jint com_android_nfc_NativeNfcTag_doGetNdefType(JNIEnv *e, jobject o, - jint libnfcType, jint javaType) -{ - jint ndefType = NDEF_UNKNOWN_TYPE; - - switch (libnfcType) { - case phNfc_eJewel_PICC: - ndefType = NDEF_TYPE1_TAG; - break; - case phNfc_eISO14443_3A_PICC: - ndefType = NDEF_TYPE2_TAG;; - break; - case phNfc_eFelica_PICC: - ndefType = NDEF_TYPE3_TAG; - break; - case phNfc_eISO14443_A_PICC: - case phNfc_eISO14443_4A_PICC: - case phNfc_eISO14443_B_PICC: - case phNfc_eISO14443_4B_PICC: - ndefType = NDEF_TYPE4_TAG; - break; - case phNfc_eMifare_PICC: - if (javaType == TARGET_TYPE_MIFARE_UL) { - ndefType = NDEF_TYPE2_TAG; - } else { - ndefType = NDEF_MIFARE_CLASSIC_TAG; - } - break; - case phNfc_eISO15693_PICC: - ndefType = NDEF_ICODE_SLI_TAG; - break; - default: - ndefType = NDEF_UNKNOWN_TYPE; - break; - } - return ndefType; -} - -static jint com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o, jintArray ndefinfo) -{ - phLibNfc_Handle handle = 0; - jint status; - phLibNfc_ChkNdef_Info_t sNdefInfo; - struct nfc_jni_callback_data cb_data; - jint *ndef = e->GetIntArrayElements(ndefinfo, 0); - int apiCardState = NDEF_MODE_UNKNOWN; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - status = NFCSTATUS_NOT_ENOUGH_MEMORY; - goto clean_and_return; - } - cb_data.pContext = &sNdefInfo; - - handle = nfc_jni_get_connected_handle(e, o); - - TRACE("phLibNfc_Ndef_CheckNdef()"); - REENTRANCE_LOCK(); - status = phLibNfc_Ndef_CheckNdef(handle, nfc_jni_checkndef_callback,(void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - status = NFCSTATUS_ABORTED; - goto clean_and_return; - } - - status = cb_data.status; - TRACE("phLibNfc_Ndef_CheckNdef() - Status code = %d", status); - - if (status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - ndef[0] = sNdefInfo.MaxNdefMsgLength; - // Translate the card state to know values for the NFC API - switch (sNdefInfo.NdefCardState) { - case PHLIBNFC_NDEF_CARD_INITIALISED: - apiCardState = NDEF_MODE_READ_WRITE; - break; - case PHLIBNFC_NDEF_CARD_READ_ONLY: - apiCardState = NDEF_MODE_READ_ONLY; - break; - case PHLIBNFC_NDEF_CARD_READ_WRITE: - apiCardState = NDEF_MODE_READ_WRITE; - break; - case PHLIBNFC_NDEF_CARD_INVALID: - apiCardState = NDEF_MODE_UNKNOWN; - break; - } - ndef[1] = apiCardState; - -clean_and_return: - e->ReleaseIntArrayElements(ndefinfo, ndef, 0); - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return status; -} - -static jboolean com_android_nfc_NativeNfcTag_doPresenceCheck(JNIEnv *e, jobject o) -{ - phLibNfc_Handle handle = 0; - NFCSTATUS status; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - handle = nfc_jni_get_connected_handle(e, o); - - TRACE("phLibNfc_RemoteDev_CheckPresence()"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_CheckPresence(handle, nfc_jni_presencecheck_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if (cb_data.status == NFCSTATUS_SUCCESS) - { - result = JNI_TRUE; - } - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - - CONCURRENCY_UNLOCK(); - - return result; -} - -static jboolean com_android_nfc_NativeNfcTag_doIsIsoDepNdefFormatable(JNIEnv *e, - jobject o, jbyteArray pollBytes, jbyteArray actBytes) -{ - // Determines whether this is a formatable IsoDep tag - currently only NXP DESFire - // is supported. - jboolean result = JNI_FALSE; - - // DESfire has one sak byte and 2 ATQA bytes - if (pollBytes != NULL && (e->GetArrayLength(pollBytes) >= 2) && - actBytes != NULL && (e->GetArrayLength(actBytes) >= 1)) { - jbyte* poll = e->GetByteArrayElements(pollBytes, NULL); - jbyte* act = e->GetByteArrayElements(actBytes, NULL); - if (act[0] == 0x20 && poll[1] == 0x03) { - uint8_t cmd[] = {0x90, 0x60, 0x00, 0x00, 0x00}; - // Identifies as DESfire, use get version cmd to be sure - jbyteArray versionCmd = e->NewByteArray(5); - e->SetByteArrayRegion(versionCmd, 0, 5, (jbyte*)cmd); - jbyteArray respBytes = com_android_nfc_NativeNfcTag_doTransceive(e, o, - versionCmd, JNI_TRUE, NULL); - if (respBytes != NULL) { - // Check whether the response matches a typical DESfire - // response. - // libNFC even does more advanced checking than we do - // here, and will only format DESfire's with a certain - // major/minor sw version and NXP as a manufacturer. - // We don't want to do such checking here, to avoid - // having to change code in multiple places. - // A succesful (wrapped) DESFire getVersion command returns - // 9 bytes, with byte 7 0x91 and byte 8 having status - // code 0xAF (these values are fixed and well-known). - int respLength = e->GetArrayLength(respBytes); - jbyte* resp = e->GetByteArrayElements(respBytes, NULL); - if (respLength == 9 && resp[7] == (jbyte)0x91 && - resp[8] == (jbyte)0xAF) { - result = JNI_TRUE; - } - e->ReleaseByteArrayElements(respBytes, (jbyte *)resp, JNI_ABORT); - } - } - e->ReleaseByteArrayElements(pollBytes, (jbyte *)poll, JNI_ABORT); - e->ReleaseByteArrayElements(actBytes, (jbyte *)act, JNI_ABORT); - } - - return result; -} - -static jboolean com_android_nfc_NativeNfcTag_doNdefFormat(JNIEnv *e, jobject o, jbyteArray key) -{ - phLibNfc_Handle handle = 0; - NFCSTATUS status; - phNfc_sData_t keyBuffer; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - handle = nfc_jni_get_connected_handle(e, o); - - keyBuffer.buffer = (uint8_t *)e->GetByteArrayElements(key, NULL); - keyBuffer.length = e->GetArrayLength(key); - TRACE("phLibNfc_RemoteDev_FormatNdef()"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_FormatNdef(handle, &keyBuffer, nfc_jni_formatndef_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_FormatNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_FormatNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if (cb_data.status == NFCSTATUS_SUCCESS) - { - result = JNI_TRUE; - } - -clean_and_return: - e->ReleaseByteArrayElements(key, (jbyte *)keyBuffer.buffer, JNI_ABORT); - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} - -static jboolean com_android_nfc_NativeNfcTag_doMakeReadonly(JNIEnv *e, jobject o, jbyteArray key) -{ - phLibNfc_Handle handle = 0; - NFCSTATUS status; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - phNfc_sData_t keyBuffer; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - handle = nfc_jni_get_connected_handle(e, o); - keyBuffer.buffer = (uint8_t *)e->GetByteArrayElements(key, NULL); - keyBuffer.length = e->GetArrayLength(key); - TRACE("phLibNfc_ConvertToReadOnlyNdef()"); - REENTRANCE_LOCK(); - status = phLibNfc_ConvertToReadOnlyNdef(handle, &keyBuffer, nfc_jni_readonly_callback, - (void *)&cb_data); - REENTRANCE_UNLOCK(); - - if(status != NFCSTATUS_PENDING) - { - ALOGE("pphLibNfc_ConvertToReadOnlyNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_ConvertToReadOnlyNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if (cb_data.status == NFCSTATUS_SUCCESS) - { - result = JNI_TRUE; - } - -clean_and_return: - e->ReleaseByteArrayElements(key, (jbyte *)keyBuffer.buffer, JNI_ABORT); - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doConnect", "(I)I", - (void *)com_android_nfc_NativeNfcTag_doConnect}, - {"doDisconnect", "()Z", - (void *)com_android_nfc_NativeNfcTag_doDisconnect}, - {"doReconnect", "()I", - (void *)com_android_nfc_NativeNfcTag_doReconnect}, - {"doHandleReconnect", "(I)I", - (void *)com_android_nfc_NativeNfcTag_doHandleReconnect}, - {"doTransceive", "([BZ[I)[B", - (void *)com_android_nfc_NativeNfcTag_doTransceive}, - {"doGetNdefType", "(II)I", - (void *)com_android_nfc_NativeNfcTag_doGetNdefType}, - {"doCheckNdef", "([I)I", - (void *)com_android_nfc_NativeNfcTag_doCheckNdef}, - {"doRead", "()[B", - (void *)com_android_nfc_NativeNfcTag_doRead}, - {"doWrite", "([B)Z", - (void *)com_android_nfc_NativeNfcTag_doWrite}, - {"doPresenceCheck", "()Z", - (void *)com_android_nfc_NativeNfcTag_doPresenceCheck}, - {"doIsIsoDepNdefFormatable", "([B[B)Z", - (void *)com_android_nfc_NativeNfcTag_doIsIsoDepNdefFormatable}, - {"doNdefFormat", "([B)Z", - (void *)com_android_nfc_NativeNfcTag_doNdefFormat}, - {"doMakeReadonly", "([B)Z", - (void *)com_android_nfc_NativeNfcTag_doMakeReadonly}, -}; - -int register_com_android_nfc_NativeNfcTag(JNIEnv *e) -{ - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeNfcTag", - gMethods, NELEM(gMethods)); -} - -} // namespace android diff --git a/jni/com_android_nfc_NativeP2pDevice.cpp b/jni/com_android_nfc_NativeP2pDevice.cpp deleted file mode 100644 index b3cc6e3..0000000 --- a/jni/com_android_nfc_NativeP2pDevice.cpp +++ /dev/null @@ -1,490 +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 <semaphore.h> -#include <errno.h> - -#include "com_android_nfc.h" - -extern uint8_t device_connected_flag; - -namespace android { - -extern void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat); - -/* - * Callbacks - */ -static void nfc_jni_presence_check_callback(void* pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_presence_check_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_connect_callback(void *pContext, - phLibNfc_Handle hRemoteDev, - phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - phNfc_sData_t * psGeneralBytes = (phNfc_sData_t *)pCallbackData->pContext; - LOG_CALLBACK("nfc_jni_connect_callback", status); - - if(status == NFCSTATUS_SUCCESS) - { - psGeneralBytes->length = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length; - psGeneralBytes->buffer = (uint8_t*)malloc(psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length); - psGeneralBytes->buffer = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo; - } - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_disconnect_callback(void *pContext, phLibNfc_Handle hRemoteDev, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_disconnect_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_receive_callback(void *pContext, phNfc_sData_t *data, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - phNfc_sData_t **ptr = (phNfc_sData_t **)pCallbackData->pContext; - LOG_CALLBACK("nfc_jni_receive_callback", status); - - if(status == NFCSTATUS_SUCCESS) - { - *ptr = data; - } - else - { - *ptr = NULL; - } - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static void nfc_jni_send_callback(void *pContext, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_send_callback", status); - - /* Report the callback status and wake up the caller */ - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -/* - * Functions - */ - -static void nfc_jni_transceive_callback(void *pContext, - phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status) -{ - struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext; - LOG_CALLBACK("nfc_jni_transceive_callback", status); - - /* Report the callback data and wake up the caller */ - pCallbackData->pContext = pResBuffer; - pCallbackData->status = status; - sem_post(&pCallbackData->sem); -} - -static jboolean com_android_nfc_NativeP2pDevice_doConnect(JNIEnv *e, jobject o) -{ - phLibNfc_Handle handle = 0; - NFCSTATUS status; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - - jclass target_cls = NULL; - jobject tag; - jmethodID ctor; - jfieldID f; - jbyteArray generalBytes = NULL; - phNfc_sData_t sGeneralBytes; - unsigned int i; - - CONCURRENCY_LOCK(); - - handle = nfc_jni_get_p2p_device_handle(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, (void*)&sGeneralBytes)) - { - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_Connect(P2P)"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Connect(handle, nfc_jni_connect_callback, (void*)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Connect(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Connect(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - /* Set General Bytes */ - target_cls = e->GetObjectClass(o); - - f = e->GetFieldID(target_cls, "mGeneralBytes", "[B"); - - TRACE("General Bytes Length = %d", sGeneralBytes.length); - TRACE("General Bytes ="); - for(i=0;i<sGeneralBytes.length;i++) - { - TRACE("0x%02x ", sGeneralBytes.buffer[i]); - } - - generalBytes = e->NewByteArray(sGeneralBytes.length); - - e->SetByteArrayRegion(generalBytes, 0, - sGeneralBytes.length, - (jbyte *)sGeneralBytes.buffer); - - e->SetObjectField(o, f, generalBytes); - - result = JNI_TRUE; - -clean_and_return: - if (result != JNI_TRUE) - { - /* Restart the polling loop if the connection failed */ - nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); - } - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} - -static jboolean com_android_nfc_NativeP2pDevice_doDisconnect(JNIEnv *e, jobject o) -{ - phLibNfc_Handle handle = 0; - jboolean result = JNI_FALSE; - NFCSTATUS status; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - handle = nfc_jni_get_p2p_device_handle(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Disconnect */ - TRACE("Disconnecting from target (handle = 0x%x)", handle); - - /* NativeNfcTag waits for tag to leave the field here with presence check. - * We do not in P2P path because presence check is not safe while transceive may be - * in progress. - */ - - TRACE("phLibNfc_RemoteDev_Disconnect()"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE,nfc_jni_disconnect_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - if(status == NFCSTATUS_TARGET_NOT_CONNECTED) - { - ALOGE("phLibNfc_RemoteDev_Disconnect() failed: Target not connected"); - } - else - { - ALOGE("phLibNfc_RemoteDev_Disconnect() failed"); - nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e)); - } - - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - /* Disconnect Status */ - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - /* Reset device connected flag */ - device_connected_flag = 0; - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} - -static jbyteArray com_android_nfc_NativeP2pDevice_doTransceive(JNIEnv *e, - jobject o, jbyteArray data) -{ - NFCSTATUS status; - uint8_t offset = 2; - uint8_t *buf; - uint32_t buflen; - phLibNfc_sTransceiveInfo_t transceive_info; - jbyteArray result = NULL; - phLibNfc_Handle handle = nfc_jni_get_p2p_device_handle(e, o); - phNfc_sData_t * receive_buffer = NULL; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, (void*)receive_buffer)) - { - goto clean_and_return; - } - - /* Transceive*/ - TRACE("Transceive data to target (handle = 0x%x)", handle); - - buf = (uint8_t *)e->GetByteArrayElements(data, NULL); - buflen = (uint32_t)e->GetArrayLength(data); - - TRACE("Buffer Length = %d\n", buflen); - - transceive_info.sSendData.buffer = buf; //+ offset; - transceive_info.sSendData.length = buflen; //- offset; - transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024); - transceive_info.sRecvData.length = 1024; - - if(transceive_info.sRecvData.buffer == NULL) - { - goto clean_and_return; - } - - TRACE("phLibNfc_RemoteDev_Transceive(P2P)"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info, nfc_jni_transceive_callback, (void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Transceive(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Transceive(P2P) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - /* Copy results back to Java */ - result = e->NewByteArray(receive_buffer->length); - if(result != NULL) - e->SetByteArrayRegion(result, 0, - receive_buffer->length, - (jbyte *)receive_buffer->buffer); - -clean_and_return: - if(transceive_info.sRecvData.buffer != NULL) - { - free(transceive_info.sRecvData.buffer); - } - - e->ReleaseByteArrayElements(data, - (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT); - - nfc_cb_data_deinit(&cb_data); - - CONCURRENCY_UNLOCK(); - - return result; -} - - -static jbyteArray com_android_nfc_NativeP2pDevice_doReceive( - JNIEnv *e, jobject o) -{ - NFCSTATUS status; - struct timespec ts; - phLibNfc_Handle handle; - jbyteArray buf = NULL; - static phNfc_sData_t *data; - struct nfc_jni_callback_data cb_data; - - CONCURRENCY_LOCK(); - - handle = nfc_jni_get_p2p_device_handle(e, o); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, (void*)data)) - { - goto clean_and_return; - } - - /* Receive */ - TRACE("phLibNfc_RemoteDev_Receive()"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Receive(handle, nfc_jni_receive_callback,(void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Receive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Receive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(data == NULL) - { - goto clean_and_return; - } - - buf = e->NewByteArray(data->length); - e->SetByteArrayRegion(buf, 0, data->length, (jbyte *)data->buffer); - -clean_and_return: - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return buf; -} - -static jboolean com_android_nfc_NativeP2pDevice_doSend( - JNIEnv *e, jobject o, jbyteArray buf) -{ - NFCSTATUS status; - phNfc_sData_t data; - jboolean result = JNI_FALSE; - struct nfc_jni_callback_data cb_data; - - phLibNfc_Handle handle = nfc_jni_get_p2p_device_handle(e, o); - - CONCURRENCY_LOCK(); - - /* Create the local semaphore */ - if (!nfc_cb_data_init(&cb_data, NULL)) - { - goto clean_and_return; - } - - /* Send */ - TRACE("Send data to the Initiator (handle = 0x%x)", handle); - - data.length = (uint32_t)e->GetArrayLength(buf); - data.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL); - - TRACE("phLibNfc_RemoteDev_Send()"); - REENTRANCE_LOCK(); - status = phLibNfc_RemoteDev_Send(handle, &data, nfc_jni_send_callback,(void *)&cb_data); - REENTRANCE_UNLOCK(); - if(status != NFCSTATUS_PENDING) - { - ALOGE("phLibNfc_RemoteDev_Send() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - goto clean_and_return; - } - TRACE("phLibNfc_RemoteDev_Send() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status)); - - /* Wait for callback response */ - if(sem_wait(&cb_data.sem)) - { - ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno); - goto clean_and_return; - } - - if(cb_data.status != NFCSTATUS_SUCCESS) - { - goto clean_and_return; - } - - result = JNI_TRUE; - -clean_and_return: - if (result != JNI_TRUE) - { - e->ReleaseByteArrayElements(buf, (jbyte *)data.buffer, JNI_ABORT); - } - nfc_cb_data_deinit(&cb_data); - CONCURRENCY_UNLOCK(); - return result; -} - -/* - * JNI registration. - */ -static JNINativeMethod gMethods[] = -{ - {"doConnect", "()Z", - (void *)com_android_nfc_NativeP2pDevice_doConnect}, - {"doDisconnect", "()Z", - (void *)com_android_nfc_NativeP2pDevice_doDisconnect}, - {"doTransceive", "([B)[B", - (void *)com_android_nfc_NativeP2pDevice_doTransceive}, - {"doReceive", "()[B", - (void *)com_android_nfc_NativeP2pDevice_doReceive}, - {"doSend", "([B)Z", - (void *)com_android_nfc_NativeP2pDevice_doSend}, -}; - -int register_com_android_nfc_NativeP2pDevice(JNIEnv *e) -{ - return jniRegisterNativeMethods(e, - "com/android/nfc/nxp/NativeP2pDevice", - gMethods, NELEM(gMethods)); -} - -} // namepspace android diff --git a/jni/com_android_nfc_list.cpp b/jni/com_android_nfc_list.cpp deleted file mode 100644 index f0487d3..0000000 --- a/jni/com_android_nfc_list.cpp +++ /dev/null @@ -1,210 +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 <com_android_nfc_list.h> -#include <com_android_nfc.h> -#include <pthread.h> -#include <errno.h> -#include <cutils/log.h> - -#undef LOG_TAG -#define LOG_TAG "NFC_LIST" - -bool listInit(listHead* pList) -{ - pList->pFirst = NULL; - if(pthread_mutex_init(&pList->mutex, NULL) == -1) - { - ALOGE("Mutex creation failed (errno=0x%08x)", errno); - return false; - } - - return true; -} - -bool listDestroy(listHead* pList) -{ - bool bListNotEmpty = true; - while (bListNotEmpty) { - bListNotEmpty = listGetAndRemoveNext(pList, NULL); - } - - if(pthread_mutex_destroy(&pList->mutex) == -1) - { - ALOGE("Mutex destruction failed (errno=0x%08x)", errno); - return false; - } - - return true; -} - -bool listAdd(listHead* pList, void* pData) -{ - struct listNode* pNode; - struct listNode* pLastNode; - bool result; - - /* Create node */ - pNode = (struct listNode*)malloc(sizeof(listNode)); - if (pNode == NULL) - { - result = false; - ALOGE("Failed to malloc"); - goto clean_and_return; - } - TRACE("Allocated node: %8p (%8p)", pNode, pData); - pNode->pData = pData; - pNode->pNext = NULL; - - pthread_mutex_lock(&pList->mutex); - - /* Add the node to the list */ - if (pList->pFirst == NULL) - { - /* Set the node as the head */ - pList->pFirst = pNode; - } - else - { - /* Seek to the end of the list */ - pLastNode = pList->pFirst; - while(pLastNode->pNext != NULL) - { - pLastNode = pLastNode->pNext; - } - - /* Add the node to the current list */ - pLastNode->pNext = pNode; - } - - result = true; - -clean_and_return: - pthread_mutex_unlock(&pList->mutex); - return result; -} - -bool listRemove(listHead* pList, void* pData) -{ - struct listNode* pNode; - struct listNode* pRemovedNode; - bool result; - - pthread_mutex_lock(&pList->mutex); - - if (pList->pFirst == NULL) - { - /* Empty list */ - ALOGE("Failed to deallocate (list empty)"); - result = false; - goto clean_and_return; - } - - pNode = pList->pFirst; - if (pList->pFirst->pData == pData) - { - /* Get the removed node */ - pRemovedNode = pNode; - - /* Remove the first node */ - pList->pFirst = pList->pFirst->pNext; - } - else - { - while (pNode->pNext != NULL) - { - if (pNode->pNext->pData == pData) - { - /* Node found ! */ - break; - } - pNode = pNode->pNext; - } - - if (pNode->pNext == NULL) - { - /* Node not found */ - result = false; - ALOGE("Failed to deallocate (not found %8p)", pData); - goto clean_and_return; - } - - /* Get the removed node */ - pRemovedNode = pNode->pNext; - - /* Remove the node from the list */ - pNode->pNext = pNode->pNext->pNext; - } - - /* Deallocate the node */ - TRACE("Deallocating node: %8p (%8p)", pRemovedNode, pRemovedNode->pData); - free(pRemovedNode); - - result = true; - -clean_and_return: - pthread_mutex_unlock(&pList->mutex); - return result; -} - -bool listGetAndRemoveNext(listHead* pList, void** ppData) -{ - struct listNode* pNode; - bool result; - - pthread_mutex_lock(&pList->mutex); - - if (pList->pFirst) - { - /* Empty list */ - ALOGE("Failed to deallocate (list empty)"); - result = false; - goto clean_and_return; - } - - /* Work on the first node */ - pNode = pList->pFirst; - - /* Return the data */ - if (ppData != NULL) - { - *ppData = pNode->pData; - } - - /* Remove and deallocate the node */ - pList->pFirst = pNode->pNext; - TRACE("Deallocating node: %8p (%8p)", pNode, pNode->pData); - free(pNode); - - result = true; - -clean_and_return: - listDump(pList); - pthread_mutex_unlock(&pList->mutex); - return result; -} - -void listDump(listHead* pList) -{ - struct listNode* pNode = pList->pFirst; - - TRACE("Node dump:"); - while (pNode != NULL) - { - TRACE("- %8p (%8p)", pNode, pNode->pData); - pNode = pNode->pNext; - } -} diff --git a/jni/com_android_nfc_list.h b/jni/com_android_nfc_list.h deleted file mode 100644 index 22b4f09..0000000 --- a/jni/com_android_nfc_list.h +++ /dev/null @@ -1,49 +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. - */ - -#ifndef __COM_ANDROID_NFC_LIST_H__ -#define __COM_ANDROID_NFC_LIST_H__ - -#include <pthread.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct listNode -{ - void* pData; - struct listNode* pNext; -}; - -struct listHead -{ - listNode* pFirst; - pthread_mutex_t mutex; -}; - -bool listInit(listHead* pList); -bool listDestroy(listHead* pList); -bool listAdd(listHead* pList, void* pData); -bool listRemove(listHead* pList, void* pData); -bool listGetAndRemoveNext(listHead* pList, void** ppData); -void listDump(listHead* pList); - -#ifdef __cplusplus -} -#endif - -#endif /* __COM_ANDROID_NFC_LIST_H__ */ |