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