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