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