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