replace : iotivity -> iotivity-sec
[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 "octhread.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 = NULL;\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, CLASS_NFCINTERFACE);\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 = NULL;\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, CLASS_NFCINTERFACE);\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     jmethodID mid_getBytes = CAGetJNIMethodID(env, "java/lang/String", "getBytes",\r
345                                               "(Ljava/lang/String;)[B");\r
346     if (!mid_getBytes)\r
347     {\r
348         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_getBytes");\r
349         return NULL;\r
350     }\r
351 \r
352     jbyteArray mimeTypeArr = (*env)->CallObjectMethod(env, mimeString, mid_getBytes,\r
353                                                       charSetString);\r
354     if (!mimeTypeArr)\r
355     {\r
356         OIC_LOG(ERROR, TAG, "getBytes failed for mimeTypeArr");\r
357     }\r
358 \r
359     jclass cid_NdefRecord = (*env)->FindClass(env, "android/nfc/NdefRecord");\r
360     if (!cid_NdefRecord)\r
361     {\r
362         OIC_LOG(ERROR, TAG, "Could not get NdefRecord class for cid_NdefRecord");\r
363         return NULL;\r
364     }\r
365 \r
366     jmethodID mid_createRecord = (*env)->GetMethodID(env, cid_NdefRecord, "<init>",\r
367                                                      "(S[B[B[B)V");\r
368     if (!mid_createRecord)\r
369     {\r
370         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_createRecord");\r
371         return NULL;\r
372     }\r
373 \r
374     jfieldID fid_tnfType = (*env)->GetStaticFieldID(env, cid_NdefRecord, "TNF_MIME_MEDIA", "S");\r
375 \r
376     jint tnfType = (*env)->GetStaticShortField(env, cid_NdefRecord, fid_tnfType);\r
377     OIC_LOG_V(ERROR, TAG, "tnfType : %d", tnfType);\r
378 \r
379     jbyteArray nullArr = (*env)->NewByteArray(env, 0);\r
380 \r
381     jobject ndefRecord = (*env)->NewObject(env, cid_NdefRecord, mid_createRecord, tnfType,\r
382                                            mimeTypeArr, nullArr, sendData);\r
383     if (!ndefRecord)\r
384     {\r
385         OIC_LOG(ERROR, TAG, "createNdefRecord failed for ndefRecord");\r
386         return NULL;\r
387     }\r
388 \r
389     jclass cid_NdefMsg = (*env)->FindClass(env, "android/nfc/NdefMessage");\r
390     if (!cid_NdefMsg)\r
391     {\r
392         OIC_LOG(ERROR, TAG, "Could not get NdefMessage class for cid_NdefMsg");\r
393         return NULL;\r
394     }\r
395 \r
396     jmethodID mid_createMsg = (*env)->GetMethodID(env, cid_NdefMsg, "<init>",\r
397                                                   "([Landroid/nfc/NdefRecord;)V");\r
398     if (!mid_createMsg)\r
399     {\r
400         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_createMsg");\r
401         return NULL;\r
402     }\r
403     jobjectArray tempArr = (jobjectArray) (*env)->NewObjectArray(env, 1, cid_NdefRecord,\r
404                                                                  ndefRecord);\r
405 \r
406     jobject ndefMsg = (*env)->NewObject(env, cid_NdefMsg, mid_createMsg, tempArr);\r
407     if (!ndefMsg)\r
408     {\r
409         OIC_LOG(ERROR, TAG, "createNdefMessage failed for ndefMsg");\r
410         return NULL;\r
411     }\r
412 \r
413     OIC_LOG(DEBUG, TAG, "caNativeNfcCreateNdefMessage : OUT");\r
414     return ndefMsg;\r
415 }\r
416 \r
417 /*\r
418  * Class:     org_iotivity_ca_CaNfcInterface\r
419  * Method:    caNativeNfcInvokeBeam\r
420  * Signature: ()Z\r
421  */\r
422 JNIEXPORT jboolean JNICALL\r
423 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcInvokeBeam(JNIEnv *env, jobject obj)\r
424 {\r
425     OIC_LOG(DEBUG, TAG, "cANativeNfcInvokeBeam : IN");\r
426     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);\r
427     VERIFY_NON_NULL_RET(obj, TAG, "obj is null", false);\r
428     VERIFY_NON_NULL_RET(g_context, TAG, "g_context is null", false);\r
429     VERIFY_NON_NULL_RET(g_activity, TAG, "g_activity is null", false);\r
430 \r
431     jclass cid_NfcAdapter = (*env)->FindClass(env, "android/nfc/NfcAdapter");\r
432     if (!cid_NfcAdapter)\r
433     {\r
434         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter cid_NfcAdapter ");\r
435         return JNI_FALSE;\r
436     }\r
437 \r
438     jmethodID mid_getAdapter = (*env)->GetStaticMethodID(env, cid_NfcAdapter,\r
439                                        "getDefaultAdapter",\r
440                                        "(Landroid/content/Context;)Landroid/nfc/NfcAdapter;");\r
441     if (!mid_getAdapter)\r
442     {\r
443         OIC_LOG(ERROR, TAG, "Could not get methodId mid_getAdapter");\r
444         return JNI_FALSE;\r
445     }\r
446 \r
447     jobject adapter = (*env)->CallStaticObjectMethod(env, cid_NfcAdapter, mid_getAdapter,\r
448                                                      g_context);\r
449     if (!adapter)\r
450     {\r
451         OIC_LOG(ERROR, TAG, "getDefaultAdapter failed adapter");\r
452         return JNI_FALSE;\r
453     }\r
454 \r
455     jmethodID mid_invokeBeam = (*env)->GetMethodID(env, cid_NfcAdapter, "invokeBeam",\r
456                                                    "(Landroid/app/Activity;)Z");\r
457     if (!mid_invokeBeam)\r
458     {\r
459         OIC_LOG(ERROR, TAG, "Could not get methodId mid_invokeBeam");\r
460         return JNI_FALSE;\r
461     }\r
462 \r
463 \r
464     jboolean isSuccess = (*env)->CallBooleanMethod(env, adapter, mid_invokeBeam, g_activity);\r
465     if (!isSuccess)\r
466     {\r
467         OIC_LOG(ERROR, TAG, "invokeBeam has failed");\r
468     }\r
469     OIC_LOG(DEBUG, TAG, "cANativeNfcInvokeBeam : OUT");\r
470 \r
471     return isSuccess;\r
472 }\r
473 \r
474 /*\r
475  * Class:     org_iotivity_ca_CaNfcInterface\r
476  * Method:    caNativeNfcPacketReceived\r
477  * Signature: ([B)V\r
478  */\r
479 JNIEXPORT void JNICALL\r
480 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcPacketReceived(JNIEnv *env, jobject obj,\r
481                                                               jbyteArray data)\r
482 {\r
483     OIC_LOG(DEBUG, TAG, "caNfcPacketReceived : IN");\r
484     VERIFY_NON_NULL_VOID(env, TAG, "env is null");\r
485     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");\r
486     VERIFY_NON_NULL_VOID(data, TAG, "data is null");\r
487 \r
488     char recvBuffer[COAP_MAX_PDU_SIZE] = {0};\r
489 \r
490     // get Byte Array and covert to char*\r
491     jint length = (*env)->GetArrayLength(env, data);\r
492 \r
493     if (length >= COAP_MAX_PDU_SIZE)\r
494     {\r
495         OIC_LOG_V(ERROR, TAG, "caNfcPacketReceived - Invalid CoAP length : %d",\r
496                   length);\r
497         return;\r
498     }\r
499 \r
500     jboolean isCopy;\r
501     jbyte *jni_received_data = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);\r
502 \r
503     OIC_LOG_V(DEBUG, TAG, "caNfcPacketReceived - raw data received : %s",\r
504               jni_received_data);\r
505 \r
506     memcpy(recvBuffer, (const char*) jni_received_data, length);\r
507     (*env)->ReleaseByteArrayElements(env, data, jni_received_data, JNI_ABORT);\r
508 \r
509     const char* address = "AA:BB:CC:DD:EE:FF";\r
510 \r
511     OIC_LOG_V(DEBUG, TAG, "caNfcPacketReceived - data. : %s, %d",\r
512               recvBuffer, length);\r
513 \r
514     CASecureEndpoint_t sep =\r
515             {.endpoint =\r
516                 {.adapter = CA_ADAPTER_NFC,\r
517                  .flags = CA_DEFAULT_FLAGS\r
518                 }\r
519              };\r
520     OICStrcpy(sep.endpoint.addr, sizeof(sep.endpoint.addr), address);\r
521 \r
522     g_packetReceivedCallback(&sep, recvBuffer, length);\r
523     OIC_LOG(DEBUG, TAG, "caNfcPacketReceived : OUT");\r
524 }\r
525 \r
526 CAResult_t CANfcSendDataImpl(const CAEndpoint_t * ep, const char* data, uint32_t dataLen)\r
527 {\r
528     VERIFY_NON_NULL(ep, TAG, "CANfcSendDataImpl : endpoint is null");\r
529     VERIFY_NON_NULL(data, TAG, "CANfcSendDataImpl : data is null");\r
530     VERIFY_NON_NULL(g_jvm, TAG, "CANfcSendDataImpl : g_jvm is null");\r
531 \r
532     OIC_LOG(INFO, TAG, "CANfcSendDataImpl moved env outside");\r
533     bool isAttached = false;\r
534     JNIEnv* env = NULL;\r
535     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
536     if (JNI_OK != res)\r
537     {\r
538         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
539         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
540 \r
541         if (JNI_OK != res)\r
542         {\r
543             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
544             return CA_STATUS_FAILED;\r
545         }\r
546         isAttached = true;\r
547     }\r
548 \r
549     OIC_LOG(INFO, TAG, "creating send buffer");\r
550     jbyteArray sendData = (*env)->NewByteArray(env, dataLen);\r
551     if (!sendData)\r
552     {\r
553         OIC_LOG(ERROR, TAG, "Failed to create ByteArray");\r
554         if (isAttached)\r
555         {\r
556             (*g_jvm)->DetachCurrentThread(g_jvm);\r
557         }\r
558 \r
559         return CA_SEND_FAILED;\r
560 \r
561     }\r
562 \r
563     (*env)->SetByteArrayRegion(env, sendData, 0, dataLen, (jbyte*) data);\r
564 \r
565     (*env)->CallVoidMethod(env, g_nfcInterface, g_sendMethod, sendData);\r
566     OIC_LOG(DEBUG, TAG, "send data through NFC");\r
567 \r
568     (*env)->DeleteLocalRef(env, sendData);\r
569 \r
570     if (isAttached)\r
571     {\r
572         (*g_jvm)->DetachCurrentThread(g_jvm);\r
573     }\r
574 \r
575     return CA_STATUS_OK;\r
576 }\r
577 \r
578 void CANFCSendData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)\r
579 {\r
580     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");\r
581     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");\r
582 \r
583     // JNI to Send data\r
584     CANfcSendDataImpl(endpoint, data, dataLength);\r
585     return;\r
586 }\r
587 \r