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