Merge branch 'master' into group-manager
[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     jclass cid_NfcAdapter = (*env)->FindClass(env, "android/nfc/NfcAdapter");\r
74     if (!cid_NfcAdapter)\r
75     {\r
76         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter class");\r
77         return CA_STATUS_FAILED;\r
78     }\r
79 \r
80     jmethodID mid_getAdapter = (*env)->GetStaticMethodID(env, cid_NfcAdapter,\r
81                                        "getDefaultAdapter",\r
82                                        "(Landroid/content/Context;)Landroid/nfc/NfcAdapter;");\r
83     if (!mid_getAdapter)\r
84     {\r
85         OIC_LOG(ERROR, TAG, "Could not get methodId mid_getAdapter");\r
86         return CA_STATUS_FAILED;\r
87     }\r
88 \r
89     jobject adapter = (*env)->CallStaticObjectMethod(env, cid_NfcAdapter, mid_getAdapter,\r
90                                                      g_context);\r
91     if (!adapter)\r
92     {\r
93         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter");\r
94         return CA_STATUS_FAILED;\r
95     }\r
96 \r
97     jmethodID mid_setCallback = (*env)->GetMethodID(\r
98         env, cid_NfcAdapter, "setNdefPushMessageCallback",\r
99         "(Landroid/nfc/NfcAdapter$CreateNdefMessageCallback;Landroid/app/Activity;"\r
100         "[Landroid/app/Activity;)V");\r
101     if (!mid_setCallback)\r
102     {\r
103         OIC_LOG(ERROR, TAG, "Could not get mid_setCallback");\r
104         return CA_STATUS_FAILED;\r
105     }\r
106 \r
107     jclass cid_Activity = (*env)->FindClass(env, "android/app/Activity");\r
108     if (!cid_Activity)\r
109     {\r
110         OIC_LOG(ERROR, TAG, "Could not get Activity class");\r
111         return CA_STATUS_FAILED;\r
112     }\r
113 \r
114     jobjectArray tempArr = (jobjectArray) (*env)->NewObjectArray(env, 0, cid_Activity, NULL);\r
115     (*env)->CallVoidMethod(env, adapter, mid_setCallback, g_nfcInterface, g_activity, tempArr);\r
116 \r
117     OIC_LOG(DEBUG, TAG, "SetCreateNdefMessageCallbackfromNative OUT");\r
118     return CA_STATUS_OK;\r
119 }\r
120 \r
121 CAResult_t CANfcCreateJniInterfaceObject()\r
122 {\r
123     OIC_LOG(DEBUG, TAG, "CANfcCreateJniInterfaceObject IN");\r
124 \r
125     if (!g_context)\r
126     {\r
127         OIC_LOG(ERROR, TAG, "g_context is null");\r
128         return CA_STATUS_FAILED;\r
129     }\r
130 \r
131     if (!g_jvm)\r
132     {\r
133         OIC_LOG(ERROR, TAG, "g_jvm is null");\r
134         return CA_STATUS_FAILED;\r
135     }\r
136 \r
137     bool isAttached = false;\r
138     JNIEnv* env;\r
139     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
140     if (JNI_OK != res)\r
141     {\r
142         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
143         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
144 \r
145         if (JNI_OK != res)\r
146         {\r
147             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
148             return CA_STATUS_FAILED;\r
149         }\r
150         isAttached = true;\r
151     }\r
152 \r
153     jclass jni_NfcInterface = (*env)->FindClass(env, "org/iotivity/ca/CaNfcInterface");\r
154     if (!jni_NfcInterface)\r
155     {\r
156         OIC_LOG(ERROR, TAG, "Could not get CaNfcInterface class");\r
157         goto error_exit;\r
158     }\r
159 \r
160     jmethodID NfcInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_NfcInterface, "<init>",\r
161                                             "(Landroid/content/Context;Landroid/app/Activity;)V");\r
162     if (!NfcInterfaceConstructorMethod)\r
163     {\r
164         OIC_LOG(ERROR, TAG, "Could not get CaNfcInterface constructor method");\r
165         goto error_exit;\r
166     }\r
167 \r
168     jobject jni_nfcInstance = (*env)->NewObject(env, jni_NfcInterface,\r
169                                                 NfcInterfaceConstructorMethod, g_context,\r
170                                                 g_activity);\r
171     if (!jni_nfcInstance)\r
172     {\r
173         OIC_LOG(ERROR, TAG, "Create instance for CaNfcInterface failed");\r
174         goto error_exit;\r
175     }\r
176 \r
177     g_nfcInterface = (*env)->NewGlobalRef(env, jni_nfcInstance);\r
178     if (!g_nfcInterface)\r
179     {\r
180         OIC_LOG(ERROR, TAG, "NewGlobalRef  for nfcInterface failed");\r
181         goto error_exit;\r
182     }\r
183 \r
184     OIC_LOG(DEBUG, TAG, "Create instance for CaNfcInterface");\r
185 \r
186     CAResult_t result = SetCreateNdefMessageCallbackfromNative(env);\r
187     if (CA_STATUS_OK != result)\r
188     {\r
189         OIC_LOG(ERROR, TAG, "SetCreateNdefMessageCallbackfromNative failed");\r
190         goto error_exit;\r
191     }\r
192 \r
193     if (isAttached)\r
194     {\r
195         (*g_jvm)->DetachCurrentThread(g_jvm);\r
196     }\r
197 \r
198     OIC_LOG(DEBUG, TAG, "CANfcCreateJniInterfaceObject OUT");\r
199     return CA_STATUS_OK;\r
200 \r
201 error_exit:\r
202     if (isAttached)\r
203     {\r
204         (*g_jvm)->DetachCurrentThread(g_jvm);\r
205     }\r
206 \r
207     return CA_STATUS_FAILED;\r
208 }\r
209 \r
210 CAResult_t CAInitializeNfcServer()\r
211 {\r
212     CANfcJniInit();\r
213     CANfcJNISetContext();\r
214 \r
215     CAResult_t result = CANfcCreateJniInterfaceObject();\r
216     if (CA_STATUS_OK != result)\r
217     {\r
218         OIC_LOG(ERROR, TAG, "CANfcJniInit failed");\r
219     }\r
220 \r
221     return result;\r
222 }\r
223 \r
224 CAResult_t CANFCStartServer()\r
225 {\r
226     bool isAttached = false;\r
227 \r
228     OIC_LOG(INFO, TAG, "CANFCStartServer : IN");\r
229 \r
230     JNIEnv* env;\r
231     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
232     if (JNI_OK != res)\r
233     {\r
234         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
235         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
236 \r
237         if (JNI_OK != res)\r
238         {\r
239             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
240             return CA_STATUS_FAILED;\r
241         }\r
242         isAttached = true;\r
243     }\r
244 \r
245     jclass jni_NfcInterface = (*env)->FindClass(env, "org/iotivity/ca/CaNfcInterface");\r
246     if (!jni_NfcInterface)\r
247     {\r
248         OIC_LOG(ERROR, TAG, "Could not get CaNFCClientInterface class");\r
249         goto error_exit;\r
250     }\r
251 \r
252     jmethodID methodId = (*env)->GetMethodID(env, jni_NfcInterface, "caNfcInitialize", "()V");\r
253     if (!methodId)\r
254     {\r
255         OIC_LOG(ERROR, TAG, "Could not get methodId");\r
256         goto error_exit;\r
257     }\r
258 \r
259     if (!g_nfcInterface)\r
260     {\r
261         OIC_LOG(ERROR, TAG, "g_nfcInterface NULL");\r
262         goto error_exit;\r
263     }\r
264 \r
265     (*env)->CallVoidMethod(env, g_nfcInterface, methodId);\r
266     OIC_LOG(DEBUG, TAG, "caNfcInitialize");\r
267 \r
268     jmethodID sendDataMethodId = (*env)->GetMethodID(env, jni_NfcInterface, "processSendRquest",\r
269                                                      "([B)V");\r
270     if (!sendDataMethodId)\r
271     {\r
272         OIC_LOG(ERROR, TAG, "Could not get sendDataMethodId");\r
273         goto error_exit;\r
274     }\r
275 \r
276     g_sendMethod = sendDataMethodId;\r
277 \r
278     if (isAttached)\r
279     {\r
280         (*g_jvm)->DetachCurrentThread(g_jvm);\r
281     }\r
282 \r
283     return CA_STATUS_OK;\r
284 \r
285 error_exit:\r
286     if (isAttached)\r
287     {\r
288         (*g_jvm)->DetachCurrentThread(g_jvm);\r
289     }\r
290     return CA_STATUS_FAILED;\r
291 \r
292 }\r
293 \r
294 void CANFCStopServer()\r
295 {\r
296     // JNI Call to unregstier nfc adapter\r
297 }\r
298 \r
299 /*\r
300  * Class:     org_iotivity_ca_CaNfcInterface\r
301  * Method:    caNativeNfcCreateNdefMessage\r
302  * Signature: ([B)Landroid/nfc/NdefMessage;\r
303  */\r
304 JNIEXPORT jobject JNICALL\r
305 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcCreateNdefMessage(JNIEnv *env, jobject obj,\r
306                                                                  jbyteArray sendData)\r
307 {\r
308     OIC_LOG(DEBUG, TAG, "caNativeNfcCreateNdefMessage : IN");\r
309     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);\r
310     VERIFY_NON_NULL_RET(obj, TAG, "obj is null", NULL);\r
311 \r
312     const char *mime = "application/org.iotivity.ca.sample_service";\r
313     jstring mimeString = (*env)->NewStringUTF(env, mime);\r
314     if (!mimeString)\r
315     {\r
316         OIC_LOG(ERROR, TAG, "NewStringUTF failed for mimeString");\r
317         return NULL;\r
318     }\r
319 \r
320     const char *type = "US_ASCII";\r
321     jstring charSetString = (*env)->NewStringUTF(env, type);\r
322     if (!charSetString)\r
323     {\r
324         OIC_LOG(ERROR, TAG, "NewStringUTF failed for charSetString");\r
325         return NULL;\r
326     }\r
327 \r
328     jclass cid_string = (*env)->FindClass(env, "java/lang/String");\r
329     if (!cid_string)\r
330     {\r
331         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter class for cid_string");\r
332         return NULL;\r
333     }\r
334 \r
335     jmethodID mid_getBytes = (*env)->GetMethodID(env, cid_string, "getBytes",\r
336                                                  "(Ljava/lang/String;)[B");\r
337     if (!mid_getBytes)\r
338     {\r
339         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_getBytes");\r
340         return NULL;\r
341     }\r
342 \r
343     jbyteArray mimeTypeArr = (*env)->CallObjectMethod(env, mimeString, mid_getBytes,\r
344                                                       charSetString);\r
345     if (!mimeTypeArr)\r
346     {\r
347         OIC_LOG(ERROR, TAG, "getBytes failed for mimeTypeArr");\r
348     }\r
349 \r
350     jclass cid_NdefRecord = (*env)->FindClass(env, "android/nfc/NdefRecord");\r
351     if (!cid_NdefRecord)\r
352     {\r
353         OIC_LOG(ERROR, TAG, "Could not get NdefRecord class for cid_NdefRecord");\r
354         return NULL;\r
355     }\r
356 \r
357     jmethodID mid_createRecord = (*env)->GetMethodID(env, cid_NdefRecord, "<init>",\r
358                                                      "(S[B[B[B)V");\r
359     if (!mid_createRecord)\r
360     {\r
361         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_createRecord");\r
362         return NULL;\r
363     }\r
364 \r
365     jfieldID fid_tnfType = (*env)->GetStaticFieldID(env, cid_NdefRecord, "TNF_MIME_MEDIA", "S");\r
366 \r
367     jint tnfType = (*env)->GetStaticShortField(env, cid_NdefRecord, fid_tnfType);\r
368     OIC_LOG_V(ERROR, TAG, "tnfType : %d", tnfType);\r
369 \r
370     jbyteArray nullArr = (*env)->NewByteArray(env, 0);\r
371 \r
372     jobject ndefRecord = (*env)->NewObject(env, cid_NdefRecord, mid_createRecord, tnfType,\r
373                                            mimeTypeArr, nullArr, sendData);\r
374     if (!ndefRecord)\r
375     {\r
376         OIC_LOG(ERROR, TAG, "createNdefRecord failed for ndefRecord");\r
377         return NULL;\r
378     }\r
379 \r
380     jclass cid_NdefMsg = (*env)->FindClass(env, "android/nfc/NdefMessage");\r
381     if (!cid_NdefMsg)\r
382     {\r
383         OIC_LOG(ERROR, TAG, "Could not get NdefMessage class for cid_NdefMsg");\r
384         return NULL;\r
385     }\r
386 \r
387     jmethodID mid_createMsg = (*env)->GetMethodID(env, cid_NdefMsg, "<init>",\r
388                                                   "([Landroid/nfc/NdefRecord;)V");\r
389     if (!mid_createMsg)\r
390     {\r
391         OIC_LOG(ERROR, TAG, "Could not get methodId for mid_createMsg");\r
392         return NULL;\r
393     }\r
394     jobjectArray tempArr = (jobjectArray) (*env)->NewObjectArray(env, 1, cid_NdefRecord,\r
395                                                                  ndefRecord);\r
396 \r
397     jobject ndefMsg = (*env)->NewObject(env, cid_NdefMsg, mid_createMsg, tempArr);\r
398     if (!ndefMsg)\r
399     {\r
400         OIC_LOG(ERROR, TAG, "createNdefMessage failed for ndefMsg");\r
401         return NULL;\r
402     }\r
403 \r
404     OIC_LOG(DEBUG, TAG, "caNativeNfcCreateNdefMessage : OUT");\r
405     return ndefMsg;\r
406 }\r
407 \r
408 /*\r
409  * Class:     org_iotivity_ca_CaNfcInterface\r
410  * Method:    caNativeNfcInvokeBeam\r
411  * Signature: ()Z\r
412  */\r
413 JNIEXPORT jboolean JNICALL\r
414 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcInvokeBeam(JNIEnv *env, jobject obj)\r
415 {\r
416     OIC_LOG(DEBUG, TAG, "cANativeNfcInvokeBeam : IN");\r
417     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);\r
418     VERIFY_NON_NULL_RET(obj, TAG, "obj is null", false);\r
419 \r
420     jclass cid_NfcAdapter = (*env)->FindClass(env, "android/nfc/NfcAdapter");\r
421     if (!cid_NfcAdapter)\r
422     {\r
423         OIC_LOG(ERROR, TAG, "Could not get NfcAdapter cid_NfcAdapter ");\r
424         return JNI_FALSE;\r
425     }\r
426 \r
427     jmethodID mid_getAdapter = (*env)->GetStaticMethodID(env, cid_NfcAdapter,\r
428                                        "getDefaultAdapter",\r
429                                        "(Landroid/content/Context;)Landroid/nfc/NfcAdapter;");\r
430     if (!mid_getAdapter)\r
431     {\r
432         OIC_LOG(ERROR, TAG, "Could not get methodId mid_getAdapter");\r
433         return JNI_FALSE;\r
434     }\r
435 \r
436     jobject adapter = (*env)->CallStaticObjectMethod(env, cid_NfcAdapter, mid_getAdapter,\r
437                                                      g_context);\r
438     if (!adapter)\r
439     {\r
440         OIC_LOG(ERROR, TAG, "getDefaultAdapter failed adapter");\r
441         return JNI_FALSE;\r
442     }\r
443 \r
444     jmethodID mid_invokeBeam = (*env)->GetMethodID(env, cid_NfcAdapter, "invokeBeam",\r
445                                                    "(Landroid/app/Activity;)Z");\r
446     if (!mid_invokeBeam)\r
447     {\r
448         OIC_LOG(ERROR, TAG, "Could not get methodId mid_invokeBeam");\r
449         return JNI_FALSE;\r
450     }\r
451 \r
452 \r
453     jboolean isSuccess = (*env)->CallBooleanMethod(env, adapter, mid_invokeBeam, g_activity);\r
454     if (!isSuccess)\r
455     {\r
456         OIC_LOG(ERROR, TAG, "invokeBeam has failed");\r
457     }\r
458     OIC_LOG(DEBUG, TAG, "cANativeNfcInvokeBeam : OUT");\r
459 \r
460     return isSuccess;\r
461 }\r
462 \r
463 /*\r
464  * Class:     org_iotivity_ca_CaNfcInterface\r
465  * Method:    caNativeNfcPacketReceived\r
466  * Signature: ([B)V\r
467  */\r
468 JNIEXPORT void JNICALL\r
469 Java_org_iotivity_ca_CaNfcInterface_caNativeNfcPacketReceived(JNIEnv *env, jobject obj,\r
470                                                               jbyteArray data)\r
471 {\r
472     OIC_LOG(DEBUG, TAG, "caNfcPacketReceived : IN");\r
473     VERIFY_NON_NULL_VOID(env, TAG, "env is null");\r
474     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");\r
475     VERIFY_NON_NULL_VOID(data, TAG, "data is null");\r
476 \r
477     char recvBuffer[COAP_MAX_PDU_SIZE] = {0};\r
478 \r
479     // get Byte Array and covert to char*\r
480     jint length = (*env)->GetArrayLength(env, data);\r
481 \r
482     if (length >= COAP_MAX_PDU_SIZE)\r
483     {\r
484         OIC_LOG_V(ERROR, TAG, "caNfcPacketReceived - Invalid CoAP length : %d",\r
485                   length);\r
486         return;\r
487     }\r
488 \r
489     jboolean isCopy;\r
490     jbyte *jni_received_data = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);\r
491 \r
492     OIC_LOG_V(DEBUG, TAG, "caNfcPacketReceived - raw data received : %s",\r
493               jni_received_data);\r
494 \r
495     memcpy(recvBuffer, (const char*) jni_received_data, length);\r
496     (*env)->ReleaseByteArrayElements(env, data, jni_received_data, JNI_ABORT);\r
497 \r
498     const char* address = "AA:BB:CC:DD:EE:FF";\r
499 \r
500     OIC_LOG_V(DEBUG, TAG, "caNfcPacketReceived - data. : %s, %d",\r
501               recvBuffer, length);\r
502 \r
503     CASecureEndpoint_t sep =\r
504             {.endpoint =\r
505                 {.adapter = CA_ADAPTER_NFC,\r
506                  .flags = CA_DEFAULT_FLAGS\r
507                 }\r
508              };\r
509     OICStrcpy(sep.endpoint.addr, sizeof(sep.endpoint.addr), address);\r
510 \r
511     g_packetReceivedCallback(&sep, recvBuffer, length);\r
512     OIC_LOG(DEBUG, TAG, "caNfcPacketReceived : OUT");\r
513 }\r
514 \r
515 CAResult_t CANfcSendDataImpl(const CAEndpoint_t * ep, const char* data, uint32_t dataLen)\r
516 {\r
517     VERIFY_NON_NULL(ep, TAG, "CANfcSendDataImpl : endpoint is null");\r
518     VERIFY_NON_NULL(data, TAG, "CANfcSendDataImpl : data is null");\r
519     OIC_LOG(INFO, TAG, "CANfcSendDataImpl moved env outside");\r
520     bool isAttached = false;\r
521     JNIEnv* env;\r
522     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);\r
523     if (JNI_OK != res)\r
524     {\r
525         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");\r
526         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);\r
527 \r
528         if (JNI_OK != res)\r
529         {\r
530             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");\r
531             return CA_STATUS_FAILED;\r
532         }\r
533         isAttached = true;\r
534     }\r
535 \r
536     OIC_LOG(INFO, TAG, "creating send buffer");\r
537     jbyteArray sendData = (*env)->NewByteArray(env, dataLen);\r
538     if (!sendData)\r
539     {\r
540         OIC_LOG(ERROR, TAG, "Failed to create ByteArray");\r
541         if (isAttached)\r
542         {\r
543             (*g_jvm)->DetachCurrentThread(g_jvm);\r
544         }\r
545 \r
546         return CA_SEND_FAILED;\r
547 \r
548     }\r
549 \r
550     (*env)->SetByteArrayRegion(env, sendData, 0, dataLen, (jbyte*) data);\r
551 \r
552     (*env)->CallVoidMethod(env, g_nfcInterface, g_sendMethod, sendData);\r
553     OIC_LOG(DEBUG, TAG, "send data through NFC");\r
554 \r
555     (*env)->DeleteLocalRef(env, sendData);\r
556 \r
557     if (isAttached)\r
558     {\r
559         (*g_jvm)->DetachCurrentThread(g_jvm);\r
560     }\r
561 \r
562     return CA_STATUS_OK;\r
563 }\r
564 \r
565 void CANFCSendData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength)\r
566 {\r
567     VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint is NULL");\r
568     VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");\r
569 \r
570     // JNI to Send data\r
571     CANfcSendDataImpl(endpoint, data, dataLength);\r
572     return;\r
573 }\r
574 \r