Fixed klockwork memory leaks and modified the logs
[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
15 //#define DEBUG_MODE
16 #define TAG PCF("CA_EDR_SERVER")
17
18 static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
19 static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;";
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
28 static u_arraylist_t *gdeviceStateList = NULL;
29 static u_arraylist_t *gdeviceObjectList = NULL;
30
31 static u_thread_pool_t gThreadPoolHandle = NULL;
32
33 static JavaVM *g_jvm;
34 static jobject gContext;
35
36 static jbyteArray gSendBuffer;
37
38 /**
39  * @var gMutexSocketListManager
40  * @brief Mutex to synchronize socket list update
41  */
42 static u_mutex gMutexSocketListManager;
43
44 // server socket instance
45 static jobject gServerSocketObject = NULL;
46
47 /**
48  * @var gMutexUnicastServer
49  * @brief Mutex to synchronize unicast server
50  */
51 static u_mutex gMutexUnicastServer = NULL;
52
53 /**
54  * @var gStopUnicast
55  * @brief Flag to control the Receive Unicast Data Thread
56  */
57 static bool gStopUnicast = FALSE;
58
59 /**
60  * @var gMutexMulticastServer
61  * @brief Mutex to synchronize secure multicast server
62  */
63 static u_mutex gMutexMulticastServer = NULL;
64
65 /**
66  * @var gStopMulticast
67  * @brief Flag to control the Receive Multicast Data Thread
68  */
69 static bool gStopMulticast = FALSE;
70
71 /**
72  * @var gStopAccept
73  * @brief Flag to control the Accept Thread
74  */
75 static bool gStopAccept = FALSE;
76
77 typedef struct send_data {
78     char* address;
79     char* data;
80     uint32_t id;
81 } data_t;
82
83 /**
84  @brief Thread context information for unicast, multicast and secured unicast server
85  */
86 typedef struct
87 {
88     bool *stopFlag;
89     CAAdapterServerType_t type;
90 } CAAdapterReceiveThreadContext_t;
91
92 typedef struct
93 {
94     bool *stopFlag;
95 } CAAdapterAcceptThreadContext_t;
96
97 // callback instance
98
99 /**
100  * @var gEDRNetworkChangeCallback
101  * @brief Maintains the callback to be notified when data received from remote Bluetooth device
102  */
103 static CAEDRDataReceivedCallback gEDRPacketReceivedCallback = NULL;
104
105 static void CAReceiveHandler(void *data)
106 {
107     OIC_LOG_V(DEBUG, TAG, "start CAReceiveHandler..");
108     OIC_LOG(DEBUG, TAG, "IN");
109     // Input validation
110     VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
111
112     jboolean isAttached = FALSE;
113     JNIEnv* env;
114     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
115     if(res != JNI_OK)
116     {
117         OIC_LOG_V(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
118         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
119
120         if(res != JNI_OK)
121         {
122             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
123             return;
124         }
125         isAttached = TRUE;
126     }
127
128     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
129
130     while (TRUE != *(ctx->stopFlag))
131     {
132         uint32_t idx;
133
134         // if new socket object is added in socket list after below logic is ran.
135         // new socket will be started to read after next while loop
136         uint32_t length = CAEDRServerGetSocketListLength();
137         if(0 == length)
138         {
139             OIC_LOG_V(DEBUG, TAG, "socket list is empty");
140             sleep(1);
141         }
142
143 //        for(idx = 0 ; idx < length ; idx++)
144 //        {
145 //            OIC_LOG_V(DEBUG, TAG, "start CAEDRNativeReadData");
146             CAEDRNativeReadData(env, idx, ctx->type);
147 //        }
148     }
149
150     if(isAttached)
151         (*g_jvm)->DetachCurrentThread(g_jvm);
152
153     if(ctx)
154         OICFree(ctx);
155
156     OIC_LOG(DEBUG, TAG, "OUT");
157 }
158
159 static void CAAcceptHandler(void *data)
160 {
161     int status;
162
163     OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
164
165     jboolean isAttached = FALSE;
166     JNIEnv* env;
167     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
168     if(res != JNI_OK)
169     {
170         OIC_LOG_V(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
171         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
172
173         if(res != JNI_OK)
174         {
175             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
176             return;
177         }
178         isAttached = TRUE;
179     }
180
181     jobject jni_obj_BTSeverSocket = CAEDRNativeListen(env);
182     if(!jni_obj_BTSeverSocket) {
183         OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread: jni_obj_BTSeverSocket is null");
184
185         if(isAttached)
186             (*g_jvm)->DetachCurrentThread(g_jvm);
187
188         return;
189     }
190
191     CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *)data;
192
193     while (TRUE != *(ctx->stopFlag))
194     {
195         OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
196         CAEDRNativeAccept(env, jni_obj_BTSeverSocket);
197     }
198
199     if(isAttached)
200         (*g_jvm)->DetachCurrentThread(g_jvm);
201
202     if(ctx)
203         OICFree(ctx);
204
205     OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
206
207     return;
208 }
209
210
211 // adapter common method
212
213 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, u_thread_pool_t handle)
214 {
215     OIC_LOG_V(DEBUG, TAG, "IN");
216     CAEDRServerInitialize(handle);
217     // FIXME
218     CAEDRStartUnicastServer(NULL, FALSE);
219     OIC_LOG_V(DEBUG, TAG, "OUT");
220     return CA_STATUS_OK;
221 }
222
223 CAResult_t CAEDRServerStop(const int32_t serverFD)
224 {
225     OIC_LOG_V(DEBUG, TAG, "IN");
226     CAEDRStopUnicastServer(-1);
227     CAEDRStopMulticastServer(-1);
228     CAEDRServerTerminate();
229     OIC_LOG_V(DEBUG, TAG, "OUT");
230     return CA_STATUS_OK;
231 }
232
233 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
234 {
235     gEDRPacketReceivedCallback = packetReceivedCallback;
236 }
237
238 /**
239  * Destroy Mutex
240  */
241 static void CAEDRServerDestroyMutex()
242 {
243     OIC_LOG(DEBUG, TAG, "IN");
244
245     if (gMutexUnicastServer)
246     {
247         u_mutex_free(gMutexUnicastServer);
248         gMutexUnicastServer = NULL;
249     }
250
251 #ifdef __WITH_DTLS__
252
253 #endif
254
255     if (gMutexMulticastServer)
256     {
257         u_mutex_free(gMutexMulticastServer);
258         gMutexMulticastServer = NULL;
259     }
260
261     if(gMutexSocketListManager)
262     {
263         u_mutex_free(gMutexSocketListManager);
264         gMutexSocketListManager = NULL;
265     }
266
267     OIC_LOG(DEBUG, TAG, "OUT");
268 }
269
270
271 /*
272  * Create Mutex
273  */
274 static CAResult_t CAEDRServerCreateMutex()
275 {
276     OIC_LOG(DEBUG, TAG, "IN");
277
278     gMutexUnicastServer = u_mutex_new();
279     if (!gMutexUnicastServer)
280     {
281         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
282         return CA_STATUS_FAILED;
283     }
284
285 #ifdef __WITH_DTLS__
286
287 #endif
288
289     gMutexMulticastServer = u_mutex_new();
290     if (!gMutexMulticastServer)
291     {
292         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
293
294         CAEDRServerDestroyMutex();
295         return CA_STATUS_FAILED;
296     }
297
298     gMutexSocketListManager = u_mutex_new();
299     if (!gMutexSocketListManager)
300     {
301         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
302
303         CAEDRServerDestroyMutex();
304         return CA_STATUS_FAILED;
305     }
306
307     OIC_LOG(DEBUG, TAG, "OUT");
308     return CA_STATUS_OK;
309 }
310
311 void CAEDRServerJniInit(JNIEnv *env, JavaVM* jvm)
312 {
313     OIC_LOG_V(DEBUG, TAG, "CAEDRServerJniInit");
314     g_jvm = jvm;
315 }
316
317 void CAEDRServerInitialize(u_thread_pool_t handle)
318 {
319     OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
320
321     gThreadPoolHandle = handle;
322
323     // init mutex
324     CAEDRServerCreateMutex();
325
326     jboolean isAttached = FALSE;
327     JNIEnv* env;
328     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
329     if(res != JNI_OK)
330     {
331         OIC_LOG_V(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
332         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
333
334         if(res != JNI_OK)
335         {
336             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
337             return;
338         }
339         isAttached = TRUE;
340     }
341
342     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
343     if(jni_address)
344     {
345         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
346         OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
347     }
348
349     CAEDRServerNativeCreateDeviceStateList();
350     CAEDRServerNativeCreateDeviceSocketList();
351
352     if(isAttached)
353         (*g_jvm)->DetachCurrentThread(g_jvm);
354
355 //    CAEDRCreateJNIInterfaceObject(gContext); /* create java CAEDRInterface instance*/
356
357     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
358                                                OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
359     if (!ctx)
360     {
361         OIC_LOG(ERROR, TAG, "Out of memory!");
362         return;
363     }
364
365     ctx->stopFlag = &gStopAccept;
366     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAAcceptHandler, (void *)ctx))
367     {
368         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
369         OICFree((void *)ctx);
370         return;
371     }
372
373     OIC_LOG(DEBUG, TAG, "OUT");
374 }
375
376 void CAEDRServerTerminate()
377 {
378     OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
379
380     jboolean isAttached = FALSE;
381     JNIEnv* env;
382     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
383     if(res != JNI_OK)
384     {
385         OIC_LOG_V(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
386         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
387
388         if(res != JNI_OK)
389         {
390             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
391             return;
392         }
393         isAttached = TRUE;
394     }
395
396     gStopAccept = TRUE;
397     gStopMulticast = TRUE;
398     gStopUnicast = TRUE;
399
400     if(isAttached)
401         (*g_jvm)->DetachCurrentThread(g_jvm);
402
403     // delete mutex
404     CAEDRServerDestroyMutex();
405
406     CAEDRServerNativeRemoveAllDeviceState();
407     CAEDRServerNativeRemoveAllDeviceSocket(env);
408 }
409
410 int32_t CAEDRStartUnicastServer(const char* address, bool isSecured)
411 {
412     OIC_LOG_V(DEBUG, TAG, "CAEDRStartUnicastServer(%s)", address);
413
414     u_mutex_lock(gMutexUnicastServer);
415
416     /**
417       * The task to listen for data from unicast is added to the thread pool.
418       * This is a blocking call is made where we try to receive some data..
419       * We will keep waiting until some data is received.
420       * This task will be terminated when thread pool is freed on stopping the adapters.
421       * Thread context will be freed by thread on exit.
422       */
423     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
424                                            OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
425     if (!ctx)
426     {
427         OIC_LOG(ERROR, TAG, "Out of memory!");
428         u_mutex_unlock(gMutexUnicastServer);
429         return CA_MEMORY_ALLOC_FAILED;
430     }
431
432     ctx->stopFlag = &gStopUnicast;
433     ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
434     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAReceiveHandler, (void *)ctx))
435     {
436         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
437         u_mutex_unlock(gMutexUnicastServer);
438         OICFree((void *)ctx);
439         return CA_STATUS_FAILED;
440     }
441     u_mutex_unlock(gMutexUnicastServer);
442
443     OIC_LOG(DEBUG, TAG, "OUT");
444     return CA_STATUS_OK;
445 }
446
447 int32_t CAEDRStartMulticastServer(bool isSecured)
448 {
449     OIC_LOG_V(DEBUG, TAG, "CAEDRStartMulticastServer");
450
451     u_mutex_lock(gMutexMulticastServer);
452
453     /**
454       * The task to listen to data from multicast socket is added to the thread pool.
455       * This is a blocking call is made where we try to receive some data.
456       * We will keep waiting until some data is received.
457       * This task will be terminated when thread pool is freed on stopping the adapters.
458       * Thread context will be freed by thread on exit.
459       */
460     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
461                                            OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
462     if (!ctx)
463     {
464         OIC_LOG(ERROR, TAG, "Out of memory!");
465         u_mutex_unlock(gMutexMulticastServer);
466
467         return CA_MEMORY_ALLOC_FAILED;
468     }
469
470     ctx->stopFlag = &gStopMulticast;
471     ctx->type = CA_MULTICAST_SERVER;
472
473     gStopMulticast = FALSE;
474     if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, CAReceiveHandler, (void *)ctx))
475     {
476         OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
477
478         gStopMulticast = TRUE;
479         u_mutex_unlock(gMutexMulticastServer);
480
481         return CA_STATUS_FAILED;
482     }
483     u_mutex_unlock(gMutexMulticastServer);
484
485     OIC_LOG(DEBUG, TAG, "OUT");
486     return CA_STATUS_OK;
487 }
488
489 int32_t CAEDRStopUnicastServer(int32_t serverID)
490 {
491     OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
492
493     u_mutex_lock(gMutexUnicastServer);
494     gStopUnicast = TRUE;
495     u_mutex_unlock(gMutexUnicastServer);
496
497     return 0;
498 }
499
500 int32_t CAEDRStopMulticastServer(int32_t serverID)
501 {
502     OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
503
504     u_mutex_lock(gMutexMulticastServer);
505     gStopMulticast = true;
506     u_mutex_unlock(gMutexMulticastServer);
507
508     OIC_LOG_V(INFO, TAG, "Multicast server stopped");
509
510     return 0;
511 }
512
513 uint32_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
514 {
515     if(!((*env)->ExceptionCheck(env)))
516     {
517         // check whether this socket object is connected or not.
518         jobject jni_obj_socket = CAEDRServerNativeGetDeviceSocket(id);
519         if(!jni_obj_socket)
520         {
521             return -1;
522         }
523
524         jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
525         const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
526         if(STATE_DISCONNECTED == CAEDRServerIsConnectedDevice(address))
527         {
528             OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: it is not connected yet..");
529             return -1;
530         }
531
532         // start to read through InputStream
533         jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
534         jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getInputStream", "()Ljava/io/InputStream;");
535         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData:  get InputStream..%d, %s", id, address);
536
537         if(!jni_obj_socket)
538         {
539             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
540             return -1;
541         }
542
543         jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getInputStream);
544         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData:  ready inputStream..");
545
546         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
547         jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
548
549         jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
550         jlong nread;
551
552         if(!jni_obj_socket)
553         {
554             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
555             return -1;
556         }
557
558         while ((nread = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read, jbuf, (jint)0, MAX_PDU_BUFFER)) != -1)
559         {
560             if((*env)->ExceptionCheck(env))
561             {
562                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: read Error!!!");
563                 (*env)->ExceptionDescribe(env);
564                 (*env)->ExceptionClear(env);
565                 return -1;
566             }
567             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: reading");
568             jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
569             jint length = strlen((char*)buf);
570             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s", buf);
571             if (buf == NULL)
572             {
573                 return -1;
574             }
575
576             switch (type)
577             {
578                 case CA_UNICAST_SERVER:
579                 case CA_MULTICAST_SERVER:
580                     // Notify data to upper layer
581                     if (gEDRPacketReceivedCallback)
582                     {
583                         uint32_t sentLength = 0;
584                         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] data will be sent to callback routine: %s, %d", buf, length);
585                         gEDRPacketReceivedCallback(address, (void*)buf, length, &sentLength);
586                     }
587                     break;
588 #ifdef __WITH_DTLS__
589                 case CA_SECURED_UNICAST_SERVER:
590                     break;
591 #endif //__WITH_DTLS__
592                 default:
593                     // Should never occur
594                     OIC_LOG_V(DEBUG, TAG, "Invalid server type");
595                     return -1;
596             }
597             (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
598
599             // close socket after data was sent
600             CAEDRNativeServerSocketClose(env, address, id);
601             break;
602         }
603     }
604     else
605     {
606         (*env)->ExceptionDescribe(env);
607         (*env)->ExceptionClear(env);
608         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: env error!!");
609         return -1;
610     }
611
612     return 0;
613 }
614
615 jobject CAEDRNativeListen(JNIEnv *env)
616 {
617     OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
618
619     jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
620     if(!jni_cid_BTAdapter)
621     {
622         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
623         return NULL;
624     }
625
626     // get BTadpater
627     jmethodID jni_mid_getDefaultAdapter =(*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
628     if(!jni_cid_BTAdapter)
629     {
630         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
631         return NULL;
632     }
633
634     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
635     if(!jni_obj_BTAdapter)
636     {
637         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
638         return NULL;
639     }
640
641     // get listen method ID
642     jmethodID jni_mid_listen = (*env)->GetMethodID(env, jni_cid_BTAdapter,
643             "listenUsingInsecureRfcommWithServiceRecord","(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
644     if(!jni_mid_listen)
645     {
646         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
647         return NULL;
648     }
649     // listenUsingInsecureRfcommWithServiceRecord  / listenUsingRfcommWithServiceRecord
650     // setting UUID
651     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
652     if(!jni_cid_uuid)
653     {
654         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
655         return NULL;
656     }
657
658     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
659     if(!jni_mid_fromString)
660     {
661         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
662         return NULL;
663     }
664
665 //  jstring uuid = (*env)->NewStringUTF(env, "0000111f-0000-1000-8000-00805f9b8033");
666     jstring jni_uuid = (*env)->NewStringUTF(env, "00000000-0000-0000-0000-0000cdab0000");
667     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
668     if(!jni_obj_uuid)
669     {
670         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
671         return NULL;
672     }
673
674     // create socket
675     jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
676     jobject jni_obj_BTSeverSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen, jni_name, jni_obj_uuid);
677     if(!jni_obj_BTSeverSocket)
678     {
679         OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen: jni_obj_BTSeverSocket is null");
680         return NULL;
681     }
682
683     gServerSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket);
684
685     return jni_obj_BTSeverSocket;
686 }
687
688 void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject)
689 {
690     if(severSocketObject != NULL)
691     {
692         jclass jni_cid_BTServerSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothServerSocket");
693         if(!jni_cid_BTServerSocket)
694         {
695             OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
696             return;
697         }
698
699         jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept", "()Landroid/bluetooth/BluetoothSocket;");
700         if(!jni_mid_accept)
701         {
702             OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
703             return;
704         }
705
706         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
707
708         jobject jni_obj_BTSocket = NULL;
709         jni_obj_BTSocket = (*env)->CallObjectMethod(env, severSocketObject, jni_mid_accept);
710         if(!jni_obj_BTSocket)
711         {
712             OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
713             return;
714         }
715
716         // get remote address
717         jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
718
719         const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
720         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
721
722         // set socket to list
723         jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
724         CAEDRServerNativeAddDeviceSocketToList(env, jni_socket);
725
726         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
727
728         // update state
729         CAEDRServerUpdateDeviceState(STATE_CONNECTED, address);
730     }
731     else
732     {
733         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: severSocket is close previously");
734     }
735 }
736
737 void CAEDRNativeServerSocketClose(JNIEnv *env, const char* address, uint32_t id)
738 {
739
740     jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
741     if(!jni_cid_BTSocket)
742     {
743         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
744         return;
745     }
746
747     jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
748     if(!jni_mid_close)
749     {
750         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_mid_close is null");
751         return;
752     }
753
754     jobject jni_obj_socket = CAEDRServerNativeGetDeviceSocket(id);
755     if(!jni_obj_socket)
756     {
757         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_obj_socket is not available");
758         return;
759     }
760
761     (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
762
763     if((*env)->ExceptionCheck(env))
764     {
765         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!");
766         (*env)->ExceptionDescribe(env);
767         (*env)->ExceptionClear(env);
768         return;
769     }
770
771     // remove socket to list
772     CAEDRServerNativeRemoveDeviceSocket(env, jni_obj_socket);
773
774     // update state
775     CAEDRServerUpdateDeviceState(STATE_DISCONNECTED, address);
776
777     OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
778 }
779
780 /**
781  * BT State List
782  */
783 void CAEDRServerNativeCreateDeviceStateList()
784 {
785     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList");
786
787     // create new object array
788     if (gdeviceStateList == NULL)
789     {
790         OIC_LOG_V(DEBUG, TAG, "Create device list");
791
792         gdeviceStateList = u_arraylist_create();
793     }
794 }
795
796 void CAEDRServerUpdateDeviceState(uint32_t state, const char* address)
797 {
798     state_t *newstate = (state_t*) OICMalloc( sizeof(state_t) );
799     memset(newstate->address, 0, strlen(newstate->address));
800     strcpy(newstate->address, address);
801     newstate->state = state;
802
803     CAEDRServerNativeAddDeviceStateToList(newstate);
804 }
805
806 void CAEDRServerNativeAddDeviceStateToList(state_t* state)
807 {
808     if(!state)
809     {
810         OIC_LOG(DEBUG, TAG, "[EDR][Native] device is null");
811         return;
812     }
813
814     if(!gdeviceStateList)
815     {
816         OIC_LOG(DEBUG, TAG, "[EDR][Native] gdevice_list is null");
817         return;
818     }
819
820     if(!CAEDRServerNativeIsDeviceInList(state->address)) {
821         CAEDRServerNativeRemoveDevice(state->address); // delete previous state for update new state
822         u_arraylist_add(gdeviceStateList, state);          // update new state
823         OIC_LOG_V(DEBUG, TAG, "Set State to Connected State List");
824     }
825 }
826
827 jboolean CAEDRServerNativeIsDeviceInList(const char* remoteAddress){
828
829     jint index;
830     for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
831     {
832         state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, index);
833         if(!state)
834         {
835             OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
836             return TRUE;
837         }
838
839         if(!strcmp(remoteAddress, state->address))
840         {
841             OIC_LOG_V(DEBUG, TAG, "the device is already set");
842             return TRUE;
843         }
844         else
845         {
846             continue;
847         }
848     }
849
850     OIC_LOG_V(DEBUG, TAG, "there are no the device in list.");
851     return FALSE;
852 }
853
854 void CAEDRServerNativeRemoveAllDeviceState()
855 {
856     OIC_LOG_V(DEBUG, TAG, "CAEDRNativeRemoveAllDevices");
857
858     if(!gdeviceStateList)
859     {
860         OIC_LOG(DEBUG, TAG, "[EDR][Native] gdeviceStateList is null");
861         return;
862     }
863
864     jint index;
865     for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
866     {
867         state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, index);
868         if(!state)
869         {
870             OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
871             continue;
872         }
873         OICFree(state);
874     }
875
876     OICFree(gdeviceStateList);
877     gdeviceStateList = NULL;
878     return;
879 }
880
881 void CAEDRServerNativeRemoveDevice(const char* remoteAddress)
882 {
883     OIC_LOG_V(DEBUG, TAG, "CAEDRNativeRemoveDevice");
884
885     if(!gdeviceStateList)
886     {
887         OIC_LOG(DEBUG, TAG, "[EDR][Native] gdeviceStateList is null");
888         return;
889     }
890
891     jint index;
892     for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
893     {
894         state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, index);
895         if(!state)
896         {
897             OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
898             continue;
899         }
900
901         if(!strcmp(state->address, remoteAddress))
902         {
903             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress);
904             OICFree(state);
905
906             CAEDRServerReorderingDeviceList(index);
907             break;
908         }
909     }
910     OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
911     return;
912 }
913
914 jboolean CAEDRServerIsConnectedDevice(const char* remoteAddress)
915 {
916     OIC_LOG_V(DEBUG, TAG, "CAEDRServerIsConnectedDevice");
917
918     if(!gdeviceStateList)
919     {
920         OIC_LOG(DEBUG, TAG, "[EDR][Native] gdeviceStateList is null");
921         return FALSE;
922     }
923
924     jint index;
925     for (index = 0; index < u_arraylist_length(gdeviceStateList); index++)
926     {
927         state_t* state = (state_t*) u_arraylist_get(gdeviceStateList, index);
928         if(!state)
929         {
930             OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
931             continue;
932         }
933
934         if(!strcmp(state->address, remoteAddress))
935         {
936             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] check whether it is connected or not");
937
938             return state->state;
939         }
940     }
941     OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
942     return FALSE;
943 }
944
945 void CAEDRServerReorderingDeviceList(uint32_t index)
946 {
947     if (index >= gdeviceStateList->length)
948     {
949         return;
950     }
951
952     if (index < gdeviceStateList->length - 1)
953     {
954         memmove(&gdeviceStateList->data[index], &gdeviceStateList->data[index + 1],
955                 (gdeviceStateList->length - index - 1) * sizeof(void *));
956     }
957
958     gdeviceStateList->size--;
959     gdeviceStateList->length--;
960 }
961
962 /**
963  * Device Socket Object List
964  */
965 void CAEDRServerNativeCreateDeviceSocketList()
966 {
967     OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRServerNativeCreateDeviceSocketList");
968
969     // create new object array
970     if (gdeviceObjectList == NULL)
971     {
972         OIC_LOG_V(DEBUG, TAG, "Create Device object list");
973
974         gdeviceObjectList = u_arraylist_create();
975     }
976 }
977
978 void CAEDRServerNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
979 {
980     OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRServerNativeAddDeviceSocketToList");
981
982     if(!deviceSocket)
983     {
984         OIC_LOG(DEBUG, TAG, "[BLE][Native] Device is null");
985         return;
986     }
987
988     if(!gdeviceObjectList)
989     {
990         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
991         return;
992     }
993
994     jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
995     if(!jni_remoteAddress)
996     {
997         OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
998         return;
999     }
1000
1001     u_mutex_lock(gMutexSocketListManager);
1002
1003     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1004
1005     if(!CAEDRServerNativeIsDeviceSocketInList(env, remoteAddress))
1006     {
1007         jobject gDeviceSocker = (*env)->NewGlobalRef(env, deviceSocket);
1008         u_arraylist_add(gdeviceObjectList, gDeviceSocker);
1009         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1010     }
1011
1012     u_mutex_unlock(gMutexSocketListManager);
1013 }
1014
1015 jboolean CAEDRServerNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress)
1016 {
1017     OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsDeviceObjInList");
1018
1019     jint index;
1020     for (index = 0; index < u_arraylist_length(gdeviceObjectList); index++)
1021     {
1022
1023         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, index);
1024         if(!jarrayObj)
1025         {
1026             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1027             return TRUE;
1028         }
1029
1030         jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1031         if(!jni_setAddress)
1032         {
1033             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1034             return TRUE;
1035         }
1036
1037         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1038
1039         if(!strcmp(remoteAddress, setAddress))
1040         {
1041             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1042             return TRUE;
1043         }
1044         else
1045         {
1046             continue;
1047         }
1048     }
1049
1050     OIC_LOG_V(DEBUG, TAG, "there are no the Device obejct in list. we can add");
1051     return FALSE;
1052 }
1053
1054 void CAEDRServerNativeRemoveAllDeviceSocket(JNIEnv *env)
1055 {
1056     OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList");
1057
1058     if(!gdeviceObjectList)
1059     {
1060         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
1061         return;
1062     }
1063
1064     jint index;
1065     for (index = 0; index < u_arraylist_length(gdeviceObjectList); index++)
1066     {
1067         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, index);
1068         if(!jarrayObj)
1069         {
1070             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1071             return;
1072         }
1073         (*env)->DeleteGlobalRef(env, jarrayObj);
1074     }
1075
1076     OICFree(gdeviceObjectList);
1077     gdeviceObjectList = NULL;
1078     return;
1079 }
1080
1081 void CAEDRServerNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket)
1082 {
1083     OIC_LOG_V(DEBUG, TAG, "CAEDRServerNativeRemoveDeviceSocket");
1084
1085     if(!gdeviceObjectList)
1086     {
1087         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
1088         return;
1089     }
1090
1091     u_mutex_lock(gMutexSocketListManager);
1092
1093     jint index;
1094     for (index = 0; index < u_arraylist_length(gdeviceObjectList); index++)
1095     {
1096         jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, index);
1097         if(!jarrayObj)
1098         {
1099             OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1100             continue;
1101         }
1102
1103         jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1104         if(!jni_setAddress)
1105         {
1106             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1107             continue;
1108         }
1109         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1110
1111         jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1112         if(!jni_remoteAddress)
1113         {
1114             OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1115             continue;
1116         }
1117         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1118
1119         if(!strcmp(setAddress, remoteAddress))
1120         {
1121             OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1122             (*env)->DeleteGlobalRef(env, jarrayObj);
1123
1124             CAEDRServerReorderingDeviceSocketList(index);
1125             break;
1126         }
1127     }
1128     u_mutex_unlock(gMutexSocketListManager);
1129
1130     OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1131     return;
1132 }
1133
1134 jobject CAEDRServerNativeGetDeviceSocket(uint32_t idx)
1135 {
1136     OIC_LOG_V(DEBUG, TAG, "CAEDRServerNativeGetDeviceSocket");
1137
1138     if(idx < 0)
1139     {
1140         OIC_LOG(DEBUG, TAG, "[BLE][Native] index is not available");
1141         return NULL;
1142     }
1143
1144     if(!gdeviceObjectList)
1145     {
1146         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
1147         return NULL;
1148     }
1149
1150     jobject jarrayObj = (jobject) u_arraylist_get(gdeviceObjectList, idx);
1151     if(!jarrayObj)
1152     {
1153         OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is not available");
1154         return NULL;
1155     }
1156     return jarrayObj;
1157 }
1158
1159 uint32_t CAEDRServerGetSocketListLength()
1160 {
1161     if(!gdeviceObjectList)
1162     {
1163         OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceObjectList is null");
1164         return 0;
1165     }
1166
1167     uint32_t length = u_arraylist_length(gdeviceObjectList);
1168
1169     return length;
1170 }
1171
1172 void CAEDRServerReorderingDeviceSocketList(uint32_t index)
1173 {
1174     if (index >= gdeviceObjectList->length)
1175     {
1176         return;
1177     }
1178
1179     if (index < gdeviceObjectList->length - 1)
1180     {
1181         memmove(&gdeviceObjectList->data[index], &gdeviceObjectList->data[index + 1],
1182                 (gdeviceObjectList->length - index - 1) * sizeof(void *));
1183     }
1184
1185     gdeviceObjectList->size--;
1186     gdeviceObjectList->length--;
1187 }
1188
1189 void CAEDRServerSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
1190 {
1191     gEDRPacketReceivedCallback = packetReceivedCallback;
1192 }
1193
1194