Fixed Android EDR Crash issue.
[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(bool isSecured)
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(int32_t serverID)
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(int32_t serverID)
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             return CA_STATUS_FAILED;
759         }
760
761         // start to read through InputStream
762         jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
763         if (!jni_cid_BTsocket)
764         {
765             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
766             return CA_STATUS_FAILED;
767         }
768         jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
769                                                                "getInputStream",
770                                                                "()Ljava/io/InputStream;");
771         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData:  get InputStream..%d, %s", id, address);
772
773         if (!jni_obj_socket)
774         {
775             OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
776             return CA_STATUS_FAILED;
777         }
778
779         jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
780                                                                jni_mid_getInputStream);
781         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData:  ready inputStream..");
782
783         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
784         if (!jni_cid_InputStream)
785         {
786             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
787             return CA_STATUS_FAILED;
788         }
789         jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
790
791         jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
792
793         if (!jni_obj_socket)
794         {
795             OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
796             return CA_STATUS_FAILED;
797         }
798
799         ca_mutex_lock(g_mutexInputStream);
800         if (!g_inputStream)
801         {
802             g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
803         }
804
805         jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
806                                             MAX_PDU_BUFFER);
807         ca_mutex_unlock(g_mutexInputStream);
808
809         OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
810
811         if (-1 == length)
812         {
813             OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
814             return CA_STATUS_FAILED;
815         }
816
817         if ((*env)->ExceptionCheck(env))
818         {
819             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
820             (*env)->ExceptionDescribe(env);
821             (*env)->ExceptionClear(env);
822
823             // update state to disconnect
824             // the socket will be close next read thread routine
825             ca_mutex_lock(g_mutexStateList);
826             CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
827             ca_mutex_unlock(g_mutexStateList);
828             (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
829             return CA_STATUS_FAILED;
830         }
831
832         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
833         jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
834         if (NULL == buf)
835         {
836             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
837             return CA_STATUS_FAILED;
838         }
839
840         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
841
842         char responseData[MAX_PDU_BUFFER] = { 0 };
843         memcpy(responseData, (const char*) buf, length);
844
845         switch (type)
846         {
847             case CA_UNICAST_SERVER:
848             case CA_MULTICAST_SERVER:
849                 // Notify data to upper layer
850                 if (g_edrPacketReceivedCallback)
851                 {
852                     uint32_t sentLength = 0;
853                     OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
854                               %s, %d", responseData, length);
855                     g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
856                 }
857                 break;
858
859             default:
860                 // Should never occur
861                 OIC_LOG(ERROR, TAG, "Invalid server type");
862                 return CA_STATUS_FAILED;
863         }
864         (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
865         (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
866     }
867     else
868     {
869         (*env)->ExceptionDescribe(env);
870         (*env)->ExceptionClear(env);
871         OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
872         return CA_STATUS_FAILED;
873     }
874
875     return CA_STATUS_OK;
876 }
877
878 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
879 {
880     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
881
882     if (!CAEDRNativeIsEnableBTAdapter(env))
883     {
884         OIC_LOG(ERROR, TAG, "BT adpater is not enable");
885         return JNI_FALSE;
886     }
887
888     if (!socket)
889     {
890         OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
891         return JNI_FALSE;
892     }
893
894     jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
895     if (!jni_cid_BTsocket)
896     {
897         OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
898         return JNI_FALSE;
899     }
900
901     jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
902                                                         "()Z");
903     if (!jni_mid_isConnected)
904     {
905         OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
906                 - jni_mid_isConnected is null.");
907         return JNI_FALSE;
908     }
909
910     jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
911
912     return jni_isConnected;
913 }
914
915 void CANativeStartListenTask(JNIEnv *env)
916 {
917     jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
918     if (!jni_obj_BTServerSocket)
919     {
920         OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
921         return;
922     }
923
924     ca_mutex_lock(g_mutexServerSocket);
925     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
926     ca_mutex_unlock(g_mutexServerSocket);
927 }
928
929 jobject CAEDRNativeListen(JNIEnv *env)
930 {
931     if (!CAEDRNativeIsEnableBTAdapter(env))
932     {
933         OIC_LOG(ERROR, TAG, "BT adpater is not enable");
934         return NULL;
935     }
936
937     OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
938
939     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
940     if (!jni_cid_BTAdapter)
941     {
942         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
943         return NULL;
944     }
945
946     // get BTadpater
947     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
948                                                                     "getDefaultAdapter",
949                                                                     METHODID_OBJECTNONPARAM);
950     if (!jni_cid_BTAdapter)
951     {
952         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
953         return NULL;
954     }
955
956     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
957                                                                jni_mid_getDefaultAdapter);
958     if (!jni_obj_BTAdapter)
959     {
960         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
961         return NULL;
962     }
963
964     // get listen method ID
965     jmethodID jni_mid_listen = (*env)->GetMethodID(
966             env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
967             "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
968     if (!jni_mid_listen)
969     {
970         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
971         return NULL;
972     }
973     // listenUsingInsecureRfcommWithServiceRecord  / listenUsingRfcommWithServiceRecord
974     // setting UUID
975     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
976     if (!jni_cid_uuid)
977     {
978         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
979         return NULL;
980     }
981
982     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
983             env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
984     if (!jni_mid_fromString)
985     {
986         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
987         return NULL;
988     }
989
990     jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
991     if (!jni_uuid)
992     {
993         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
994         return NULL;
995     }
996     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
997                                                           jni_uuid);
998     if (!jni_obj_uuid)
999     {
1000         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1001         return NULL;
1002     }
1003
1004     // create socket
1005     jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1006     if (!jni_name)
1007     {
1008         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1009         return NULL;
1010     }
1011     jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1012                                                              jni_name, jni_obj_uuid);
1013     if (!jni_obj_BTServerSocket)
1014     {
1015         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1016         return NULL;
1017     }
1018
1019     g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1020
1021     return jni_obj_BTServerSocket;
1022 }
1023
1024 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1025 {
1026     if (NULL != serverSocketObject)
1027     {
1028         jclass jni_cid_BTServerSocket = (*env)->FindClass(
1029                 env, "android/bluetooth/BluetoothServerSocket");
1030         if (!jni_cid_BTServerSocket)
1031         {
1032             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1033             return;
1034         }
1035
1036         jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1037                                                        "()Landroid/bluetooth/BluetoothSocket;");
1038         if (!jni_mid_accept)
1039         {
1040             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1041             return;
1042         }
1043
1044         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1045
1046         jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1047                                                             jni_mid_accept);
1048         if (!jni_obj_BTSocket)
1049         {
1050             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1051
1052             if ((*env)->ExceptionCheck(env))
1053             {
1054                 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1055                 (*env)->ExceptionDescribe(env);
1056                 (*env)->ExceptionClear(env);
1057                 return;
1058             }
1059         }
1060
1061         // get remote address
1062         jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1063         if (!j_str_address)
1064         {
1065             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1066             return;
1067         }
1068
1069         const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1070         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1071
1072         // set socket to list
1073         jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1074         ca_mutex_lock(g_mutexObjectList);
1075         CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1076         ca_mutex_unlock(g_mutexObjectList);
1077
1078         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1079
1080         // update state
1081         ca_mutex_lock(g_mutexStateList);
1082         CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1083         ca_mutex_unlock(g_mutexStateList);
1084         (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1085     }
1086     else
1087     {
1088         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1089     }
1090 }
1091
1092 /**
1093  * InputStream & BluetoothServerSocket will be close for Terminating.
1094  */
1095 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1096 {
1097     if (g_inputStream)
1098     {
1099         OIC_LOG(DEBUG, TAG, "InputStream will be close");
1100         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1101         jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1102         (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1103         (*env)->DeleteGlobalRef(env, g_inputStream);
1104     }
1105
1106     if (g_serverSocket)
1107     {
1108         OIC_LOG(DEBUG, TAG, "[EDR][Native] Accept Resource will be close");
1109
1110         jclass jni_cid_BTServerSocket = (*env)->FindClass(
1111                 env, "android/bluetooth/BluetoothServerSocket");
1112         if (!jni_cid_BTServerSocket)
1113         {
1114             OIC_LOG(ERROR, TAG, "[EDR][Native] jni_cid_BTServerSocket is null");
1115             return;
1116         }
1117
1118         jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "close", "()V");
1119         if (!jni_mid_accept)
1120         {
1121             OIC_LOG(ERROR, TAG, "[EDR][Native] jni_mid_accept is null");
1122             return;
1123         }
1124         (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_accept);
1125         (*env)->DeleteGlobalRef(env, g_serverSocket);
1126
1127         OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");
1128     }
1129 }
1130