com_android_nfc_NativeNfcTag.cpp revision 48819102064977c3e37e18fd6db9a6022c01300c
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
17f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly#include <semaphore.h>
18f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
19c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly#include "com_android_nfc.h"
20f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
21c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic sem_t nfc_jni_tag_sem;
22c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic NFCSTATUS nfc_jni_cb_status = NFCSTATUS_FAILED;
23c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic phLibNfc_Data_t nfc_jni_ndef_rw;
24f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellystatic phLibNfc_Handle handle;
25c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyuint8_t nfc_jni_is_ndef = -1;
26c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyuint8_t *nfc_jni_ndef_buf = NULL;
27c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellyuint32_t nfc_jni_ndef_buf_len = 0;
28f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
29f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
30f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
31f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
32f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
33f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellynamespace android {
34f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
3521545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pellyextern void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat);
36f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
37f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/*
38f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Callbacks
39f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */
40c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly static void nfc_jni_tag_rw_callback(void *pContext, NFCSTATUS status)
41f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
42c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_tag_rw_callback", status);
43f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
44c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_cb_status = status;
45f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
46c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_post(&nfc_jni_tag_sem);
47f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
48f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
49c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_connect_callback(void *pContext,
50f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle hRemoteDev,
51f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo, NFCSTATUS status)
52f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
53c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_connect_callback", status);
54f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
55c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_cb_status = status;
56f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
57c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_post(&nfc_jni_tag_sem);
58f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
59f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
60c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_checkndef_callback(void *pContext,
61f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_ChkNdef_Info_t info, NFCSTATUS status)
62f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
63c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_checkndef_callback", status);
64f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
65f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if(status == NFCSTATUS_OK)
66f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
67c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      if(nfc_jni_ndef_buf)
68f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
69c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         free(nfc_jni_ndef_buf);
70f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
71c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      nfc_jni_ndef_buf_len = info.MaxNdefMsgLength;
72c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      nfc_jni_ndef_buf = (uint8_t*)malloc(nfc_jni_ndef_buf_len);
7348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas      nfc_jni_is_ndef = TRUE;
74f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
75f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   else
76f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
7748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas      nfc_jni_is_ndef = FALSE;
78f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
79f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
80c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_post(&nfc_jni_tag_sem);
81f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
82f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
83c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_disconnect_callback(void *pContext,
84f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle hRemoteDev, NFCSTATUS status)
85f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
86c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_disconnect_callback", status);
87f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
88c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_ndef_buf)
89f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
90c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      free(nfc_jni_ndef_buf);
91f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
92c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_buf = NULL;
93c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_buf_len = 0;
94c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_is_ndef = -1;
95f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
96c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_cb_status = status;
97f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
98c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_post(&nfc_jni_tag_sem);
99f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
100f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
101c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_async_disconnect_callback(void *pContext,
102f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle hRemoteDev, NFCSTATUS status)
103f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
104c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_async_disconnect_callback", status);
105f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
106c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_ndef_buf)
107f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
108c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      free(nfc_jni_ndef_buf);
109f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
110c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_buf = NULL;
111c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_buf_len = 0;
112c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_is_ndef = -1;
113f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
114f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
115c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_presence_check_callback(void* pContext,NFCSTATUS  status)
116f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
117c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_presence_check_callback", status);
118f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
119c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_cb_status = status;
120f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
121c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_post(&nfc_jni_tag_sem);
122f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
123f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
124c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_async_presence_check_callback(void* pContext,NFCSTATUS  status)
125f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
126f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   NFCSTATUS ret;
127f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   JNIEnv* env = (JNIEnv*)pContext;
128f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
129c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_async_presence_check_callback", status);
130f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
131f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if(status != NFCSTATUS_SUCCESS)
132f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
133f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      /* Disconnect & Restart Polling loop */
134f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      LOGI("Tag removed from the RF Field\n");
135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
136f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      LOGD("phLibNfc_RemoteDev_Disconnect(async)");
137f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      REENTRANCE_LOCK();
138c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      ret = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE, nfc_jni_async_disconnect_callback,(void*)handle);
139f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      REENTRANCE_UNLOCK();
140f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      if(ret != NFCSTATUS_PENDING)
141f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
142c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         LOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
14321545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly         /* concurrency lock held while in callback */
14421545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly         nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(env));
145f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly         return;
146f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
147c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
148f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   else
150f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
151f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      LOGD("phLibNfc_RemoteDev_CheckPresence(async)");
152f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      /* Presence Check */
153f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      REENTRANCE_LOCK();
154c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      ret = phLibNfc_RemoteDev_CheckPresence(handle,nfc_jni_async_presence_check_callback, (void*)env);
155f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      REENTRANCE_UNLOCK();
156f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      if(ret != NFCSTATUS_PENDING)
157f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
158c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         LOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
159f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly         return;
160f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
161c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGD("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
162f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
163f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
164f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
165f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
166f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
167c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic phNfc_sData_t *nfc_jni_transceive_buffer;
168f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
169c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pellystatic void nfc_jni_transceive_callback(void *pContext,
170f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle handle, phNfc_sData_t *pResBuffer, NFCSTATUS status)
171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
172c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOG_CALLBACK("nfc_jni_transceive_callback", status);
173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
174c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_cb_status = status;
175c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_transceive_buffer = pResBuffer;
176f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
177c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_post(&nfc_jni_tag_sem);
178f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
180b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneaustatic void nfc_jni_presencecheck_callback(void *pContext, NFCSTATUS status)
181b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau{
182b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   LOG_CALLBACK("nfc_jni_presencecheck_callback", status);
183b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
184b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   nfc_jni_cb_status = status;
185b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
186b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   sem_post(&nfc_jni_tag_sem);
187b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau}
188b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* Functions */
19013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jbyteArray com_android_nfc_NativeNfcTag_doRead(JNIEnv *e,
191f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jobject o)
192f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
193f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   NFCSTATUS status;
194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle handle = 0;
195f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jbyteArray buf = NULL;
196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_LOCK();
198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
199c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   handle = nfc_jni_get_nfc_tag_handle(e, o);
200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
201c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_rw.length = nfc_jni_ndef_buf_len;
202c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_rw.buffer = nfc_jni_ndef_buf;
203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   LOGD("phLibNfc_Ndef_Read()");
205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_LOCK();
206c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   status = phLibNfc_Ndef_Read(handle, &nfc_jni_ndef_rw,
207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                               phLibNfc_Ndef_EBegin,
208c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly                               nfc_jni_tag_rw_callback,
209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly                               (void *)e);
210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_UNLOCK();
211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if(status != NFCSTATUS_PENDING)
212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
213c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGE("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
214f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
216c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOGD("phLibNfc_Ndef_Read() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
217f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Wait for callback response */
219c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_wait(&nfc_jni_tag_sem);
220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
221c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_cb_status != NFCSTATUS_SUCCESS)
222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
226c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   buf = e->NewByteArray(nfc_jni_ndef_rw.length);
227c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   e->SetByteArrayRegion(buf, 0, nfc_jni_ndef_rw.length,
228c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      (jbyte *)nfc_jni_ndef_rw.buffer);
229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return:
231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_UNLOCK();
233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return buf;
235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
236f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
237f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
23813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jboolean com_android_nfc_NativeNfcTag_doWrite(JNIEnv *e,
239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jobject o, jbyteArray buf)
240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   NFCSTATUS   status;
242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jboolean    result = JNI_FALSE;
243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
244c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   phLibNfc_Handle handle = nfc_jni_get_nfc_tag_handle(e, o);
245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_LOCK();
247f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
248c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_rw.length = (uint32_t)e->GetArrayLength(buf);
249c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   nfc_jni_ndef_rw.buffer = (uint8_t *)e->GetByteArrayElements(buf, NULL);
250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   LOGD("phLibNfc_Ndef_Write()");
252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   LOGD("Ndef Handle :0x%x\n",handle);
253c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOGD("Ndef buffer length : %d", nfc_jni_ndef_rw.length);
254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_LOCK();
255c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   status = phLibNfc_Ndef_Write(handle, &nfc_jni_ndef_rw,nfc_jni_tag_rw_callback, (void *)e);
256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_UNLOCK();
257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if(status != NFCSTATUS_PENDING)
258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
259c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGE("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
262c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOGD("phLibNfc_Ndef_Write() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Wait for callback response */
265c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_wait(&nfc_jni_tag_sem);
266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
267c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_cb_status != NFCSTATUS_SUCCESS)
268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   result = JNI_TRUE;
273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return:
275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if (result != JNI_TRUE)
276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
277c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      e->ReleaseByteArrayElements(buf, (jbyte *)nfc_jni_ndef_rw.buffer, JNI_ABORT);
278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_UNLOCK();
280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return result;
281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
28313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jboolean com_android_nfc_NativeNfcTag_doConnect(JNIEnv *e,
284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jobject o)
285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle handle = 0;
287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jclass cls;
288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jfieldID f;
289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   NFCSTATUS status;
290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jboolean result = JNI_FALSE;
291f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_LOCK();
293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
294c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   handle = nfc_jni_get_nfc_tag_handle(e, o);
295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   LOGD("phLibNfc_RemoteDev_Connect(RW)");
297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_LOCK();
298c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   status = phLibNfc_RemoteDev_Connect(handle, nfc_jni_connect_callback,(void *)e);
299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_UNLOCK();
300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if(status != NFCSTATUS_PENDING)
301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
302c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGE("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
305c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOGD("phLibNfc_RemoteDev_Connect(RW) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Wait for callback response */
308c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_wait(&nfc_jni_tag_sem);
309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
310f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Connect Status */
311c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(nfc_jni_cb_status != NFCSTATUS_SUCCESS)
312f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
313f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   result = JNI_TRUE;
317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return:
319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_UNLOCK();
320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return result;
321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
32313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jboolean com_android_nfc_NativeNfcTag_doDisconnect(JNIEnv *e, jobject o)
324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle handle = 0;
326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jclass cls;
327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jfieldID f;
328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   NFCSTATUS status;
329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jboolean result = JNI_FALSE;
330f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_LOCK();
332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
333c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   handle = nfc_jni_get_nfc_tag_handle(e, o);
334f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
335f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Disconnect */
336f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   LOGI("Disconnecting from target (handle = 0x%x)", handle);
337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Presence Check */
339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   do
340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      LOGD("phLibNfc_RemoteDev_CheckPresence()");
342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      REENTRANCE_LOCK();
343c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      status = phLibNfc_RemoteDev_CheckPresence(handle,nfc_jni_presence_check_callback,(void *)e);
344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      REENTRANCE_UNLOCK();
345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      if(status != NFCSTATUS_PENDING)
346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      {
347c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         LOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
34848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas         /* Disconnect Tag */
34948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas         break;
350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      }
351c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGD("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
352f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      /* Wait for callback response */
353c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      sem_wait(&nfc_jni_tag_sem);
354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
35548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    } while(nfc_jni_cb_status == NFCSTATUS_SUCCESS);
356f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
35748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGI("Tag removed from the RF Field\n");
358f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
35948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGD("phLibNfc_RemoteDev_Disconnect()");
36048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    REENTRANCE_LOCK();
36148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    status = phLibNfc_RemoteDev_Disconnect(handle, NFC_DISCOVERY_CONTINUE,
36248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas                                          nfc_jni_disconnect_callback, (void *)e);
36348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    REENTRANCE_UNLOCK();
36448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(status != NFCSTATUS_PENDING)
36548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
36648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        LOGE("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
36748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        nfc_jni_restart_discovery_locked(nfc_jni_get_nat_ext(e));
36848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        goto clean_and_return;
36948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
37048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
37148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
37248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    /* Wait for callback response */
37348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    sem_wait(&nfc_jni_tag_sem);
374f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
37548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    /* Disconnect Status */
37648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(nfc_jni_cb_status != NFCSTATUS_SUCCESS)
37748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
37848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
37948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        goto clean_and_return;
38048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
38148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGD("phLibNfc_RemoteDev_Disconnect() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
38248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    result = JNI_TRUE;
383f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
384f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return:
385f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_UNLOCK();
386f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return result;
387f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
38913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellystatic jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jobject o, jbyteArray data)
391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
39248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    uint8_t offset = 0;
39348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    uint8_t *buf;
39448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    uint32_t buflen;
39548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    phLibNfc_sTransceiveInfo_t transceive_info;
39648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    jbyteArray result = NULL;
39748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    int res;
39848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    jstring type = nfc_jni_get_nfc_tag_type(e, o);
39948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    const char* str = e->GetStringUTFChars(type, 0);
40048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    phLibNfc_Handle handle = nfc_jni_get_nfc_tag_handle(e, o);
40148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    NFCSTATUS status;
40248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
40348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    CONCURRENCY_LOCK();
40448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
40548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGD("Tag %s\n", str);
40648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
40748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    buf = (uint8_t *)e->GetByteArrayElements(data, NULL);
40848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    buflen = (uint32_t)e->GetArrayLength(data);
40948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
41048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    /* Prepare transceive info structure */
41148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if((res = strcmp(str, "Mifare1K") == 0) || (res = strcmp(str, "Mifare4K") == 0) || (res = strcmp(str, "MifareUL") == 0))
41248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      offset = 2;
414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.cmd.MfCmd = (phNfc_eMifareCmdList_t)buf[0];
415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.addr = (uint8_t)buf[1];
41648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
41748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    else if((res = strcmp(str, "Felica") == 0))
41848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.cmd.FelCmd = phNfc_eFelica_Raw;
420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.addr = 0;
42148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
42248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    else if((res = strcmp(str, "Iso14443") == 0))
42348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.cmd.Iso144434Cmd = phNfc_eIso14443_4_Raw;
425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.addr = 0;
42648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
42748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    else if((res = strcmp(str, "Jewel") == 0))
42848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
429f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.cmd.JewelCmd = phNfc_eJewel_Raw;
430f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      transceive_info.addr = 0;
43148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
43348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    /* Free memory */
43448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    e->ReleaseStringUTFChars(type, str);
435f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
43648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    transceive_info.sSendData.buffer = buf + offset;
43748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    transceive_info.sSendData.length = buflen - offset;
43848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    transceive_info.sRecvData.buffer = (uint8_t*)malloc(1024);
43948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    transceive_info.sRecvData.length = 1024;
440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
44148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(transceive_info.sRecvData.buffer == NULL)
44248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
44448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
44648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGD("phLibNfc_RemoteDev_Transceive()");
44748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    REENTRANCE_LOCK();
44848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    status = phLibNfc_RemoteDev_Transceive(handle, &transceive_info,
449c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         nfc_jni_transceive_callback, (void *)e);
45048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    REENTRANCE_UNLOCK();
45148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(status != NFCSTATUS_PENDING)
45248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
453c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
454f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
45548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
45648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    LOGD("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
45748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
45848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    /* Wait for callback response */
45948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    sem_wait(&nfc_jni_tag_sem);
46048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
46148819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(nfc_jni_cb_status != NFCSTATUS_SUCCESS)
46248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
46348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        LOGE("phLibNfc_RemoteDev_Transceive() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
46448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas        goto clean_and_return;
46548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
46648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas
46748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    /* Copy results back to Java */
46848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    result = e->NewByteArray(nfc_jni_transceive_buffer->length);
46948819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(result != NULL)
47048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      e->SetByteArrayRegion(result, 0,
472c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         nfc_jni_transceive_buffer->length,
473c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly         (jbyte *)nfc_jni_transceive_buffer->buffer);
47448819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
47648819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    clean_and_return:
47748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    if(transceive_info.sRecvData.buffer != NULL)
47848819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    {
479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      free(transceive_info.sRecvData.buffer);
48048819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    }
481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
48248819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    e->ReleaseByteArrayElements(data,
483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      (jbyte *)transceive_info.sSendData.buffer, JNI_ABORT);
484f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
48548819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    CONCURRENCY_UNLOCK();
486f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
48748819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas    return result;
488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
490b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneaustatic jboolean com_android_nfc_NativeNfcTag_doCheckNdef(JNIEnv *e, jobject o)
491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   phLibNfc_Handle handle = 0;
493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   NFCSTATUS status;
494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   jboolean result = JNI_FALSE;
495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_LOCK();
497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
498c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   handle = nfc_jni_get_nfc_tag_handle(e, o);
499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   LOGD("phLibNfc_Ndef_CheckNdef()");
501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_LOCK();
502c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   status = phLibNfc_Ndef_CheckNdef(handle, nfc_jni_checkndef_callback,(void *)e);
503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   REENTRANCE_UNLOCK();
504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   if(status != NFCSTATUS_PENDING)
505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
506c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly      LOGE("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
507f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
509c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   LOGD("phLibNfc_Ndef_CheckNdef() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   /* Wait for callback response */
511c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   sem_wait(&nfc_jni_tag_sem);
512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
51348819102064977c3e37e18fd6db9a6022c01300cDaniel Tomas   if (nfc_jni_is_ndef == FALSE)
514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {
515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      goto clean_and_return;
516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   }
517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
518f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   result = JNI_TRUE;
519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyclean_and_return:
521f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   CONCURRENCY_UNLOCK();
522f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return result;
523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
525b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneaustatic jboolean com_android_nfc_NativeNfcTag_doPresenceCheck(JNIEnv *e, jobject o)
526b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau{
527b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   phLibNfc_Handle handle = 0;
528b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   NFCSTATUS status;
529b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   jboolean result = JNI_FALSE;
530b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
531b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   CONCURRENCY_LOCK();
532b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
533b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   handle = nfc_jni_get_nfc_tag_handle(e, o);
534b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
535b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   LOGD("phLibNfc_RemoteDev_CheckPresence()");
536b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   REENTRANCE_LOCK();
537b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   status = phLibNfc_RemoteDev_CheckPresence(handle, nfc_jni_presencecheck_callback, (void *)e);
538b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   REENTRANCE_UNLOCK();
539b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   if(status != NFCSTATUS_PENDING)
540b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   {
541b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau      LOGE("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
542b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau      goto clean_and_return;
543b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   }
544b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   LOGD("phLibNfc_RemoteDev_CheckPresence() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
545b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
546b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   /* Wait for callback response */
547b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   sem_wait(&nfc_jni_tag_sem);
548b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
549b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   if (nfc_jni_cb_status == NFCSTATUS_SUCCESS)
550b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   {
551b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau       result = JNI_TRUE;
552b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   }
553b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau
554b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauclean_and_return:
555b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   CONCURRENCY_UNLOCK();
556b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   return result;
557b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau}
558f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
559f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
560f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/*
561f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * JNI registration.
562f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */
563f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellystatic JNINativeMethod gMethods[] =
564f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
565f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {"doConnect", "()Z",
56613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      (void *)com_android_nfc_NativeNfcTag_doConnect},
567f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {"doDisconnect", "()Z",
56813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      (void *)com_android_nfc_NativeNfcTag_doDisconnect},
569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {"doTransceive", "([B)[B",
57013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      (void *)com_android_nfc_NativeNfcTag_doTransceive},
571b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   {"doCheckNdef", "()Z",
572b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau      (void *)com_android_nfc_NativeNfcTag_doCheckNdef},
573f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {"doRead", "()[B",
57413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      (void *)com_android_nfc_NativeNfcTag_doRead},
575f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   {"doWrite", "([B)Z",
57613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      (void *)com_android_nfc_NativeNfcTag_doWrite},
577b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau   {"doPresenceCheck", "()Z",
578b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau      (void *)com_android_nfc_NativeNfcTag_doPresenceCheck},
579f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly};
580f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
58113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyint register_com_android_nfc_NativeNfcTag(JNIEnv *e)
582f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly{
583c2fdb614879c601b5162d5d93d705b05c7b1e072Nick Pelly   if(sem_init(&nfc_jni_tag_sem, 0, 0) == -1)
584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      return -1;
585f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
586f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly   return jniRegisterNativeMethods(e,
58713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly      "com/android/nfc/NativeNfcTag",
588f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly      gMethods, NELEM(gMethods));
589f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly}
590f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly
591f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly} // namespace android
592