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