Fix Android EDR crash issues.
[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(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     OIC_LOG(DEBUG, TAG, "OUT");
303     return CA_STATUS_OK;
304 }
305
306 CAResult_t CAEDRServerStop()
307 {
308     OIC_LOG(DEBUG, TAG, "IN");
309     CAEDRStopUnicastServer();
310     CAEDRStopMulticastServer();
311
312     ca_mutex_lock(g_mutexAcceptServer);
313     g_stopAccept = true;
314     ca_mutex_unlock(g_mutexAcceptServer);
315
316     if (!g_jvm)
317     {
318         OIC_LOG(DEBUG, TAG, "CAEDRServerStop - g_jvm is null");
319         return CA_STATUS_FAILED;
320     }
321
322     bool isAttached = false;
323     JNIEnv* env;
324     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
325     if (JNI_OK != res)
326     {
327         OIC_LOG(DEBUG, TAG, "CAEDRServerStop - Could not get JNIEnv pointer");
328         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
329
330         if (JNI_OK != res)
331         {
332             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
333             return CA_STATUS_FAILED;
334         }
335         isAttached = true;
336     }
337
338     CAEDRNatvieCloseServerTask(env);
339
340     if (isAttached)
341     {
342         (*g_jvm)->DetachCurrentThread(g_jvm);
343     }
344
345     OIC_LOG(DEBUG, TAG, "OUT");
346     return CA_STATUS_OK;
347 }
348
349 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
350 {
351     g_edrPacketReceivedCallback = packetReceivedCallback;
352 }
353
354 /**
355  * Destroy Mutex.
356  */
357 static void CAEDRServerDestroyMutex()
358 {
359     OIC_LOG(DEBUG, TAG, "IN");
360
361     if (g_mutexUnicastServer)
362     {
363         ca_mutex_free(g_mutexUnicastServer);
364         g_mutexUnicastServer = NULL;
365     }
366
367     if (g_mutexMulticastServer)
368     {
369         ca_mutex_free(g_mutexMulticastServer);
370         g_mutexMulticastServer = NULL;
371     }
372
373     if (g_mutexSocketListManager)
374     {
375         ca_mutex_free(g_mutexSocketListManager);
376         g_mutexSocketListManager = NULL;
377     }
378
379     if (g_mutexAcceptServer)
380     {
381         ca_mutex_free(g_mutexAcceptServer);
382         g_mutexAcceptServer = NULL;
383     }
384
385     if (g_mutexServerSocket)
386     {
387         ca_mutex_free(g_mutexServerSocket);
388         g_mutexServerSocket = NULL;
389     }
390
391     if (g_mutexStateList)
392     {
393         ca_mutex_free(g_mutexStateList);
394         g_mutexStateList = NULL;
395     }
396
397     if (g_mutexObjectList)
398     {
399         ca_mutex_free(g_mutexObjectList);
400         g_mutexObjectList = NULL;
401     }
402
403     if (g_mutexInputStream)
404     {
405         ca_mutex_free(g_mutexInputStream);
406         g_mutexInputStream = NULL;
407     }
408
409     OIC_LOG(DEBUG, TAG, "OUT");
410 }
411
412 /*
413  * Create Mutex
414  */
415 static CAResult_t CAEDRServerCreateMutex()
416 {
417     OIC_LOG(DEBUG, TAG, "IN");
418
419     g_mutexUnicastServer = ca_mutex_new();
420     if (!g_mutexUnicastServer)
421     {
422         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
423         return CA_STATUS_FAILED;
424     }
425
426     g_mutexMulticastServer = ca_mutex_new();
427     if (!g_mutexMulticastServer)
428     {
429         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
430
431         CAEDRServerDestroyMutex();
432         return CA_STATUS_FAILED;
433     }
434
435     g_mutexSocketListManager = ca_mutex_new();
436     if (!g_mutexSocketListManager)
437     {
438         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
439
440         CAEDRServerDestroyMutex();
441         return CA_STATUS_FAILED;
442     }
443
444     g_mutexAcceptServer = ca_mutex_new();
445     if (!g_mutexAcceptServer)
446     {
447         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
448
449         CAEDRServerDestroyMutex();
450         return CA_STATUS_FAILED;
451     }
452
453     g_mutexServerSocket = ca_mutex_new();
454     if (!g_mutexServerSocket)
455     {
456         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
457
458         CAEDRServerDestroyMutex();
459         return CA_STATUS_FAILED;
460     }
461
462     g_mutexStateList = ca_mutex_new();
463     if (!g_mutexStateList)
464     {
465         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
466
467         CAEDRServerDestroyMutex();
468         return CA_STATUS_FAILED;
469     }
470
471     g_mutexObjectList = ca_mutex_new();
472     if (!g_mutexObjectList)
473     {
474         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
475
476         CAEDRServerDestroyMutex();
477         return CA_STATUS_FAILED;
478     }
479
480     g_mutexInputStream = ca_mutex_new();
481     if (!g_mutexInputStream)
482     {
483         OIC_LOG(ERROR, TAG, "Failed to created g_mutexInputStream.");
484
485         CAEDRServerDestroyMutex();
486         return CA_STATUS_FAILED;
487     }
488
489     OIC_LOG(DEBUG, TAG, "OUT");
490     return CA_STATUS_OK;
491 }
492
493 void CAEDRServerJniInit()
494 {
495     OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
496     g_jvm = CANativeJNIGetJavaVM();
497 }
498
499 void CAEDRServerInitialize(ca_thread_pool_t handle)
500 {
501     OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
502
503     g_threadPoolHandle = handle;
504
505     CAEDRServerStartAcceptThread();
506
507     OIC_LOG(DEBUG, TAG, "OUT");
508 }
509
510 void CAEDRServerStartAcceptThread()
511 {
512     CAEDRServerJniInit();
513
514     // init mutex
515     CAEDRServerCreateMutex();
516
517     bool isAttached = false;
518     JNIEnv* env;
519     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
520     if (JNI_OK != res)
521     {
522         OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
523         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
524
525         if (JNI_OK != res)
526         {
527             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
528             return;
529         }
530         isAttached = true;
531     }
532
533     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
534     if (jni_address)
535     {
536         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
537         OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
538         (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
539     }
540
541     ca_mutex_lock(g_mutexStateList);
542     CAEDRNativeCreateDeviceStateList();
543     ca_mutex_unlock(g_mutexStateList);
544
545     ca_mutex_lock(g_mutexObjectList);
546     CAEDRNativeCreateDeviceSocketList();
547     ca_mutex_unlock(g_mutexObjectList);
548
549     if (isAttached)
550     {
551         (*g_jvm)->DetachCurrentThread(g_jvm);
552     }
553
554     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
555             sizeof(CAAdapterReceiveThreadContext_t));
556     if (!ctx)
557     {
558         OIC_LOG(ERROR, TAG, "Out of memory!");
559         return;
560     }
561
562     ctx->stopFlag = &g_stopAccept;
563     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
564     {
565         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
566         OICFree((void *) ctx);
567         return;
568     }
569
570     OIC_LOG(DEBUG, TAG, "OUT");
571 }
572
573 void CAEDRServerTerminate()
574 {
575     OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
576
577     if (!g_jvm)
578     {
579         return;
580     }
581     bool isAttached = false;
582     JNIEnv* env;
583     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
584     if (JNI_OK != res)
585     {
586         OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
587         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
588
589         if (JNI_OK != res)
590         {
591             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
592             return;
593         }
594         isAttached = true;
595     }
596
597     CAEDRNativeSocketCloseToAll(env);
598
599     if (isAttached)
600     {
601         (*g_jvm)->DetachCurrentThread(g_jvm);
602     }
603
604     CAEDRNativeRemoveAllDeviceState();
605     CAEDRNativeRemoveAllDeviceSocket(env);
606
607     // delete mutex
608     CAEDRServerDestroyMutex();
609 }
610
611 CAResult_t CAEDRStartUnicastServer(bool isSecured)
612 {
613     OIC_LOG(DEBUG, TAG, "CAEDRStartUnicastServer");
614
615     ca_mutex_lock(g_mutexUnicastServer);
616
617     /**
618      * The task to listen for data from unicast is added to the thread pool.
619      * This is a blocking call is made where we try to receive some data..
620      * We will keep waiting until some data is received.
621      * This task will be terminated when thread pool is freed on stopping the adapters.
622      * Thread context will be freed by thread on exit.
623      */
624     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
625             sizeof(CAAdapterReceiveThreadContext_t));
626     if (!ctx)
627     {
628         OIC_LOG(ERROR, TAG, "Out of memory!");
629         ca_mutex_unlock(g_mutexUnicastServer);
630         return CA_MEMORY_ALLOC_FAILED;
631     }
632
633     ctx->stopFlag = &g_stopUnicast;
634     ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
635     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
636     {
637         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
638         ca_mutex_unlock(g_mutexUnicastServer);
639         OICFree((void *) ctx);
640         return CA_STATUS_FAILED;
641     }
642     ca_mutex_unlock(g_mutexUnicastServer);
643
644     OIC_LOG(DEBUG, TAG, "OUT");
645     return CA_STATUS_OK;
646 }
647
648 CAResult_t CAEDRStartMulticastServer()
649 {
650     OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
651
652     ca_mutex_lock(g_mutexMulticastServer);
653
654     /**
655      * The task to listen to data from multicast socket is added to the thread pool.
656      * This is a blocking call is made where we try to receive some data.
657      * We will keep waiting until some data is received.
658      * This task will be terminated when thread pool is freed on stopping the adapters.
659      * Thread context will be freed by thread on exit.
660      */
661     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
662             sizeof(CAAdapterReceiveThreadContext_t));
663     if (!ctx)
664     {
665         OIC_LOG(ERROR, TAG, "Out of memory!");
666         ca_mutex_unlock(g_mutexMulticastServer);
667
668         return CA_MEMORY_ALLOC_FAILED;
669     }
670
671     ctx->stopFlag = &g_stopMulticast;
672     ctx->type = CA_MULTICAST_SERVER;
673
674     g_stopMulticast = false;
675     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
676     {
677         OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
678
679         g_stopMulticast = true;
680         ca_mutex_unlock(g_mutexMulticastServer);
681         OICFree((void *) ctx);
682
683         return CA_STATUS_FAILED;
684     }
685     ca_mutex_unlock(g_mutexMulticastServer);
686
687     OIC_LOG(DEBUG, TAG, "OUT");
688     return CA_STATUS_OK;
689 }
690
691 CAResult_t CAEDRStopUnicastServer()
692 {
693     OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
694
695     ca_mutex_lock(g_mutexUnicastServer);
696     g_stopUnicast = true;
697     ca_mutex_unlock(g_mutexUnicastServer);
698
699     return CA_STATUS_OK;
700 }
701
702 CAResult_t CAEDRStopMulticastServer()
703 {
704     OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
705
706     ca_mutex_lock(g_mutexMulticastServer);
707     g_stopMulticast = true;
708     ca_mutex_unlock(g_mutexMulticastServer);
709
710     OIC_LOG(INFO, TAG, "Multicast server stopped");
711
712     return CA_STATUS_OK;
713 }
714
715 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
716 {
717     if (!CAEDRNativeIsEnableBTAdapter(env))
718     {
719         OIC_LOG(ERROR, TAG, "BT adpater is not enable");
720         return CA_STATUS_INVALID_PARAM;
721     }
722
723     if (!((*env)->ExceptionCheck(env)))
724     {
725         // check whether this socket object is connected or not.
726         jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
727         if (!jni_obj_socket)
728         {
729             return CA_STATUS_INVALID_PARAM;
730         }
731
732         jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
733         if (!jni_str_address)
734         {
735             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_str_address is null");
736             return CA_STATUS_FAILED;
737         }
738         const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
739
740         // check it whether is still connected or not through google api
741         jboolean ret = CAEDRIsConnectedForSocket(env, jni_obj_socket);
742         if (!ret)
743         {
744             OIC_LOG(DEBUG, TAG, "[EDR][Native] this device is not connected now.let close socket");
745         }
746
747         // check it whether is still connected or not through socket state list
748         if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
749         {
750             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: it is not connected yet..");
751
752             // remove socket to list
753             // this code is related to below read fail exception code
754             CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
755             (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
756
757             (*env)->DeleteLocalRef(env, jni_str_address);
758
759             return CA_STATUS_FAILED;
760         }
761
762         // start to read through InputStream
763         jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
764         if (!jni_cid_BTsocket)
765         {
766             (*env)->DeleteLocalRef(env, jni_str_address);
767
768             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_BTsocket is null");
769             return CA_STATUS_FAILED;
770         }
771         jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env, jni_cid_BTsocket,
772                                                                "getInputStream",
773                                                                "()Ljava/io/InputStream;");
774         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData:  get InputStream..%d, %s", id, address);
775
776         if (!jni_obj_socket)
777         {
778             (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
779             (*env)->DeleteLocalRef(env, jni_str_address);
780
781             OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
782             return CA_STATUS_FAILED;
783         }
784
785         jobject jni_obj_inputStream = (*env)->CallObjectMethod(env, jni_obj_socket,
786                                                                jni_mid_getInputStream);
787         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData:  ready inputStream..");
788
789         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
790         if (!jni_cid_InputStream)
791         {
792             (*env)->DeleteLocalRef(env, jni_obj_inputStream);
793             (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
794             (*env)->DeleteLocalRef(env, jni_str_address);
795
796             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: jni_cid_InputStream is null");
797             return CA_STATUS_FAILED;
798         }
799         jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
800
801         jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
802
803         if (!jni_obj_socket)
804         {
805             (*env)->DeleteLocalRef(env, jni_cid_InputStream);
806             (*env)->DeleteLocalRef(env, jni_obj_inputStream);
807             (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
808             (*env)->DeleteLocalRef(env, jni_str_address);
809
810             OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
811             return CA_STATUS_FAILED;
812         }
813
814         ca_mutex_lock(g_mutexInputStream);
815         if (!g_inputStream)
816         {
817             g_inputStream = (*env)->NewGlobalRef(env, jni_obj_inputStream);
818         }
819
820         jint length = (*env)->CallIntMethod(env, g_inputStream, jni_mid_read, jbuf, (jint) 0,
821                                             MAX_PDU_BUFFER);
822         ca_mutex_unlock(g_mutexInputStream);
823
824         OIC_LOG(DEBUG, TAG, "[EDR][Native] read something from InputStream");
825
826         if (-1 == length)
827         {
828             (*env)->DeleteLocalRef(env, jni_cid_InputStream);
829             (*env)->DeleteLocalRef(env, jbuf);
830             (*env)->DeleteLocalRef(env, jni_obj_inputStream);
831             (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
832             (*env)->DeleteLocalRef(env, jni_str_address);
833
834             OIC_LOG(ERROR, TAG, "[EDR][Native] read buffer is empty...");
835             return CA_STATUS_FAILED;
836         }
837
838         if ((*env)->ExceptionCheck(env))
839         {
840             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
841             (*env)->ExceptionDescribe(env);
842             (*env)->ExceptionClear(env);
843
844             // update state to disconnect
845             // the socket will be close next read thread routine
846             ca_mutex_lock(g_mutexStateList);
847             CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
848             ca_mutex_unlock(g_mutexStateList);
849             (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
850
851             (*env)->DeleteLocalRef(env, jbuf);
852             (*env)->DeleteLocalRef(env, jni_cid_InputStream);
853             (*env)->DeleteLocalRef(env, jni_obj_inputStream);
854             (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
855             (*env)->DeleteLocalRef(env, jni_str_address);
856
857             return CA_STATUS_FAILED;
858         }
859
860         OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
861         jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
862         if (NULL == buf)
863         {
864             (*env)->DeleteLocalRef(env, jni_cid_InputStream);
865             (*env)->DeleteLocalRef(env, jbuf);
866             (*env)->DeleteLocalRef(env, jni_obj_inputStream);
867             (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
868             (*env)->DeleteLocalRef(env, jni_str_address);
869
870             OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: buf is null");
871             return CA_STATUS_FAILED;
872         }
873
874         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s, %d", buf, length);
875
876         char responseData[MAX_PDU_BUFFER] = { 0 };
877         memcpy(responseData, (const char*) buf, length);
878
879         switch (type)
880         {
881             case CA_UNICAST_SERVER:
882             case CA_MULTICAST_SERVER:
883                 // Notify data to upper layer
884                 if (g_edrPacketReceivedCallback)
885                 {
886                     uint32_t sentLength = 0;
887                     OIC_LOG_V(DEBUG, TAG,"[EDR][Native] data will be sent to callback routine: \
888                               %s, %d", responseData, length);
889                     g_edrPacketReceivedCallback(address, (void*) responseData, length, &sentLength);
890                 }
891                 break;
892
893             default:
894                 // Should never occur
895                 OIC_LOG(ERROR, TAG, "Invalid server type");
896                 return CA_STATUS_FAILED;
897         }
898         (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
899         (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
900
901         (*env)->DeleteLocalRef(env, jni_cid_InputStream);
902         (*env)->DeleteLocalRef(env, jbuf);
903         (*env)->DeleteLocalRef(env, jni_obj_inputStream);
904         (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
905         (*env)->DeleteLocalRef(env, jni_str_address);
906     }
907     else
908     {
909         (*env)->ExceptionDescribe(env);
910         (*env)->ExceptionClear(env);
911         OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: env error!!");
912         return CA_STATUS_FAILED;
913     }
914
915     return CA_STATUS_OK;
916 }
917
918 jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket)
919 {
920     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRIsConnectedForSocket...");
921
922     if (!CAEDRNativeIsEnableBTAdapter(env))
923     {
924         OIC_LOG(ERROR, TAG, "BT adpater is not enable");
925         return JNI_FALSE;
926     }
927
928     if (!socket)
929     {
930         OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - socket is null");
931         return JNI_FALSE;
932     }
933
934     jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
935     if (!jni_cid_BTsocket)
936     {
937         OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket - jni_cid_BTsocket is null");
938         return JNI_FALSE;
939     }
940
941     jmethodID jni_mid_isConnected = (*env)->GetMethodID(env, jni_cid_BTsocket, "isConnected",
942                                                         "()Z");
943     if (!jni_mid_isConnected)
944     {
945         (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
946
947         OIC_LOG(ERROR, TAG, "[EDR][Native] CAEDRIsConnectedForSocket \
948                 - jni_mid_isConnected is null.");
949         return JNI_FALSE;
950     }
951
952     jboolean jni_isConnected = (*env)->CallBooleanMethod(env, socket, jni_mid_isConnected);
953
954     (*env)->DeleteLocalRef(env, jni_cid_BTsocket);
955
956     return jni_isConnected;
957 }
958
959 void CANativeStartListenTask(JNIEnv *env)
960 {
961     jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
962     if (!jni_obj_BTServerSocket)
963     {
964         OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTServerSocket is null");
965         return;
966     }
967
968     ca_mutex_lock(g_mutexServerSocket);
969     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
970     ca_mutex_unlock(g_mutexServerSocket);
971 }
972
973 jobject CAEDRNativeListen(JNIEnv *env)
974 {
975     if (!CAEDRNativeIsEnableBTAdapter(env))
976     {
977         OIC_LOG(ERROR, TAG, "BT adpater is not enable");
978         return NULL;
979     }
980
981     OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
982
983     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
984     if (!jni_cid_BTAdapter)
985     {
986         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
987         return NULL;
988     }
989
990     // get BTadpater
991     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
992                                                                     "getDefaultAdapter",
993                                                                     METHODID_OBJECTNONPARAM);
994     if (!jni_cid_BTAdapter)
995     {
996         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
997         return NULL;
998     }
999
1000     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1001                                                                jni_mid_getDefaultAdapter);
1002     if (!jni_obj_BTAdapter)
1003     {
1004         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
1005         return NULL;
1006     }
1007
1008     // get listen method ID
1009     jmethodID jni_mid_listen = (*env)->GetMethodID(
1010             env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
1011             "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
1012     if (!jni_mid_listen)
1013     {
1014         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1015         return NULL;
1016     }
1017     // listenUsingInsecureRfcommWithServiceRecord  / listenUsingRfcommWithServiceRecord
1018     // setting UUID
1019     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1020     if (!jni_cid_uuid)
1021     {
1022         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
1023         return NULL;
1024     }
1025
1026     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
1027             env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
1028     if (!jni_mid_fromString)
1029     {
1030         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
1031         return NULL;
1032     }
1033
1034     jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
1035     if (!jni_uuid)
1036     {
1037         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_uuid is null");
1038         return NULL;
1039     }
1040     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1041                                                           jni_uuid);
1042     if (!jni_obj_uuid)
1043     {
1044         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
1045         return NULL;
1046     }
1047
1048     // create socket
1049     jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
1050     if (!jni_name)
1051     {
1052         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
1053         return NULL;
1054     }
1055     jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
1056                                                              jni_name, jni_obj_uuid);
1057     if (!jni_obj_BTServerSocket)
1058     {
1059         OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTServerSocket is null");
1060         return NULL;
1061     }
1062
1063     g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
1064
1065     return jni_obj_BTServerSocket;
1066 }
1067
1068 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
1069 {
1070     if (NULL != serverSocketObject)
1071     {
1072         jclass jni_cid_BTServerSocket = (*env)->FindClass(
1073                 env, "android/bluetooth/BluetoothServerSocket");
1074         if (!jni_cid_BTServerSocket)
1075         {
1076             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
1077             return;
1078         }
1079
1080         jmethodID jni_mid_accept = (*env)->GetMethodID(env, jni_cid_BTServerSocket, "accept",
1081                                                        "()Landroid/bluetooth/BluetoothSocket;");
1082         if (!jni_mid_accept)
1083         {
1084             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
1085             return;
1086         }
1087
1088         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
1089
1090         jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
1091                                                             jni_mid_accept);
1092         if (!jni_obj_BTSocket)
1093         {
1094             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
1095
1096             if ((*env)->ExceptionCheck(env))
1097             {
1098                 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: socket might closed or timeout!!!");
1099                 (*env)->ExceptionDescribe(env);
1100                 (*env)->ExceptionClear(env);
1101                 return;
1102             }
1103         }
1104
1105         // get remote address
1106         jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
1107         if (!j_str_address)
1108         {
1109             OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: j_str_address is null");
1110             return;
1111         }
1112
1113         const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
1114         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
1115
1116         // set socket to list
1117         jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
1118         ca_mutex_lock(g_mutexObjectList);
1119         CAEDRNativeAddDeviceSocketToList(env, jni_socket);
1120         ca_mutex_unlock(g_mutexObjectList);
1121
1122         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
1123
1124         // update state
1125         ca_mutex_lock(g_mutexStateList);
1126         CAEDRUpdateDeviceState(STATE_CONNECTED, address);
1127         ca_mutex_unlock(g_mutexStateList);
1128         (*env)->ReleaseStringUTFChars(env, j_str_address, address);
1129     }
1130     else
1131     {
1132         OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: serverSocket is close previously");
1133     }
1134 }
1135
1136 /**
1137  * InputStream & BluetoothServerSocket will be close for Terminating.
1138  */
1139 void CAEDRNatvieCloseServerTask(JNIEnv* env)
1140 {
1141     if (g_inputStream)
1142     {
1143         OIC_LOG(DEBUG, TAG, "InputStream will be close");
1144         jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
1145         jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_InputStream, "close", "()V");
1146         (*env)->CallVoidMethod(env, g_inputStream, jni_mid_close);
1147         (*env)->DeleteGlobalRef(env, g_inputStream);
1148         g_inputStream = NULL;
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         g_serverSocket = NULL;
1172
1173         OIC_LOG(DEBUG, TAG, "[EDR][Native] close accept obj");
1174     }
1175 }
1176