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"
232534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes#include <ScopedLocalRef.h>
24f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
2513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly/*
2613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly * JNI Initialization
2713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly */
2813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyjint JNI_OnLoad(JavaVM *jvm, void *reserved)
2913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly{
3013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   JNIEnv *e;
3113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
322534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ALOGI("NFC Service: loading nxp JNI");
3313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
3413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   // Check JNI version
3513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6))
3613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
3713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
380412f53e664083dc5307bbcf18c0002b26180203Nick Pelly   android::vm = jvm;
390412f53e664083dc5307bbcf18c0002b26180203Nick Pelly
4013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if (android::register_com_android_nfc_NativeNfcManager(e) == -1)
4113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
4213d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if (android::register_com_android_nfc_NativeNfcTag(e) == -1)
4313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
4413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if (android::register_com_android_nfc_NativeP2pDevice(e) == -1)
4513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
4613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if (android::register_com_android_nfc_NativeLlcpSocket(e) == -1)
4713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
4813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if (android::register_com_android_nfc_NativeLlcpConnectionlessSocket(e) == -1)
4913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
5013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   if (android::register_com_android_nfc_NativeLlcpServiceSocket(e) == -1)
5113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      return JNI_ERR;
520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   if (android::register_com_android_nfc_NativeNfcSecureElement(e) == -1)
530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas      return JNI_ERR;
5413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
5513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly   return JNI_VERSION_1_6;
5613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly}
5713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly
58f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellynamespace android {
59f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
60c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyextern struct nfc_jni_native_data *exported_nat;
61f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
620412f53e664083dc5307bbcf18c0002b26180203Nick PellyJavaVM *vm;
630412f53e664083dc5307bbcf18c0002b26180203Nick Pelly
64f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/*
65f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * JNI Utils
66f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */
670412f53e664083dc5307bbcf18c0002b26180203Nick PellyJNIEnv *nfc_get_env()
680412f53e664083dc5307bbcf18c0002b26180203Nick Pelly{
690412f53e664083dc5307bbcf18c0002b26180203Nick Pelly    JNIEnv *e;
700412f53e664083dc5307bbcf18c0002b26180203Nick Pelly    if (vm->GetEnv((void **)&e, JNI_VERSION_1_6) != JNI_OK) {
71afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block        ALOGE("Current thread is not attached to VM");
7216c9bd97838d7004f39269290b8a3c147d90d1c7Sunil Jogi        phLibNfc_Mgt_Recovery();
730412f53e664083dc5307bbcf18c0002b26180203Nick Pelly        abort();
740412f53e664083dc5307bbcf18c0002b26180203Nick Pelly    }
750412f53e664083dc5307bbcf18c0002b26180203Nick Pelly    return e;
760412f53e664083dc5307bbcf18c0002b26180203Nick Pelly}
770412f53e664083dc5307bbcf18c0002b26180203Nick Pelly
78b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneaubool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext)
79b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau{
80b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   /* Create semaphore */
81b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   if(sem_init(&pCallbackData->sem, 0, 0) == -1)
82b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   {
83afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("Semaphore creation failed (errno=0x%08x)", errno);
84b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau      return false;
85b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   }
86b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
87b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   /* Set default status value */
88b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   pCallbackData->status = NFCSTATUS_FAILED;
89b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
90b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   /* Copy the context */
91b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   pCallbackData->pContext = pContext;
92b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
93b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   /* Add to active semaphore list */
94b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   if (!listAdd(&nfc_jni_get_monitor()->sem_list, pCallbackData))
95b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   {
96afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("Failed to add the semaphore to the list");
97b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   }
98b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
99b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   return true;
100b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau}
101b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
102b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneauvoid nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData)
103b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau{
104b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   /* Destroy semaphore */
105b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   if (sem_destroy(&pCallbackData->sem))
106b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   {
107afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("Failed to destroy semaphore (errno=0x%08x)", errno);
108b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   }
109b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
110b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   /* Remove from active semaphore list */
111b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   if (!listRemove(&nfc_jni_get_monitor()->sem_list, pCallbackData))
112b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   {
113afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block      ALOGE("Failed to remove semaphore from the list");
114b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   }
115b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
116b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau}
117b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
118b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneauvoid nfc_cb_data_releaseAll()
119b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau{
120b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   nfc_jni_callback_data* pCallbackData;
121b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
122b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   while (listGetAndRemoveNext(&nfc_jni_get_monitor()->sem_list, (void**)&pCallbackData))
123b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   {
124b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau      pCallbackData->status = NFCSTATUS_FAILED;
125b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau      sem_post(&pCallbackData->sem);
126b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau   }
127b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau}
128b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
129c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyint nfc_jni_cache_object(JNIEnv *e, const char *clsname,
130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jobject *cached_obj)
131f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
1322534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> cls(e, e->FindClass(clsname));
1332534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   if (cls.get() == NULL) {
1347d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block      ALOGD("Find class error\n");
1352534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes      return -1;
136f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
137f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1382534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jmethodID ctor = e->GetMethodID(cls.get(), "<init>", "()V");
1392534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jobject> obj(e, e->NewObject(cls.get(), ctor));
1402534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   if (obj.get() == NULL) {
1417d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block      ALOGD("Create object error\n");
1422534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes      return -1;
143f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
144f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
1452534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   *cached_obj = e->NewGlobalRef(obj.get());
1462534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   if (*cached_obj == NULL) {
1477d4e962f71c5db6d71aca046bd1416f53a10653bSteve Block      ALOGD("Global ref error\n");
148f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      return -1;
149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
150f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
151f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return 0;
152f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
153f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
154f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
155c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystruct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o)
156f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
157f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Retrieve native structure address */
1582534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
1592534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mNative", "I");
1602534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   return (struct nfc_jni_native_data*) e->GetIntField(o, f);
161f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
162f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
163c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystruct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e)
164f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
165f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return exported_nat;
166f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
167f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
168c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic nfc_jni_native_monitor_t *nfc_jni_native_monitor = NULL;
169f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
170c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellynfc_jni_native_monitor_t* nfc_jni_init_monitor(void)
171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   pthread_mutexattr_t recursive_attr;
174f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
175f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   pthread_mutexattr_init(&recursive_attr);
176f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   pthread_mutexattr_settype(&recursive_attr, PTHREAD_MUTEX_RECURSIVE_NP);
177f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
178c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_native_monitor == NULL)
179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
180c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      nfc_jni_native_monitor = (nfc_jni_native_monitor_t*)malloc(sizeof(nfc_jni_native_monitor_t));
181f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
183c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_native_monitor != NULL)
184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
185c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      memset(nfc_jni_native_monitor, 0, sizeof(nfc_jni_native_monitor_t));
186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
187c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      if(pthread_mutex_init(&nfc_jni_native_monitor->reentrance_mutex, &recursive_attr) == -1)
188f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
189afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("NFC Manager Reentrance Mutex creation returned 0x%08x", errno);
190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly         return NULL;
191f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
192f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
193c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      if(pthread_mutex_init(&nfc_jni_native_monitor->concurrency_mutex, NULL) == -1)
194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
195afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("NFC Manager Concurrency Mutex creation returned 0x%08x", errno);
196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly         return NULL;
197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
198b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau
199b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau      if(!listInit(&nfc_jni_native_monitor->sem_list))
200b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau      {
201afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("NFC Manager Semaphore List creation failed");
202b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau         return NULL;
203b78172c6c46957cc37786b690db9bc854b26b7f9Sylvain Fonteneau      }
20452e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau
20552e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      LIST_INIT(&nfc_jni_native_monitor->incoming_socket_head);
20652e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau
20752e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      if(pthread_mutex_init(&nfc_jni_native_monitor->incoming_socket_mutex, NULL) == -1)
20852e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      {
209afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("NFC Manager incoming socket mutex creation returned 0x%08x", errno);
21052e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau         return NULL;
21152e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      }
21252e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau
21352e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      if(pthread_cond_init(&nfc_jni_native_monitor->incoming_socket_cond, NULL) == -1)
21452e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      {
215afc8705e932af9a3a27239b0ca6fdb2026f15dfcSteve Block         ALOGE("NFC Manager incoming socket condition creation returned 0x%08x", errno);
21652e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau         return NULL;
21752e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau      }
21852e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau
21952e3711950d017debd9f1783a33a0c9ac90dd51bSylvain Fonteneau}
220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
221c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   return nfc_jni_native_monitor;
2222534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes}
223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
224c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellynfc_jni_native_monitor_t* nfc_jni_get_monitor(void)
225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
226c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   return nfc_jni_native_monitor;
227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
2282534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes
229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
230c2fdb614879c601b5162d5d93d705b05c7b1e072Nick PellyphLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o)
231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
2322534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
2332534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mHandle", "I");
234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return e->GetIntField(o, f);
235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
237c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyjshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o)
238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
2392534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
2402534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mMode", "S");
241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return e->GetShortField(o, f);
242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
245bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenenint nfc_jni_get_connected_tech_index(JNIEnv *e, jobject o)
246bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen{
2472534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
2482534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mConnectedTechIndex", "I");
249bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   return e->GetIntField(o, f);
250bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
251bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen}
252bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
253bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenenjint nfc_jni_get_connected_technology(JNIEnv *e, jobject o)
254bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen{
255bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   int connectedTech = -1;
256bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
257bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o);
258bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   jintArray techTypes = nfc_jni_get_nfc_tag_type(e, o);
259bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
260bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   if ((connectedTechIndex != -1) && (techTypes != NULL) &&
261bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen           (connectedTechIndex < e->GetArrayLength(techTypes))) {
262bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen       jint* technologies = e->GetIntArrayElements(techTypes, 0);
263bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen       if (technologies != NULL) {
264bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen           connectedTech = technologies[connectedTechIndex];
265bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen           e->ReleaseIntArrayElements(techTypes, technologies, JNI_ABORT);
266bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen       }
267bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   }
268bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
269bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen   return connectedTech;
270bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
271bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen}
272bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
2730a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenenjint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o)
2740a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen{
2750a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen   jint connectedLibNfcType = -1;
2760a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen
2770a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen   int connectedTechIndex = nfc_jni_get_connected_tech_index(e,o);
2782534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
2792534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mTechLibNfcTypes", "[I");
2802534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jintArray> libNfcTypes(e, (jintArray) e->GetObjectField(o, f));
2810a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen
2822534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   if ((connectedTechIndex != -1) && (libNfcTypes.get() != NULL) &&
2832534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes           (connectedTechIndex < e->GetArrayLength(libNfcTypes.get()))) {
2842534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       jint* types = e->GetIntArrayElements(libNfcTypes.get(), 0);
2850a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen       if (types != NULL) {
2860a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen           connectedLibNfcType = types[connectedTechIndex];
2872534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes           e->ReleaseIntArrayElements(libNfcTypes.get(), types, JNI_ABORT);
2880a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen       }
2890a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen   }
2900a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen   return connectedLibNfcType;
2910a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen}
2920a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen
293bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn CoenenphLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o)
294bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen{
2952534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
2962534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mConnectedHandle", "I");
2973fb14d0868594c78a777e805545209636814e223Martijn Coenen   return e->GetIntField(o, f);
298bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen}
299bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen
300c2fdb614879c601b5162d5d93d705b05c7b1e072Nick PellyphLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o)
301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
3022534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
3032534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mHandle", "I");
304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return e->GetIntField(o, f);
305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3076d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn CoenenjintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o)
308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
3092534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   ScopedLocalRef<jclass> c(e, e->GetObjectClass(o));
3102534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   jfieldID f = e->GetFieldID(c.get(), "mTechList","[I");
3112534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes   return (jintArray) e->GetObjectField(o, f);
312f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
313f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly//Display status code
317c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyconst char* nfc_jni_get_status_name(NFCSTATUS status)
318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   #define STATUS_ENTRY(status) { status, #status }
3202534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes
321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   struct status_entry {
322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      NFCSTATUS   code;
323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      const char  *name;
324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   };
325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   const struct status_entry sNameTable[] = {
327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_SUCCESS),
328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_FAILED),
329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_PARAMETER),
330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_RESOURCES),
331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_TARGET_LOST),
332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_HANDLE),
333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_MULTIPLE_TAGS),
334f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_ALREADY_REGISTERED),
335f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_FEATURE_NOT_SUPPORTED),
336f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_SHUTDOWN),
337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_ABORTED),
338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_REJECTED ),
339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_NOT_INITIALISED),
340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_PENDING),
341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_BUFFER_TOO_SMALL),
342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_ALREADY_INITIALISED),
343f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_BUSY),
344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_TARGET_NOT_CONNECTED),
345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_MULTIPLE_PROTOCOLS),
346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_DESELECTED),
347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_DEVICE),
348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_MORE_INFORMATION),
349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_RF_TIMEOUT),
350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_RF_ERROR),
351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_BOARD_COMMUNICATION_ERROR),
352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_STATE),
353f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_NOT_REGISTERED),
354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_RELEASED),
355f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_NOT_ALLOWED),
356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_REMOTE_DEVICE),
357f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_SMART_TAG_FUNC_NOT_SUPPORTED),
358f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_READ_FAILED),
359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_WRITE_FAILED),
360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_NO_NDEF_SUPPORT),
361f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_EOF_NDEF_CONTAINER_REACHED),
362f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_RECEIVE_LENGTH),
363f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INVALID_FORMAT),
364f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_INSUFFICIENT_STORAGE),
365f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      STATUS_ENTRY(NFCSTATUS_FORMAT_ERROR),
366f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   };
367f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   int i = sizeof(sNameTable)/sizeof(status_entry);
3692534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes
370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   while(i>0)
371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
372f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      i--;
373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      if (sNameTable[i].code == PHNFCSTATUS(status))
374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
375f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly         return sNameTable[i].name;
376f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
377f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
378f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
379f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return "UNKNOWN";
380f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
381f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3820a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenenint addTechIfNeeded(int *techList, int* handleList, int* typeList, int listSize,
3830a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen        int maxListSize, int techToAdd, int handleToAdd, int typeToAdd) {
3844f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    bool found = false;
3854f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    for (int i = 0; i < listSize; i++) {
3864f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen        if (techList[i] == techToAdd) {
3874f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            found = true;
3884f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            break;
3894f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen        }
3904f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    }
3914f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    if (!found && listSize < maxListSize) {
3924f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen        techList[listSize] = techToAdd;
3934f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen        handleList[listSize] = handleToAdd;
3940a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen        typeList[listSize] = typeToAdd;
3954f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen        return listSize + 1;
3964f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    }
3974f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    else {
3984f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen        return listSize;
3994f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen    }
4004f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen}
4014f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen
4024f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen
4034f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen#define MAX_NUM_TECHNOLOGIES 32
4044f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen
4050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas/*
4064f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen *  Utility to get a technology tree and a corresponding handle list from a detected tag.
4070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas */
4082534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughesvoid nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList, uint8_t count,
4092534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes                                 ScopedLocalRef<jintArray>* techList,
4102534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes                                 ScopedLocalRef<jintArray>* handleList,
4112534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes                                 ScopedLocalRef<jintArray>* libnfcTypeList)
4120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas{
4134f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen   int technologies[MAX_NUM_TECHNOLOGIES];
4144f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen   int handles[MAX_NUM_TECHNOLOGIES];
4150a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen   int libnfctypes[MAX_NUM_TECHNOLOGIES];
4160a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen
4174f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen   int index = 0;
418ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen   // TODO: This counts from up to down because on multi-protocols, the
419ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen   // ISO handle is usually the second, and we prefer the ISO. Should implement
420ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen   // a method to find the "preferred handle order" and use that instead,
421ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen   // since we shouldn't have dependencies on the tech list ordering.
422ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen   for (int target = count - 1; target >= 0; target--) {
4234f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen       int type = devList[target].psRemoteDevInfo->RemDevType;
4244f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen       int handle = devList[target].hTargetDev;
4254f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen       switch (type)
4264f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen       {
4274f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eISO14443_A_PICC:
4284f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eISO14443_4A_PICC:
4294f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4300a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
4310a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
4326d11530887a3e6f30fa21d01bc0de5cdbd0218eaMartijn Coenen              break;
4334f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }
4344f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eISO14443_4B_PICC:
4354f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4360a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
4370a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
4380a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes, index,
4390a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type);
4404f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4414f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eISO14443_3A_PICC:
4424f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4430a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4440a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
4454f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4464f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eISO14443_B_PICC:
4474f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4484f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen              // TODO a bug in libnfc will cause 14443-3B only cards
4494f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen              // to be returned as this type as well, but these cards
4504f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen              // are very rare. Hence assume it's -4B
4510a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4520a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_4, handle, type);
4530a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4540a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3B, handle, type);
4554f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4564f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eISO15693_PICC:
4574f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4580a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4590a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO15693, handle, type);
4604f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4614f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eMifare_PICC:
4624f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
463c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen              // We don't want to be too clever here; libnfc has already determined
464c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen              // it's a Mifare, so we only check for UL, for all other tags
465c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen              // we assume it's a mifare classic. This should make us more
466c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen              // future-proof.
4674f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen              int sak = devList[target].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak;
4684f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen              switch(sak)
4690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas              {
4704f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen                case 0x00:
4714f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen                  // could be UL or UL-C
4720a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                  index = addTechIfNeeded(technologies, handles, libnfctypes,
4730a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_UL, handle, type);
4744f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen                  break;
475c1af11b4fa643e5b7f181772b3c7a32a6daa4044Martijn Coenen                default:
4760a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                  index = addTechIfNeeded(technologies, handles, libnfctypes,
4770a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                          index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_MIFARE_CLASSIC, handle, type);
4784f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen                  break;
4794f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen              }
4804f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4814f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eFelica_PICC:
4824f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4830a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4840a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_FELICA, handle, type);
4854f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4864f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          case phNfc_eJewel_PICC:
4874f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4880a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              // Jewel represented as NfcA
4890a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4900a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_ISO14443_3A, handle, type);
4914f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }break;
4924f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen          default:
4934f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            {
4940a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen              index = addTechIfNeeded(technologies, handles, libnfctypes,
4950a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen                      index, MAX_NUM_TECHNOLOGIES, TARGET_TYPE_UNKNOWN, handle, type);
4964f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen            }
4970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas        }
4980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas   }
4996a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton
5004f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen   // Build the Java arrays
5016a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton   if (techList != NULL) {
5022534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       techList->reset(e->NewIntArray(index));
5032534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       e->SetIntArrayRegion(techList->get(), 0, index, technologies);
5046a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton   }
5056a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton
5066a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton   if (handleList != NULL) {
5072534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       handleList->reset(e->NewIntArray(index));
5082534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       e->SetIntArrayRegion(handleList->get(), 0, index, handles);
5094f2715ade09afdd18463eb92f15215a43af41d63Martijn Coenen   }
5100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
5116a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton   if (libnfcTypeList != NULL) {
5122534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       libnfcTypeList->reset(e->NewIntArray(index));
5132534d9a546f24435d9dab8168f9ea5bf8ca1eb9bElliott Hughes       e->SetIntArrayRegion(libnfcTypeList->get(), 0, index, libnfctypes);
5146a8cddd71f669bb313788eea562c7e01cd587ae5Jeff Hamilton   }
5150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas}
5160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas
517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} // namespace android
518