1f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* 2f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Copyright (C) 2010 The Android Open Source Project 3f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 4f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * you may not use this file except in compliance with the License. 6f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * You may obtain a copy of the License at 7f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 8f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 10f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Unless required by applicable law or agreed to in writing, software 11f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * See the License for the specific language governing permissions and 14f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * limitations under the License. 15f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */ 16f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 170412f53e664083dc5307bbcf18c0002b26180203Nick Pelly#include <stdlib.h> 180412f53e664083dc5307bbcf18c0002b26180203Nick Pelly 19f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly#include "errno.h" 20c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly#include "com_android_nfc.h" 21b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau#include "com_android_nfc_list.h" 22f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly#include "phLibNfcStatus.h" 23f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly/* 2513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly * JNI Initialization 2613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly */ 2713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyjint JNI_OnLoad(JavaVM *jvm, void *reserved) 2813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly{ 2913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly JNIEnv *e; 3013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 3116fade071b801dc3632b387bc9aaece1afa28120Sylvain Fonteneau LOGD("NFC Service : loading JNI\n"); 3213d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 3313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly // Check JNI version 3413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6)) 3513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 3613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 370412f53e664083dc5307bbcf18c0002b26180203Nick Pelly android::vm = jvm; 380412f53e664083dc5307bbcf18c0002b26180203Nick Pelly 3913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if (android::register_com_android_nfc_NativeNfcManager(e) == -1) 4013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 4113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if (android::register_com_android_nfc_NativeNfcTag(e) == -1) 4213d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 4313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if (android::register_com_android_nfc_NativeP2pDevice(e) == -1) 4413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 4513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if (android::register_com_android_nfc_NativeLlcpSocket(e) == -1) 4613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 4713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if (android::register_com_android_nfc_NativeLlcpConnectionlessSocket(e) == -1) 4813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 4913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly if (android::register_com_android_nfc_NativeLlcpServiceSocket(e) == -1) 5013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_ERR; 510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (android::register_com_android_nfc_NativeNfcSecureElement(e) == -1) 520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return JNI_ERR; 5313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 5413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly return JNI_VERSION_1_6; 5513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly} 5613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 57f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellynamespace android { 58f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 59c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyextern struct nfc_jni_native_data *exported_nat; 60f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 610412f53e664083dc5307bbcf18c0002b26180203Nick PellyJavaVM *vm; 620412f53e664083dc5307bbcf18c0002b26180203Nick Pelly 63f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* 64f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * JNI Utils 65f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */ 660412f53e664083dc5307bbcf18c0002b26180203Nick PellyJNIEnv *nfc_get_env() 670412f53e664083dc5307bbcf18c0002b26180203Nick Pelly{ 680412f53e664083dc5307bbcf18c0002b26180203Nick Pelly JNIEnv *e; 690412f53e664083dc5307bbcf18c0002b26180203Nick Pelly if (vm->GetEnv((void **)&e, JNI_VERSION_1_6) != JNI_OK) { 700412f53e664083dc5307bbcf18c0002b26180203Nick Pelly LOGE("Current thread is not attached to VM"); 710412f53e664083dc5307bbcf18c0002b26180203Nick Pelly abort(); 720412f53e664083dc5307bbcf18c0002b26180203Nick Pelly } 730412f53e664083dc5307bbcf18c0002b26180203Nick Pelly return e; 740412f53e664083dc5307bbcf18c0002b26180203Nick Pelly} 750412f53e664083dc5307bbcf18c0002b26180203Nick Pelly 76b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneaubool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext) 77b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau{ 78b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Create semaphore */ 79b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(sem_init(&pCallbackData->sem, 0, 0) == -1) 80b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 81b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau LOGE("Semaphore creation failed (errno=0x%08x)", errno); 82b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau return false; 83b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 84b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 85b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Set default status value */ 86b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = NFCSTATUS_FAILED; 87b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 88b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Copy the context */ 89b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->pContext = pContext; 90b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 91b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Add to active semaphore list */ 92b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!listAdd(&nfc_jni_get_monitor()->sem_list, pCallbackData)) 93b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 94b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau LOGE("Failed to add the semaphore to the list"); 95b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 96b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 97b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau return true; 98b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau} 99b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 100b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneauvoid nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData) 101b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau{ 102b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Destroy semaphore */ 103b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (sem_destroy(&pCallbackData->sem)) 104b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 105b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau LOGE("Failed to destroy semaphore (errno=0x%08x)", errno); 106b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 107b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 108b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau /* Remove from active semaphore list */ 109b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if (!listRemove(&nfc_jni_get_monitor()->sem_list, pCallbackData)) 110b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 111b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau LOGE("Failed to remove semaphore from the list"); 112b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 113b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 114b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau} 115b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 116b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneauvoid nfc_cb_data_releaseAll() 117b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau{ 118b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau nfc_jni_callback_data* pCallbackData; 119b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 120b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau while (listGetAndRemoveNext(&nfc_jni_get_monitor()->sem_list, (void**)&pCallbackData)) 121b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 122b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau pCallbackData->status = NFCSTATUS_FAILED; 123b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau sem_post(&pCallbackData->sem); 124b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 125b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau} 126b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 127c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyint nfc_jni_cache_object(JNIEnv *e, const char *clsname, 128f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jobject *cached_obj) 129f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jclass cls; 131f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jobject obj; 132f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jmethodID ctor; 133f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 134f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly cls = e->FindClass(clsname); 135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(cls == NULL) 136f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 137f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return -1; 138f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LOGD("Find class error\n"); 139f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 140f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 141f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 142f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly ctor = e->GetMethodID(cls, "<init>", "()V"); 143f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 144f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly obj = e->NewObject(cls, ctor); 145f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(obj == NULL) 146f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 147f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return -1; 148f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LOGD("Create object error\n"); 149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 150f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 151f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly *cached_obj = e->NewGlobalRef(obj); 152f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if(*cached_obj == NULL) 153f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 154f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly e->DeleteLocalRef(obj); 155f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LOGD("Global ref error\n"); 156f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return -1; 157f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 158f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 159f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly e->DeleteLocalRef(obj); 160f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 161f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return 0; 162f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 163f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 164f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 165c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystruct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o) 166f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 167f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jclass c; 168f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jfieldID f; 169f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 170f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Retrieve native structure address */ 171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly c = e->GetObjectClass(o); 172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly f = e->GetFieldID(c, "mNative", "I"); 173c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly return (struct nfc_jni_native_data*)e->GetIntField(o, f); 174f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 175f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 176c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystruct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e) 177f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 178f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return exported_nat; 179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 180f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 181c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic nfc_jni_native_monitor_t *nfc_jni_native_monitor = NULL; 182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 183c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellynfc_jni_native_monitor_t* nfc_jni_init_monitor(void) 184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly pthread_mutexattr_t recursive_attr; 187f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 188f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly pthread_mutexattr_init(&recursive_attr); 189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly pthread_mutexattr_settype(&recursive_attr, PTHREAD_MUTEX_RECURSIVE_NP); 190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 191c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(nfc_jni_native_monitor == NULL) 192f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 193c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly nfc_jni_native_monitor = (nfc_jni_native_monitor_t*)malloc(sizeof(nfc_jni_native_monitor_t)); 194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 196c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(nfc_jni_native_monitor != NULL) 197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 198c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly memset(nfc_jni_native_monitor, 0, sizeof(nfc_jni_native_monitor_t)); 199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 200c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(pthread_mutex_init(&nfc_jni_native_monitor->reentrance_mutex, &recursive_attr) == -1) 201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 2022692a3cabf0344ef3121cec3c7f87bfc987e2d70Sylvain Fonteneau LOGE("NFC Manager Reentrance Mutex creation returned 0x%08x", errno); 203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return NULL; 204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 206c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly if(pthread_mutex_init(&nfc_jni_native_monitor->concurrency_mutex, NULL) == -1) 207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 2082692a3cabf0344ef3121cec3c7f87bfc987e2d70Sylvain Fonteneau LOGE("NFC Manager Concurrency Mutex creation returned 0x%08x", errno); 209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return NULL; 210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 211b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau 212b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau if(!listInit(&nfc_jni_native_monitor->sem_list)) 213b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau { 2142692a3cabf0344ef3121cec3c7f87bfc987e2d70Sylvain Fonteneau LOGE("NFC Manager Semaphore List creation failed"); 215b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau return NULL; 216b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau } 21752e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau 21852e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau LIST_INIT(&nfc_jni_native_monitor->incoming_socket_head); 21952e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau 22052e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau if(pthread_mutex_init(&nfc_jni_native_monitor->incoming_socket_mutex, NULL) == -1) 22152e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau { 22252e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau LOGE("NFC Manager incoming socket mutex creation returned 0x%08x", errno); 22352e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau return NULL; 22452e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau } 22552e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau 22652e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau if(pthread_cond_init(&nfc_jni_native_monitor->incoming_socket_cond, NULL) == -1) 22752e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau { 22852e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau LOGE("NFC Manager incoming socket condition creation returned 0x%08x", errno); 22952e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau return NULL; 23052e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau } 23152e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau 23252e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau} 233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 234c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly return nfc_jni_native_monitor; 235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 237c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellynfc_jni_native_monitor_t* nfc_jni_get_monitor(void) 238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 239c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly return nfc_jni_native_monitor; 240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 243c2fdb614879c601b5162d5d93d705b05c7b1e072Nick PellyphLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o) 244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jclass c; 246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jfieldID f; 247f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly c = e->GetObjectClass(o); 249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly f = e->GetFieldID(c, "mHandle", "I"); 250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return e->GetIntField(o, f); 252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 254c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyjshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o) 255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jclass c; 257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jfieldID f; 258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 259f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly c = e->GetObjectClass(o); 260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly f = e->GetFieldID(c, "mMode", "S"); 261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return e->GetShortField(o, f); 263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 266bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenenint nfc_jni_get_connected_tech_index(JNIEnv *e, jobject o) 267bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen{ 268bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 269bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jclass c; 270bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jfieldID f; 271bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 272bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen c = e->GetObjectClass(o); 273bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen f = e->GetFieldID(c, "mConnectedTechnology", "I"); 274bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 275bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return e->GetIntField(o, f); 276bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 277bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen} 278bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 279bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenenjint nfc_jni_get_connected_technology(JNIEnv *e, jobject o) 280bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen{ 281bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jclass c; 282bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jfieldID f; 283bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen int connectedTech = -1; 284bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 285bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o); 286bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jintArray techTypes = nfc_jni_get_nfc_tag_type(e, o); 287bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 288bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen if ((connectedTechIndex != -1) && (techTypes != NULL) && 289bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen (connectedTechIndex < e->GetArrayLength(techTypes))) { 290bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jint* technologies = e->GetIntArrayElements(techTypes, 0); 291bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen if (technologies != NULL) { 292bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen connectedTech = technologies[connectedTechIndex]; 293bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen e->ReleaseIntArrayElements(techTypes, technologies, JNI_ABORT); 294bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 295bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 296bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 297bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return connectedTech; 298bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 299bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen} 300bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 3010a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenenjint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o) 3020a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen{ 3030a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen jclass c; 3040a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen jfieldID f; 3050a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen jint connectedLibNfcType = -1; 3060a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen 3070a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o); 3080a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen c = e->GetObjectClass(o); 3090a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen f = e->GetFieldID(c, "mTechLibNfcTypes", "[I"); 3100a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen jintArray libNfcTypes = (jintArray) e->GetObjectField(o, f); 3110a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen 3120a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen if ((connectedTechIndex != -1) && (libNfcTypes != NULL) && 3130a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen (connectedTechIndex < e->GetArrayLength(libNfcTypes))) { 3140a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen jint* types = e->GetIntArrayElements(libNfcTypes, 0); 3150a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen if (types != NULL) { 3160a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen connectedLibNfcType = types[connectedTechIndex]; 3170a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen e->ReleaseIntArrayElements(libNfcTypes, types, JNI_ABORT); 3180a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen } 3190a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen } 3200a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen return connectedLibNfcType; 3210a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen 3220a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen} 3230a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen 324bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn CoenenphLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o) 325bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen{ 326bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jclass c; 327bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jfieldID f; 328bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen phLibNfc_Handle connectedHandle = -1; 329bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 330bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o); 331bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen c = e->GetObjectClass(o); 332bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen f = e->GetFieldID(c, "mTechHandles", "[I"); 333bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jintArray techHandles = (jintArray) e->GetObjectField(o, f); 334bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 335bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen if ((connectedTechIndex != -1) && (techHandles != NULL) && 336bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen (connectedTechIndex < e->GetArrayLength(techHandles))) { 337bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen jint* handles = e->GetIntArrayElements(techHandles, 0); 338bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen if (handles != NULL) { 339bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen connectedHandle = handles[connectedTechIndex]; 340bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen e->ReleaseIntArrayElements(techHandles, handles, JNI_ABORT); 341bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 342bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen } 343bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return connectedHandle; 344bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 345bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen} 346bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen 347c2fdb614879c601b5162d5d93d705b05c7b1e072Nick PellyphLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o) 348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jclass c; 350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jfieldID f; 351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly c = e->GetObjectClass(o); 353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly f = e->GetFieldID(c, "mHandle", "I"); 354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 355f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return e->GetIntField(o, f); 356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 357f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 3586d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn CoenenjintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o) 359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jclass c; 361f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly jfieldID f; 3626d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen jintArray techtypes; 363f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 364f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly c = e->GetObjectClass(o); 3656d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen f = e->GetFieldID(c, "mTechList","[I"); 366f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 3676d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen /* Read the techtypes */ 3686d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen techtypes = (jintArray) e->GetObjectField(o, f); 3696d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen 3706d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen return techtypes; 371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly//Display status code 376c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyconst char* nfc_jni_get_status_name(NFCSTATUS status) 377f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{ 378f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly #define STATUS_ENTRY(status) { status, #status } 379f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 380f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly struct status_entry { 381f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NFCSTATUS code; 382f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly const char *name; 383f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 384f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 385f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly const struct status_entry sNameTable[] = { 386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_SUCCESS), 387f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_FAILED), 388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_PARAMETER), 389f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_RESOURCES), 390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_TARGET_LOST), 391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_HANDLE), 392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_MULTIPLE_TAGS), 393f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_ALREADY_REGISTERED), 394f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_FEATURE_NOT_SUPPORTED), 395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_SHUTDOWN), 396f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_ABORTED), 397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_REJECTED ), 398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_NOT_INITIALISED), 399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_PENDING), 400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_BUFFER_TOO_SMALL), 401f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_ALREADY_INITIALISED), 402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_BUSY), 403f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_TARGET_NOT_CONNECTED), 404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_MULTIPLE_PROTOCOLS), 405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_DESELECTED), 406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_DEVICE), 407f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_MORE_INFORMATION), 408f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_RF_TIMEOUT), 409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_RF_ERROR), 410f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_BOARD_COMMUNICATION_ERROR), 411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_STATE), 412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_NOT_REGISTERED), 413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_RELEASED), 414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_NOT_ALLOWED), 415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_REMOTE_DEVICE), 416f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED), 417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_READ_FAILED), 418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_WRITE_FAILED), 419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_NO_NDEF_SUPPORT), 420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_EOF_NDEF_CONTAINER_REACHED), 421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_RECEIVE_LENGTH), 422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INVALID_FORMAT), 423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_STORAGE), 424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly STATUS_ENTRY(NFCSTATUS_FORMAT_ERROR), 425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 426f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly int i = sizeof(sNameTable)/sizeof(status_entry); 428f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly while(i>0) 430f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 431f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly i--; 432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (sNameTable[i].code == PHNFCSTATUS(status)) 433f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly { 434f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return sNameTable[i].name; 435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 436f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 438f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return "UNKNOWN"; 439f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} 440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 4410a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenenint addTechIfNeeded(int *techList, int* handleList, int* typeList, int listSize, 4420a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen int maxListSize, int techToAdd, int handleToAdd, int typeToAdd) { 4434f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen bool found = false; 4444f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen for (int i = 0; i < listSize; i++) { 4454f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen if (techList[i] == techToAdd) { 4464f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen found = true; 4474f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen break; 4484f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 4494f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 4504f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen if (!found && listSize < maxListSize) { 4514f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen techList[listSize] = techToAdd; 4524f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen handleList[listSize] = handleToAdd; 4530a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen typeList[listSize] = typeToAdd; 4544f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen return listSize + 1; 4554f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 4564f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen else { 4574f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen return listSize; 4584f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 4594f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen} 4604f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen 4614f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen 4624f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen#define MAX_NUM_TECHNOLOGIES 32 4634f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen 4640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/* 4654f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen * Utility to get a technology tree and a corresponding handle list from a detected tag. 4660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */ 4674f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenenvoid nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList, 4680a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen uint8_t count, jintArray* techList, jintArray* handleList, 4690a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen jintArray* libnfcTypeList) 4700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{ 4714f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen int technologies[MAX_NUM_TECHNOLOGIES]; 4724f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen int handles[MAX_NUM_TECHNOLOGIES]; 4730a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen int libnfctypes[MAX_NUM_TECHNOLOGIES]; 4740a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen 4754f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen int index = 0; 476ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // TODO: This counts from up to down because on multi-protocols, the 477ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // ISO handle is usually the second, and we prefer the ISO. Should implement 478ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // a method to find the "preferred handle order" and use that instead, 479ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // since we shouldn't have dependencies on the tech list ordering. 480ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen for (int target = count - 1; target >= 0; target--) { 4814f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen int type = devList[target].psRemoteDevInfo->RemDevType; 4824f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen int handle = devList[target].hTargetDev; 4834f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen switch (type) 4844f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 4854f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eISO14443_A_PICC: 4864f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eISO14443_4A_PICC: 4874f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 4880a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, index, 4890a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type); 4900a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, index, 4910a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); 4926d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen break; 4934f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 4944f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eISO14443_4B_PICC: 4954f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 4960a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, index, 4970a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type); 4980a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, index, 4990a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type); 5004f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5014f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eISO14443_3A_PICC: 5024f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 5030a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5040a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); 5054f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5064f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eISO14443_B_PICC: 5074f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 5084f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen // TODO a bug in libnfc will cause 14443-3B only cards 5094f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen // to be returned as this type as well, but these cards 5104f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen // are very rare. Hence assume it's -4B 5110a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5120a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type); 5130a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5140a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type); 5154f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5164f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eISO15693_PICC: 5174f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 5180a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5190a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO15693, handle, type); 5204f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5214f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eMifare_PICC: 5224f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 523c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen // We don't want to be too clever here; libnfc has already determined 524c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen // it's a Mifare, so we only check for UL, for all other tags 525c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen // we assume it's a mifare classic. This should make us more 526c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen // future-proof. 5274f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen int sak = devList[target].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak; 5284f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen switch(sak) 5290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas { 5304f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case 0x00: 5314f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen // could be UL or UL-C 5320a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5330a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_UL, handle, type); 5340a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5350a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); 5364f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen break; 537c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen default: 5380a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5390a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_CLASSIC, handle, type); 5400a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5410a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); 5424f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen break; 5434f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 5444f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5454f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eFelica_PICC: 5464f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 5470a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5480a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_FELICA, handle, type); 5494f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5504f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen case phNfc_eJewel_PICC: 5514f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 5520a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen // Jewel represented as NfcA 5530a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5540a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type); 5554f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen }break; 5564f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen default: 5574f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen { 5580a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index = addTechIfNeeded(technologies, handles, libnfctypes, 5590a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_UNKNOWN, handle, type); 5604f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 5610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 5620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 5636a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton 5644f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen // Build the Java arrays 5656a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton if (techList != NULL) { 5666a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton *techList = e->NewIntArray(index); 5676a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton jint* techItems = e->GetIntArrayElements(*techList, NULL); 5686a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton for (int i = 0; i < index; i++) { 5696a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton techItems[i] = technologies[i]; 5706a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton } 5716a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton e->ReleaseIntArrayElements(*techList, techItems, 0); 5726a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton } 5736a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton 5746a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton if (handleList != NULL) { 5756a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton *handleList = e->NewIntArray(index); 5766a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton jint* handleItems = e->GetIntArrayElements(*handleList, NULL); 5776a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton for (int i = 0; i < index; i++) { 5786a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton handleItems[i] = handles[i]; 5796a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton } 5806a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton e->ReleaseIntArrayElements(*handleList, handleItems, 0); 5814f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen } 5820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 5836a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton if (libnfcTypeList != NULL) { 5846a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton *libnfcTypeList = e->NewIntArray(index); 5856a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton 5866a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton jint* typeItems = e->GetIntArrayElements(*libnfcTypeList, NULL); 5876a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton for (int i = 0; i < index; i++) { 5886a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton typeItems[i] = libnfctypes[i]; 5896a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton } 5906a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton e->ReleaseIntArrayElements(*libnfcTypeList, typeItems, 0); 5916a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton } 5920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas} 5930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 594f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} // namespace android 595