Fix issuse related unregisterReceiver
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / nfc_adapter / android / canfcserver.c
1 /* ****************************************************************j\r
2  *\r
3  * Copyright 2015 Samsung Electronics All Rights Reserved.\r
4  *\r
5  *\r
6  *\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  *\r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  *\r
19  ******************************************************************/\r
20 #include "canfcinterface.h"\r
21 \r
22 #include "caadapterutils.h"\r
23 #include "camutex.h"\r
24 #include "oic_malloc.h"\r
25 #include "oic_string.h"\r
26 \r
27 /**\r
28  * TAG\r
29  * Logging tag for module name\r
30  */\r
31 #define TAG "NFC_SERVER"\r
32 \r
33 static CANFCPacketReceivedCallback g_packetReceivedCallback;\r
34 \r
35 static JavaVM *g_jvm = NULL;\r
36 static jobject g_context = NULL;\r
37 static jobject g_activity = NULL;\r
38 static jobject g_nfcInterface = NULL;\r
39 static jmethodID g_sendMethod = NULL;\r
40 \r
41 static void CANfcJniInit();\r
42 static void CANfcJNISetContext();\r
43 static CAResult_t CANfcCreateJniInterfaceObject();\r
44 static CAResult_t CANfcSendDataImpl(const CAEndpoint_t * ep, const char* data, uint32_t dataLen);\r
45 \r
46 static const char CLASS_NFCINTERFACE[] = "org/iotivity/ca/CaNfcInterface";\r
47 \r
48 static void CANfcJniInit()\r
49 {\r
50     OIC_LOG(DEBUG, TAG, "CANfcJniInit");\r
51     g_jvm = (JavaVM*) CANativeJNIGetJavaVM();\r
52 }\r
53 \r
54 static void CANfcJNISetContext()\r
55 {\r
56     OIC_LOG(DEBUG, TAG, "CANfcJNISetContext");\r
57     g_context = (jobject) CANativeJNIGetContext();\r
58     g_activity = (jobject) CANativeGetActivity();\r
59 }\r
60 \r
61 void CANFCSetPacketReceiveCallback(CANFCPacketReceivedCallback callback)\r
62 {\r
63     OIC_LOG(DEBUG, TAG, "IN");\r
64 \r
65     g_packetReceivedCallback = callback;\r
66 \r
67     OIC_LOG(DEBUG, TAG, "OUT");\r
68 }\r
69 \r
70 CAResult_t SetCreateNdefMessageCallbackfromNative(JNIEnv* env)\r
71 {\r
72     OIC_LOG(DEBUG, TAG, "SetCreateNdefMessageCallbackfromNative IN");\r
73 \r
74     VERIFY_NON_NULL(env, TAG, "env");\r
75     VERIFY_NON_NULL(g_context, TAG, "g_context");\r
76     VERIFY_NON_NULL(g_activity, TAG, "g_activity");\r
77     VERIFY_NON_NULL(g_nfcInterface, TAG, "g_nfcInterface");\r
78 \r
79     jclass cid_NfcAdapter = (*env)->FindClass(env, "android/nfc/NfcAdapter");\r
80     if (!cid_NfcAdapter)\r
81     {\r
82         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter class");\r
83         return CA_STATUS_FAILED;\r
84     }\r
85 \r
86     jmethodID mid_getAdapter = (*env)->GetStaticMethodID(env, cid_NfcAdapter,\r
87                                        "getDefaultAdapter",\r
88                                        "(Landroid/content/Context;)Landroid/nfc/NfcAdapter;");\r
89     if (!mid_getAdapter)\r
90     {\r
91         OIC_LOG(ERROR, TAG, "Could not get methodId mid_getAdapter");\r
92         return CA_STATUS_FAILED;\r
93     }\r
94 \r
95     jobject adapter = (*env)->CallStaticObjectMethod(env, cid_NfcAdapter, mid_getAdapter,\r
96                                                      g_context);\r
97     if (!adapter)\r
98     {\r
99         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter");\r
100         return CA_STATUS_FAILED;\r
101     }\r
102 \r
103     jmethodID mid_setCallback = (*env)->GetMethodID(\r
104         env, cid_NfcAdapter, "setNdefPushMessageCallback",\r
105         "(Landroid/nfc/NfcAdapter$CreateNdefMessageCallback;Landroid/app/Activity;"\r
106         "[Landroid/app/Activity;)V");\r
107     if (!mid_setCallback)\r
108     {\r
109         OIC_LOG(ERROR, TAG, "Could not get mid_setCallback");\r
110         return CA_STATUS_FAILED;\r
111     }\r
112 \r
113     jclass cid_Activity = (*env)->FindClass(env, "android/app/Activity");\r
114     if (!cid_Activity)\r
115     {\r
116         OIC_LOG(ERROR, TAG, "Could not get Activity class");\r
117         return CA_STATUS_FAILED;\r
118     }\r
119 \r
120     jobjectArray tempArr = (jobjectArray) (*env)->NewObjectArray(env, 0, cid_Activity, NULL);\r
121     (*env)->CallVoidMethod(env, adapter, mid_setCallback, g_nfcInterface, g_activity, tempArr);\r
122 \r
123     OIC_LOG(DEBUG, TAG, "SetCreateNdefMessageCallbackfromNative OUT");\r
124     return CA_STATUS_OK;\r
125 }\r
126 \r
127 CAResult_t CANfcCreateJniInterfaceObject()\r
128 {\r
129     OIC_LOG(DEBUG, TAG, "CANfcCreateJniInterfaceObject IN");\r
130 \r
131     VERIFY_NON_NULL(g_activity, TAG, "g_activity");\r
132     VERIFY_NON_NULL(g_context, TAG, "g_context");\r
133     VERIFY_NON_NULL(g_jvm, TAG, "g_jvm");\r
134 \r
135     bool isAttached = false;\r
136     JNIEnv* env;\r
137     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
138     if (JNI_OK != res)\r
139     {\r
140         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
141         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
142 \r
143         if (JNI_OK != res)\r
144         {\r
145             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
146             return CA_STATUS_FAILED;\r
147         }\r
148         isAttached = true;\r
149     }\r
150 \r
151     jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",\r
152                                                            "getApplicationContext",\r
153                                                            "()Landroid/content/Context;");\r
154 \r
155     if (!mid_getApplicationContext)\r
156     {\r
157         OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");\r
158         return CA_STATUS_FAILED;\r
159     }\r
160 \r
161     jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,\r
162                                                            mid_getApplicationContext);\r
163     if (!jApplicationContext)\r
164     {\r
165         OIC_LOG(ERROR, TAG, "Could not get application context");\r
166         return CA_STATUS_FAILED;\r
167     }\r
168 \r
169     jclass jni_NfcInterface = (*env)->FindClass(env, "org/iotivity/ca/CaNfcInterface");\r
170     if (!jni_NfcInterface)\r
171     {\r
172         OIC_LOG(ERROR, TAG, "Could not get CaNfcInterface class");\r
173         goto error_exit;\r
174     }\r
175 \r
176     jmethodID NfcInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_NfcInterface, "<init>",\r
177                                             "(Landroid/content/Context;Landroid/app/Activity;)V");\r
178     if (!NfcInterfaceConstructorMethod)\r
179     {\r
180         OIC_LOG(ERROR, TAG, "Could not get CaNfcInterface constructor method");\r
181         goto error_exit;\r
182     }\r
183 \r
184     jobject jni_nfcInstance = (*env)->NewObject(env, jni_NfcInterface,\r
185                                                 NfcInterfaceConstructorMethod, jApplicationContext,\r
186                                                 g_activity);\r
187     if (!jni_nfcInstance)\r
188     {\r
189         OIC_LOG(ERROR, TAG, "Create instance for CaNfcInterface failed");\r
190         goto error_exit;\r
191     }\r
192 \r
193     g_nfcInterface = (*env)->NewGlobalRef(env, jni_nfcInstance);\r
194     if (!g_nfcInterface)\r
195     {\r
196         OIC_LOG(ERROR, TAG, "NewGlobalRef  for nfcInterface failed");\r
197         goto error_exit;\r
198     }\r
199 \r
200     OIC_LOG(DEBUG, TAG, "Create instance for CaNfcInterface");\r
201 \r
202     CAResult_t result = SetCreateNdefMessageCallbackfromNative(env);\r
203     if (CA_STATUS_OK != result)\r
204     {\r
205         OIC_LOG(ERROR, TAG, "SetCreateNdefMessageCallbackfromNative failed");\r
206         goto error_exit;\r
207     }\r
208 \r
209     if (isAttached)\r
210     {\r
211         (*g_jvm)->DetachCurrentThread(g_jvm);\r
212     }\r
213 \r
214     OIC_LOG(DEBUG, TAG, "CANfcCreateJniInterfaceObject OUT");\r
215     return CA_STATUS_OK;\r
216 \r
217 error_exit:\r
218     if (isAttached)\r
219     {\r
220         (*g_jvm)->DetachCurrentThread(g_jvm);\r
221     }\r
222 \r
223     return CA_STATUS_FAILED;\r
224 }\r
225 \r
226 CAResult_t CAInitializeNfcServer()\r
227 {\r
228     CANfcJniInit();\r
229     CANfcJNISetContext();\r
230 \r
231     CAResult_t result = CANfcCreateJniInterfaceObject();\r
232     if (CA_STATUS_OK != result)\r
233     {\r
234         OIC_LOG(ERROR, TAG, "CANfcJniInit failed");\r
235     }\r
236 \r
237     return result;\r
238 }\r
239 \r
240 CAResult_t CANFCStartServer()\r
241 {\r
242     bool isAttached = false;\r
243 \r
244     OIC_LOG(INFO, TAG, "CANFCStartServer : IN");\r
245 \r
246     JNIEnv* env;\r
247     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
248     if (JNI_OK != res)\r
249     {\r
250         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
251         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
252 \r
253         if (JNI_OK != res)\r
254         {\r
255             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
256             return CA_STATUS_FAILED;\r
257         }\r
258         isAttached = true;\r
259     }\r
260 \r
261     jclass jni_NfcInterface = (*env)->FindClass(env, "org/iotivity/ca/CaNfcInterface");\r
262     if (!jni_NfcInterface)\r
263     {\r
264         OIC_LOG(ERROR, TAG, "Could not get CaNFCClientInterface class");\r
265         goto error_exit;\r
266     }\r
267 \r
268     jmethodID methodId = (*env)->GetMethodID(env, jni_NfcInterface, "caNfcInitialize", "()V");\r
269     if (!methodId)\r
270     {\r
271         OIC_LOG(ERROR, TAG, "Could not get methodId");\r
272         goto error_exit;\r
273     }\r
274 \r
275     if (!g_nfcInterface)\r
276     {\r
277         OIC_LOG(ERROR, TAG, "g_nfcInterface NULL");\r
278         goto error_exit;\r
279     }\r
280 \r
281     (*env)->CallVoidMethod(env, g_nfcInterface, methodId);\r
282     OIC_LOG(DEBUG, TAG, "caNfcInitialize");\r
283 \r
284     jmethodID sendDataMethodId = (*env)->GetMethodID(env, jni_NfcInterface, "processSendRquest",\r
285                                                      "([B)V");\r
286     if (!sendDataMethodId)\r
287     {\r
288         OIC_LOG(ERROR, TAG, "Could not get sendDataMethodId");\r
289         goto error_exit;\r
290     }\r
291 \r
292     g_sendMethod = sendDataMethodId;\r
293 \r
294     if (isAttached)\r
295     {\r
296         (*g_jvm)->DetachCurrentThread(g_jvm);\r
297     }\r
298 \r
299     return CA_STATUS_OK;\r
300 \r
301 error_exit:\r
302     if (isAttached)\r
303     {\r
304         (*g_jvm)->DetachCurrentThread(g_jvm);\r
305     }\r
306     return CA_STATUS_FAILED;\r
307 \r
308 }\r
309 \r
310 void CANFCStopServer()\r
311 {\r
312     // JNI Call to unregstier nfc adapter\r
313 }\r
314 \r
315 /*\r
316  * Class:     org_iotivity_ca_CaNfcInterface\r
317  * Method:    caNativeNfcCreateNdefMessage\r
318  * Signature: ([B)Landroid/nfc/NdefMessage;\r
319  */\r
320 JNIEXPORT jobject JNICALL\r
321 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcCreateNdefMessage(JNIEnv *env, jobject obj,\r
322                                                                  jbyteArray sendData)\r
323 {\r
324     OIC_LOG(DEBUG, TAG, "caNativeNfcCreateNdefMessage : IN");\r
325     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);\r
326     VERIFY_NON_NULL_RET(obj, TAG, "obj is null", NULL);\r
327 \r
328     const char *mime = "application/org.iotivity.ca.sample_service";\r
329     jstring mimeString = (*env)->NewStringUTF(env, mime);\r
330     if (!mimeString)\r
331     {\r
332         OIC_LOG(ERROR, TAG, "NewStringUTF failed for mimeString");\r
333         return NULL;\r
334     }\r
335 \r
336     const char *type = "US_ASCII";\r
337     jstring charSetString = (*env)->NewStringUTF(env, type);\r
338     if (!charSetString)\r
339     {\r
340         OIC_LOG(ERROR, TAG, "NewStringUTF failed for charSetString");\r
341         return NULL;\r
342     }\r
343 \r
344     jclass cid_string = (*env)->FindClass(env, "java/lang/String");\r
345     if (!cid_string)\r
346     {\r
347         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter class for cid_string");\r
348         return NULL;\r
349     }\r
350 \r
351     jmethodID mid_getBytes = (*env)->GetMethodID(env, cid_string, "getBytes",\r
352                                                  "(Ljava/lang/String;)[B");\r
353     if (!mid_getBytes)\r
354     {\r
355         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_getBytes");\r
356         return NULL;\r
357     }\r
358 \r
359     jbyteArray mimeTypeArr = (*env)->CallObjectMethod(env, mimeString, mid_getBytes,\r
360                                                       charSetString);\r
361     if (!mimeTypeArr)\r
362     {\r
363         OIC_LOG(ERROR, TAG, "getBytes failed for mimeTypeArr");\r
364     }\r
365 \r
366     jclass cid_NdefRecord = (*env)->FindClass(env, "android/nfc/NdefRecord");\r
367     if (!cid_NdefRecord)\r
368     {\r
369         OIC_LOG(ERROR, TAG, "Could not get NdefRecord class for cid_NdefRecord");\r
370         return NULL;\r
371     }\r
372 \r
373     jmethodID mid_createRecord = (*env)->GetMethodID(env, cid_NdefRecord, "<init>",\r
374                                                      "(S[B[B[B)V");\r
375     if (!mid_createRecord)\r
376     {\r
377         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_createRecord");\r
378         return NULL;\r
379     }\r
380 \r
381     jfieldID fid_tnfType = (*env)->GetStaticFieldID(env, cid_NdefRecord, "TNF_MIME_MEDIA", "S");\r
382 \r
383     jint tnfType = (*env)->GetStaticShortField(env, cid_NdefRecord, fid_tnfType);\r
384     OIC_LOG_V(ERROR, TAG, "tnfType : %d", tnfType);\r
385 \r
386     jbyteArray nullArr = (*env)->NewByteArray(env, 0);\r
387 \r
388     jobject ndefRecord = (*env)->NewObject(env, cid_NdefRecord, mid_createRecord, tnfType,\r
389                                            mimeTypeArr, nullArr, sendData);\r
390     if (!ndefRecord)\r
391     {\r
392         OIC_LOG(ERROR, TAG, "createNdefRecord failed for ndefRecord");\r
393         return NULL;\r
394     }\r
395 \r
396     jclass cid_NdefMsg = (*env)->FindClass(env, "android/nfc/NdefMessage");\r
397     if (!cid_NdefMsg)\r
398     {\r
399         OIC_LOG(ERROR, TAG, "Could not get NdefMessage class for cid_NdefMsg");\r
400         return NULL;\r
401     }\r
402 \r
403     jmethodID mid_createMsg = (*env)->GetMethodID(env, cid_NdefMsg, "<init>",\r
404                                                   "([Landroid/nfc/NdefRecord;)V");\r
405     if (!mid_createMsg)\r
406     {\r
407         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_createMsg");\r
408         return NULL;\r
409     }\r
410     jobjectArray tempArr = (jobjectArray) (*env)->NewObjectArray(env, 1, cid_NdefRecord,\r
411                                                                  ndefRecord);\r
412 \r
413     jobject ndefMsg = (*env)->NewObject(env, cid_NdefMsg, mid_createMsg, tempArr);\r
414     if (!ndefMsg)\r
415     {\r
416         OIC_LOG(ERROR, TAG, "createNdefMessage failed for ndefMsg");\r
417         return NULL;\r
418     }\r
419 \r
420     OIC_LOG(DEBUG, TAG, "caNativeNfcCreateNdefMessage : OUT");\r
421     return ndefMsg;\r
422 }\r
423 \r
424 /*\r
425  * Class:     org_iotivity_ca_CaNfcInterface\r
426  * Method:    caNativeNfcInvokeBeam\r
427  * Signature: ()Z\r
428  */\r
429 JNIEXPORT jboolean JNICALL\r
430 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcInvokeBeam(JNIEnv *env, jobject obj)\r
431 {\r
432     OIC_LOG(DEBUG, TAG, "cANativeNfcInvokeBeam : IN");\r
433     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);\r
434     VERIFY_NON_NULL_RET(obj, TAG, "obj is null", false);\r
435     VERIFY_NON_NULL_RET(g_context, TAG, "g_context is null", false);\r
436     VERIFY_NON_NULL_RET(g_activity, TAG, "g_activity is null", false);\r
437 \r
438     jclass cid_NfcAdapter = (*env)->FindClass(env, "android/nfc/NfcAdapter");\r
439     if (!cid_NfcAdapter)\r
440     {\r
441         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter cid_NfcAdapter ");\r
442         return JNI_FALSE;\r
443     }\r
444 \r
445     jmethodID mid_getAdapter = (*env)->GetStaticMethodID(env, cid_NfcAdapter,\r
446                                        "getDefaultAdapter",\r
447                                        "(Landroid/content/Context;)Landroid/nfc/NfcAdapter;");\r
448     if (!mid_getAdapter)\r
449     {\r
450         OIC_LOG(ERROR, TAG, "Could not get methodId mid_getAdapter");\r
451         return JNI_FALSE;\r
452     }\r
453 \r
454     jobject adapter = (*env)->CallStaticObjectMethod(env, cid_NfcAdapter, mid_getAdapter,\r
455                                                      g_context);\r
456     if (!adapter)\r
457     {\r
458         OIC_LOG(ERROR, TAG, "getDefaultAdapter failed adapter");\r
459         return JNI_FALSE;\r
460     }\r
461 \r
462     jmethodID mid_invokeBeam = (*env)->GetMethodID(env, cid_NfcAdapter, "invokeBeam",\r
463                                                    "(Landroid/app/Activity;)Z");\r
464     if (!mid_invokeBeam)\r
465     {\r
466         OIC_LOG(ERROR, TAG, "Could not get methodId mid_invokeBeam");\r
467         return JNI_FALSE;\r
468     }\r
469 \r
470 \r
471     jboolean isSuccess = (*env)->CallBooleanMethod(env, adapter, mid_invokeBeam, g_activity);\r
472     if (!isSuccess)\r
473     {\r
474         OIC_LOG(ERROR, TAG, "invokeBeam has failed");\r
475     }\r
476     OIC_LOG(DEBUG, TAG, "cANativeNfcInvokeBeam : OUT");\r
477 \r
478     return isSuccess;\r
479 }\r
480 \r
481 /*\r
482  * Class:     org_iotivity_ca_CaNfcInterface\r
483  * Method:    caNativeNfcPacketReceived\r
484  * Signature: ([B)V\r
485  */\r
486 JNIEXPORT void JNICALL\r
487 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcPacketReceived(JNIEnv *env, jobject obj,\r
488                                                               jbyteArray data)\r
489 {\r
490     OIC_LOG(DEBUG, TAG, "caNfcPacketReceived : IN");\r
491     VERIFY_NON_NULL_VOID(env, TAG, "env is null");\r
492     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");\r
493     VERIFY_NON_NULL_VOID(data, TAG, "data is null");\r
494 \r
495     char recvBuffer[COAP_MAX_PDU_SIZE] = {0};\r
496 \r
497     // get Byte Array and covert to char*\r
498     jint length = (*env)->GetArrayLength(env, data);\r
499 \r
500     if (length >= COAP_MAX_PDU_SIZE)\r
501     {\r
502         OIC_LOG_V(ERROR, TAG, "caNfcPacketReceived - Invalid CoAP length : %d",\r
503                   length);\r
504         return;\r
505     }\r
506 \r
507     jboolean isCopy;\r
508     jbyte *jni_received_data = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);\r
509 \r
510     OIC_LOG_V(DEBUG, TAG, "caNfcPacketReceived - raw data received : %s",\r
511               jni_received_data);\r
512 \r
513     memcpy(recvBuffer, (const char*) jni_received_data, length);\r
514     (*env)->ReleaseByteArrayElements(env, data, jni_received_data, JNI_ABORT);\r
515 \r
516     const char* address = "AA:BB:CC:DD:EE:FF";\r
517 \r
518     OIC_LOG_V(DEBUG, TAG, "caNfcPacketReceived - data. : %s, %d",\r
519               recvBuffer, length);\r
520 \r
521     CASecureEndpoint_t sep =\r
522             {.endpoint =\r
523                 {.adapter = CA_ADAPTER_NFC,\r
524                  .flags = CA_DEFAULT_FLAGS\r
525                 }\r
526              };\r
527     OICStrcpy(sep.endpoint.addr, sizeof(sep.endpoint.addr), address);\r
528 \r
529     g_packetReceivedCallback(&sep, recvBuffer, length);\r
530     OIC_LOG(DEBUG, TAG, "caNfcPacketReceived : OUT");\r
531 }\r
532 \r
533 CAResult_t CANfcSendDataImpl(const CAEndpoint_t * ep, const char* data, uint32_t dataLen)\r
534 {\r
535     VERIFY_NON_NULL(ep, TAG, "CANfcSendDataImpl : endpoint is null");\r
536     VERIFY_NON_NULL(data, TAG, "CANfcSendDataImpl : data is null");\r
537     VERIFY_NON_NULL(g_jvm, TAG, "CANfcSendDataImpl : g_jvm is null");\r
538 \r
539     OIC_LOG(INFO, TAG, "CANfcSendDataImpl moved env outside");\r
540     bool isAttached = false;\r
541     JNIEnv* env;\r
542     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
543     if (JNI_OK != res)\r
544     {\r
545         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
546         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
547 \r
548         if (JNI_OK != res)\r
549         {\r
550             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
551             return CA_STATUS_FAILED;\r
552         }\r
553         isAttached = true;\r
554     }\r
555 \r
556     OIC_LOG(INFO, TAG, "creating send buffer");\r
557     jbyteArray sendData = (*env)->NewByteArray(env, dataLen);\r
558     if (!sendData)\r
559     {\r
560         OIC_LOG(ERROR, TAG, "Failed to create ByteArray");\r
561         if (isAttached)\r
562         {\r
563             (*g_jvm)->DetachCurrentThread(g_jvm);\r
564         }\r
565 \r
566         return CA_SEND_FAILED;\r
567 \r
568     }\r
569 \r
570     (*env)->SetByteArrayRegion(env, sendData, 0, dataLen, (jbyte*) data);\r
571 \r
572     (*env)->CallVoidMethod(env, g_nfcInterface, g_sendMethod, sendData);\r
573     OIC_LOG(DEBUG, TAG, "send data through NFC");\r
574 \r
575     (*env)->DeleteLocalRef(env, sendData);\r
576 \r
577     if (isAttached)\r
578     {\r
579         (*g_jvm)->DetachCurrentThread(g_jvm);\r
580     }\r
581 \r
582     return CA_STATUS_OK;\r
583 }\r
584 \r
585 void CANFCSendData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)\r
586 {\r
587     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");\r
588     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");\r
589 \r
590     // JNI to Send data\r
591     CANfcSendDataImpl(endpoint, data, dataLength);\r
592     return;\r
593 }\r
594 \r