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