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