Fixed prevent and klock work issues reported.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / android / caedrserver.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <jni.h>
4
5 #include "caedrinterface.h"
6 #include "caedrutils.h"
7 #include "caedrserver.h"
8 #include "logger.h"
9 #include "oic_malloc.h"
10 #include "uthreadpool.h" /* for thread pool */
11 #include "umutex.h"
12 #include "uarraylist.h"
13 #include "caadapterutils.h"
14 #include "com_iotivity_jar_CAEDRInterface.h"
15
16 //#define DEBUG_MODE
17 #define TAG PCF("CA_EDR_SERVER")
18
19 static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
20 static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter";
21 static const char *CLASSPATH_BT_UUID = "java/util/UUID";
22
23 static const uint32_t STATE_CONNECTED = 1;
24 static const uint32_t STATE_DISCONNECTED = 0;
25
26 static const uint32_t MAX_PDU_BUFFER = 1024;
27 static const uint32_t MAX_CONNECTED_BT_SUPPORT_CNT = 7;
28
29 static u_thread_pool_t gThreadPoolHandle = NULL;
30
31 static JavaVM *g_jvm;
32 static jobject gContext;
33
34 /**
35  * @var gMutexSocketListManager
36  * @brief Mutex to synchronize socket list update
37  */
38 static u_mutex gMutexSocketListManager;
39
40 // server socket instance
41 static jobject gServerSocketObject = NULL;
42
43 /**
44  * @var gMutexUnicastServer
45  * @brief Mutex to synchronize unicast server
46  */
47 static u_mutex gMutexUnicastServer = NULL;
48
49 /**
50  * @var gStopUnicast
51  * @brief Flag to control the Receive Unicast Data Thread
52  */
53 static bool gStopUnicast = FALSE;
54
55 /**
56  * @var gMutexMulticastServer
57  * @brief Mutex to synchronize secure multicast server
58  */
59 static u_mutex gMutexMulticastServer = NULL;
60
61 /**
62  * @var gMutexMulticastServer
63  * @brief Mutex to synchronize multicast receiver
64  */
65 static u_mutex gMutexReceiver = NULL;
66
67 /**
68  * @var gStopMulticast
69  * @brief Flag to control the Receive Multicast Data Thread
70  */
71 static bool gStopMulticast = FALSE;
72
73 /**
74  * @var gStopAccept
75  * @brief Flag to control the Accept Thread
76  */
77 static bool gStopAccept = FALSE;
78
79
80 static jobject gInputStream = NULL;
81
82 static jobject gSeverSocket = NULL;
83
84 typedef struct send_data {
85     char* address;
86     char* data;
87     uint32_t id;
88 } data_t;
89
90 /**
91  @brief Thread context information for unicast, multicast and secured unicast server
92  */
93 typedef struct
94 {
95     bool *stopFlag;
96     CAAdapterServerType_t type;
97 } CAAdapterReceiveThreadContext_t;
98
99 typedef struct
100 {
101     bool *stopFlag;
102 } CAAdapterAcceptThreadContext_t;
103
104 /**
105  * @var gEDRNetworkChangeCallback
106  * @brief Maintains the callback to be notified when data received from remote Bluetooth device
107  */
108 static CAEDRDataReceivedCallback gEDRPacketReceivedCallback = NULL;
109
110 static void CAReceiveHandler(void *data)
111 {
112     OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
113     // Input validation
114     VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
115
116     jboolean isAttached = FALSE;
117     JNIEnv* env;
118     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
119     if(res != JNI_OK)
120     {
121         OIC_LOG_V(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
122         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
123
124         if(res != JNI_OK)
125         {
126             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
127             return;
128         }
129         isAttached = TRUE;
130     }
131
132     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
133
134     while (TRUE != *(ctx->stopFlag))
135     {
136         uint32_t idx;
137
138         // if new socket object is added in socket list after below logic is ran.
139         // new socket will be started to read after next while loop
140         uint32_t length = CAEDRGetSocketListLength();
141         if(0 == length)
142         {
143             OIC_LOG_V(DEBUG, TAG, "socket list is empty");
144             sleep(1);
145         }
146
147         for(idx = 0 ; idx < length ; idx++)
148         {
149             OIC_LOG_V(DEBUG, TAG, "start CAEDRNativeReadData");
150             CAEDRNativeReadData(env, idx, ctx->type);
151             sleep(1);
152         }
153     }
154
155     if(isAttached)
156         (*g_jvm)->DetachCurrentThread(g_jvm);
157
158     if(ctx)
159         OICFree(ctx);
160
161     OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
162 }
163
164 static void CAAcceptHandler(void *data)
165 {
166     int status;
167
168     OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
169
170     jboolean isAttached = FALSE;
171     JNIEnv* env;
172     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
173     if(res != JNI_OK)
174     {
175         OIC_LOG_V(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
176         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
177
178         if(res != JNI_OK)
179         {
180             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
181             return;
182         }
183         isAttached = TRUE;
184     }
185
186     jobject jni_obj_BTSeverSocket = CAEDRNativeListen(env);
187     if(!jni_obj_BTSeverSocket) {
188         OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread: jni_obj_BTSeverSocket is null");
189
190         if(isAttached)
191             (*g_jvm)->DetachCurrentThread(g_jvm);
192
193         return;
194     }
195
196     gSeverSocket = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket);
197
198     CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *)data;
199
200     if(NULL == ctx)
201     {
202         OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread: ctx is null");
203         return;
204     }
205
206     // it should be initialized for restart accept thread
207     gStopAccept = FALSE;
208
209     while (TRUE != *(ctx->stopFlag))
210     {
211         OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
212
213         // when BT state is changed with Off. its thread will be stopped
214         if(!CAEDRNativeIsEnableBTAdapter(env))
215         {
216             OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
217             gStopAccept = TRUE;
218             gSeverSocket = NULL;
219         }
220         else
221         {
222             CAEDRNativeAccept(env, gSeverSocket);
223         }
224     }
225
226     if(isAttached)
227         (*g_jvm)->DetachCurrentThread(g_jvm);
228
229     if(ctx)
230         OICFree(ctx);
231
232     OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
233
234     return;
235 }
236
237 /**
238  * implement for adapter common method
239  */
240 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, u_thread_pool_t handle)
241 {
242     OIC_LOG_V(DEBUG, TAG, "IN");
243     CAEDRServerInitialize(handle);
244     // FIXME
245     CAEDRStartUnicastServer(NULL, FALSE);
246
247     *serverFD = 1;
248     OIC_LOG_V(DEBUG, TAG, "OUT");
249     return CA_STATUS_OK;
250 }
251
252 CAResult_t CAEDRServerStop(const int32_t serverFD)
253 {
254     OIC_LOG_V(DEBUG, TAG, "IN");
255     CAEDRStopUnicastServer(-1);
256     CAEDRStopMulticastServer(-1);
257     CAEDRServerTerminate();
258     OIC_LOG_V(DEBUG, TAG, "OUT");
259     return CA_STATUS_OK;
260 }
261
262 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
263 {
264     gEDRPacketReceivedCallback = packetReceivedCallback;
265 }
266
267 /**
268  * Destroy Mutex
269  */
270 static void CAEDRServerDestroyMutex()
271 {
272     OIC_LOG(DEBUG, TAG, "IN");
273
274     if (gMutexUnicastServer)
275     {
276         u_mutex_free(gMutexUnicastServer);
277         gMutexUnicastServer = NULL;
278     }
279
280 #ifdef __WITH_DTLS__
281
282 #endif
283
284     if (gMutexMulticastServer)
285     {
286         u_mutex_free(gMutexMulticastServer);
287         gMutexMulticastServer = NULL;
288     }
289
290     if(gMutexSocketListManager)
291     {
292         u_mutex_free(gMutexSocketListManager);
293         gMutexSocketListManager = NULL;
294     }
295
296     OIC_LOG(DEBUG, TAG, "OUT");
297 }
298
299
300 /*
301  * Create Mutex
302  */
303 static CAResult_t CAEDRServerCreateMutex()
304 {
305     OIC_LOG(DEBUG, TAG, "IN");
306
307     gMutexUnicastServer = u_mutex_new();
308     if (!gMutexUnicastServer)
309     {
310         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
311         return CA_STATUS_FAILED;
312     }
313
314 #ifdef __WITH_DTLS__
315
316 #endif
317
318     gMutexMulticastServer = u_mutex_new();
319     if (!gMutexMulticastServer)
320     {
321         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
322
323         CAEDRServerDestroyMutex();
324         return CA_STATUS_FAILED;
325     }
326
327     gMutexSocketListManager = u_mutex_new();
328     if (!gMutexSocketListManager)
329     {
330         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
331
332         CAEDRServerDestroyMutex();
333         return CA_STATUS_FAILED;
334     }
335
336     OIC_LOG(DEBUG, TAG, "OUT");
337     return CA_STATUS_OK;
338 }
339
340 void CAEDRServerJniInit()
341 {
342     OIC_LOG_V(DEBUG, TAG, "CAEDRServerJniInit");
343     g_jvm = CANativeJNIGetJavaVM();
344 }
345
346 void CAEDRServerInitialize(u_thread_pool_t handle)
347 {
348     OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
349
350     gThreadPoolHandle = handle;
351
352     CAEDRServerStartAccpetThread();
353
354     OIC_LOG(DEBUG, TAG, "OUT");
355 }
356
357 void CAEDRServerStartAccpetThread()
358 {
359     CAEDRServerJniInit();
360
361     // init mutex
362     CAEDRServerCreateMutex();
363
364     jboolean isAttached = FALSE;
365     JNIEnv* env;
366     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
367     if(res != JNI_OK)
368     {
369         OIC_LOG_V(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
370         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
371
372         if(res != JNI_OK)
373         {
374             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
375             return;
376         }
377         isAttached = TRUE;
378     }
379
380     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
381     if(jni_address)
382     {
383         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
384         OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
385     }
386
387     CAEDRNativeCreateDeviceStateList();
388     CAEDRNativeCreateDeviceSocketList();
389
390     if(isAttached)
391         (*g_jvm)->DetachCurrentThread(g_jvm);
392
393     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
394                                                OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
395     if (!ctx)
396     {
397         OIC_LOG(ERROR, TAG, "Out of memory!");
398         return;
399     }
400
401     ctx->stopFlag = &gStopAccept;
402     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAAcceptHandler, (void *)ctx))
403     {
404         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
405         OICFree((void *)ctx);
406         return;
407     }
408 }
409
410 void CAEDRServerTerminate()
411 {
412     OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
413
414     jboolean isAttached = FALSE;
415     JNIEnv* env;
416     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
417     if(res != JNI_OK)
418     {
419         OIC_LOG_V(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
420         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
421
422         if(res != JNI_OK)
423         {
424             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
425             return;
426         }
427         isAttached = TRUE;
428     }
429
430     gStopAccept = TRUE;
431     gStopMulticast = TRUE;
432     gStopUnicast = TRUE;
433
434     CAEDRNatvieCloseServerTask(env);
435
436     CAEDRNativeSocketCloseToAll(env);
437
438     // delete mutex
439     CAEDRServerDestroyMutex();
440
441     CAEDRNativeRemoveAllDeviceState();
442     CAEDRNativeRemoveAllDeviceSocket(env);
443
444     if(isAttached)
445             (*g_jvm)->DetachCurrentThread(g_jvm);
446 }
447
448 int32_t CAEDRStartUnicastServer(const char* address, bool isSecured)
449 {
450     OIC_LOG_V(DEBUG, TAG, "CAEDRStartUnicastServer(%s)", address);
451
452     u_mutex_lock(gMutexUnicastServer);
453
454     /**
455       * The task to listen for data from unicast is added to the thread pool.
456       * This is a blocking call is made where we try to receive some data..
457       * We will keep waiting until some data is received.
458       * This task will be terminated when thread pool is freed on stopping the adapters.
459       * Thread context will be freed by thread on exit.
460       */
461     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
462                                            OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
463     if (!ctx)
464     {
465         OIC_LOG(ERROR, TAG, "Out of memory!");
466         u_mutex_unlock(gMutexUnicastServer);
467         return CA_MEMORY_ALLOC_FAILED;
468     }
469
470     ctx->stopFlag = &gStopUnicast;
471     ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
472     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAReceiveHandler, (void *)ctx))
473     {
474         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
475         u_mutex_unlock(gMutexUnicastServer);
476         OICFree((void *)ctx);
477         return CA_STATUS_FAILED;
478     }
479     u_mutex_unlock(gMutexUnicastServer);
480
481     OIC_LOG(DEBUG, TAG, "OUT");
482     return CA_STATUS_OK;
483 }
484
485 int32_t CAEDRStartMulticastServer(bool isSecured)
486 {
487     OIC_LOG_V(DEBUG, TAG, "CAEDRStartMulticastServer");
488
489     u_mutex_lock(gMutexMulticastServer);
490
491     /**
492       * The task to listen to data from multicast socket is added to the thread pool.
493       * This is a blocking call is made where we try to receive some data.
494       * We will keep waiting until some data is received.
495       * This task will be terminated when thread pool is freed on stopping the adapters.
496       * Thread context will be freed by thread on exit.
497       */
498     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
499                                            OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
500     if (!ctx)
501     {
502         OIC_LOG(ERROR, TAG, "Out of memory!");
503         u_mutex_unlock(gMutexMulticastServer);
504
505         return CA_MEMORY_ALLOC_FAILED;
506     }
507
508     ctx->stopFlag = &gStopMulticast;
509     ctx->type = CA_MULTICAST_SERVER;
510
511     gStopMulticast = FALSE;
512     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAReceiveHandler, (void *)ctx))
513     {
514         OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
515
516         gStopMulticast = TRUE;
517         u_mutex_unlock(gMutexMulticastServer);
518
519         return CA_STATUS_FAILED;
520     }
521     u_mutex_unlock(gMutexMulticastServer);
522
523     OIC_LOG(DEBUG, TAG, "OUT");
524     return CA_STATUS_OK;
525 }
526
527 int32_t CAEDRStopUnicastServer(int32_t serverID)
528 {
529     OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
530
531     u_mutex_lock(gMutexUnicastServer);
532     gStopUnicast = TRUE;
533     u_mutex_unlock(gMutexUnicastServer);
534
535     return 0;
536 }
537
538 int32_t CAEDRStopMulticastServer(int32_t serverID)
539 {
540     OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
541
542     u_mutex_lock(gMutexMulticastServer);
543     gStopMulticast = true;
544     u_mutex_unlock(gMutexMulticastServer);
545
546     OIC_LOG_V(INFO, TAG, "Multicast server stopped");
547
548     return 0;
549 }
550
551 uint32_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
552 {
553     if(!CAEDRNativeIsEnableBTAdapter(env))
554     {
555         OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
556         return 0;
557     }
558
559     if(!((*env)->ExceptionCheck(env)))
560     {
561         // check whether this socket object is connected or not.
562         jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
563         if(!jni_obj_socket)
564         {
565             return 0;
566         }
567
568         jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
569         const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
570
571         // check it whether is still connected or not through google api
572         jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
573         if(!ret)
574         {
575             OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now...let close socket");
576         }
577
578         // check it whether is still connected or not through socket state list
579         if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
580         {
581             OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: it is not connected yet..");
582
583             // remove socket to list
584             // this code is related to below read fail exception code
585             CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
586
587             return 0;
588         }
589
590         // start to read through InputStream
591         jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
592         jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getInputStream", "()Ljava/io/InputStream;");
593         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData:  get InputStream..%d, %s", id, address);
594
595         if(!jni_obj_socket)
596         {
597             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
598             return 0;
599         }
600
601         jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getInputStream);
602         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData:  ready inputStream...");
603
604         gInputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
605
606         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
607         jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
608
609         jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
610         jlong nread;
611
612         if(!jni_obj_socket)
613         {
614             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
615             return 0;
616         }
617
618         nread = (*env)->CallIntMethod(env, gInputStream, jni_mid_read, jbuf, (jint)0, MAX_PDU_BUFFER);
619
620         OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
621
622         if(-1 == nread)
623         {
624             OIC_LOG(DEBUG, TAG, "[EDR][Native] read buffer is empty...");
625             return 0;
626         }
627
628         if((*env)->ExceptionCheck(env))
629         {
630             OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: read Error!!!");
631             (*env)->ExceptionDescribe(env);
632             (*env)->ExceptionClear(env);
633
634             // update state to disconnect
635             // the socket will be close next read thread routine
636             CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
637             return 0;
638         }
639
640         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: reading");
641         jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
642         if (buf == NULL)
643         {
644             return 0;
645         }
646
647         jint length = strlen((char*)buf);
648         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
649
650         char responseData[MAX_PDU_BUFFER];
651         memset(responseData, 0, MAX_PDU_BUFFER);
652         strncpy(responseData, (char*)buf, length);
653         responseData[length] = '\0';
654
655         switch (type)
656         {
657             case CA_UNICAST_SERVER:
658             case CA_MULTICAST_SERVER:
659                 // Notify data to upper layer
660                 if (gEDRPacketReceivedCallback)
661                 {
662                   //  u_mutex_lock(gMutexSocketListManager);
663                     uint32_t sentLength = 0;
664                     OIC_LOG_V(DEBUG, TAG, "[EDR][Native] data will be sent to callback routine: %s, %d", responseData, length);
665 //                        sleep(3);
666                     gEDRPacketReceivedCallback(address, (void*)responseData, length, &sentLength);
667                   //  u_mutex_unlock(gMutexSocketListManager);
668                 }
669                 break;
670 #ifdef __WITH_DTLS__
671             case CA_SECURED_UNICAST_SERVER:
672                 break;
673 #endif //__WITH_DTLS__
674             default:
675                 // Should never occur
676                 OIC_LOG_V(DEBUG, TAG, "Invalid server type");
677                 return 0;
678         }
679         (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
680     }
681     else
682     {
683         (*env)->ExceptionDescribe(env);
684         (*env)->ExceptionClear(env);
685         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: env error!!");
686         return 0;
687     }
688
689     return 1;
690 }
691
692 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
693 {
694     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
695
696     if(!CAEDRNativeIsEnableBTAdapter(env))
697     {
698         OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
699         return FALSE;
700     }
701
702     if(!socket)
703     {
704         OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
705         return FALSE;
706     }
707
708     jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
709     if(!jni_cid_BTsocket)
710     {
711         OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
712         return FALSE;
713     }
714
715     jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected", "()Z");
716     if(!jni_mid_isConnected)
717     {
718         OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_mid_isConnected is null.");
719         return FALSE;
720     }
721
722     jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
723
724     return jni_isConnected;
725 }
726
727 void CANativeStartListenTask(JNIEnv *env)
728 {
729     jobject jni_obj_BTSeverSocket = CAEDRNativeListen(env);
730     if(!jni_obj_BTSeverSocket) {
731         OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread: jni_obj_BTSeverSocket is null");
732         return;
733     }
734
735     gSeverSocket = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket);
736 }
737
738 jobject CAEDRNativeListen(JNIEnv *env)
739 {
740     if(!CAEDRNativeIsEnableBTAdapter(env))
741     {
742         OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
743         return NULL;
744     }
745
746     OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
747
748     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
749     if(!jni_cid_BTAdapter)
750     {
751         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
752         return NULL;
753     }
754
755     // get BTadpater
756     jmethodID jni_mid_getDefaultAdapter =(*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
757     if(!jni_cid_BTAdapter)
758     {
759         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
760         return NULL;
761     }
762
763     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
764     if(!jni_obj_BTAdapter)
765     {
766         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
767         return NULL;
768     }
769
770     // get listen method ID
771     jmethodID jni_mid_listen = (*env)->GetMethodID(env, jni_cid_BTAdapter,
772             "listenUsingInsecureRfcommWithServiceRecord","(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
773     if(!jni_mid_listen)
774     {
775         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
776         return NULL;
777     }
778     // listenUsingInsecureRfcommWithServiceRecord  / listenUsingRfcommWithServiceRecord
779     // setting UUID
780     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
781     if(!jni_cid_uuid)
782     {
783         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
784         return NULL;
785     }
786
787     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
788     if(!jni_mid_fromString)
789     {
790         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
791         return NULL;
792     }
793
794 //  jstring uuid = (*env)->NewStringUTF(env, "0000111f-0000-1000-8000-00805f9b8033");
795     jstring jni_uuid = (*env)->NewStringUTF(env, "00000000-0000-0000-0000-0000cdab0000");
796     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
797     if(!jni_obj_uuid)
798     {
799         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
800         return NULL;
801     }
802
803     // create socket
804     jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
805     jobject jni_obj_BTSeverSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen, jni_name, jni_obj_uuid);
806     if(!jni_obj_BTSeverSocket)
807     {
808         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_BTSeverSocket is null");
809         return NULL;
810     }
811
812     gServerSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket);
813
814     return jni_obj_BTSeverSocket;
815 }
816
817 void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject)
818 {
819     if(severSocketObject != NULL)
820     {
821         jclass jni_cid_BTServerSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothServerSocket");
822         if(!jni_cid_BTServerSocket)
823         {
824             OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
825             return;
826         }
827
828         jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept", "()Landroid/bluetooth/BluetoothSocket;");
829         if(!jni_mid_accept)
830         {
831             OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
832             return;
833         }
834
835         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
836
837         jobject jni_obj_BTSocket = NULL;
838         jni_obj_BTSocket = (*env)->CallObjectMethod(env, severSocketObject, jni_mid_accept);
839         if(!jni_obj_BTSocket)
840         {
841             OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
842
843             if((*env)->ExceptionCheck(env))
844             {
845                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
846                 (*env)->ExceptionDescribe(env);
847                 (*env)->ExceptionClear(env);
848                 return;
849             }
850         }
851
852         // get remote address
853         jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
854
855         const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
856         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
857
858         // set socket to list
859         jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
860         CAEDRNativeAddDeviceSocketToList(env, jni_socket);
861
862         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
863
864         // update state
865         CAEDRUpdateDeviceState(STATE_CONNECTED, address);
866     }
867     else
868     {
869         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: severSocket is close previously");
870     }
871 }
872
873 void CAEDRNativeServerSocketClose(JNIEnv *env, const char* address, uint32_t id)
874 {
875     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeServerSocketClose");
876
877     if(!CAEDRNativeIsEnableBTAdapter(env))
878     {
879         OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
880         return;
881     }
882
883     jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
884     if(!jni_cid_BTSocket)
885     {
886         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
887         return;
888     }
889
890     jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
891     if(!jni_mid_close)
892     {
893         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_mid_close is null");
894         return;
895     }
896
897     jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
898     if(!jni_obj_socket)
899     {
900         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_obj_socket is not available");
901         return;
902     }
903
904     (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
905
906     if((*env)->ExceptionCheck(env))
907     {
908         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!");
909         (*env)->ExceptionDescribe(env);
910         (*env)->ExceptionClear(env);
911         return;
912     }
913
914     // remove socket to list
915     CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
916
917     // update state
918     CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
919
920     OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
921 }
922
923 /**
924  * InputStream & BluetoothServerSocket will be close for Terminating
925  */
926 void CAEDRNatvieCloseServerTask(JNIEnv* env)
927 {
928     if(gInputStream)
929     {
930         OIC_LOG_V(DEBUG, TAG, "InputStream will be close");
931         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
932         jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
933         (*env)->CallVoidMethod(env, gInputStream, jni_mid_close);
934         (*env)->DeleteGlobalRef(env, gInputStream);
935     }
936
937     if(gSeverSocket)
938     {
939         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
940
941         jclass jni_cid_BTServerSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothServerSocket");
942         if(!jni_cid_BTServerSocket)
943         {
944             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
945             return;
946         }
947
948         jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
949         if(!jni_mid_accept)
950         {
951             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_mid_accept is null");
952             return;
953         }
954         (*env)->CallVoidMethod(env, gSeverSocket, jni_mid_accept);
955         (*env)->DeleteGlobalRef(env, gSeverSocket);
956
957         OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");
958     }
959 }
960
961 void CAEDRServerSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
962 {
963     gEDRPacketReceivedCallback = packetReceivedCallback;
964 }
965