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