Changed to be used only once to create input stream.
[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 TAG PCF("OIC_CA_EDR_SERVER")
38
39 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
40 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
41 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
42 static const char CLASSPATH_BT_SERVER_SOCKET[] = "android/bluetooth/BluetoothServerSocket";
43
44 static ca_thread_pool_t g_threadPoolHandle = NULL;
45
46 static JavaVM *g_jvm;
47
48 /**
49  * Maximum CoAP over TCP header length
50  * to know the total data length.
51  */
52 #define EDR_MAX_HEADER_LEN  6
53
54 /**
55  * Mutex to synchronize receive server.
56  */
57 static ca_mutex g_mutexReceiveServer = NULL;
58
59 /**
60  * Flag to control the Receive Unicast Data Thread.
61  */
62 static bool g_stopUnicast = false;
63
64 /**
65  * Mutex to synchronize accept server.
66  */
67 static ca_mutex g_mutexAcceptServer = NULL;
68
69 /**
70  * Flag to control the Accept Thread.
71  */
72 static bool g_stopAccept = false;
73
74 /**
75  * Mutex to synchronize server socket.
76  */
77 static ca_mutex g_mutexServerSocket = NULL;
78
79 /**
80  * Flag to control the server socket.
81  */
82 static jobject g_serverSocket = NULL;
83
84 /**
85  * Mutex to synchronize device state list.
86  */
87 static ca_mutex g_mutexStateList = NULL;
88
89 /**
90  * Mutex to synchronize device object list.
91  */
92 static ca_mutex g_mutexObjectList = NULL;
93
94 /**
95  * Thread context information for unicast, multicast and secured unicast server.
96  */
97 typedef struct
98 {
99     bool *stopFlag;
100     CAAdapterServerType_t type;
101 } CAAdapterReceiveThreadContext_t;
102
103 typedef struct
104 {
105     bool *stopFlag;
106 } CAAdapterAcceptThreadContext_t;
107
108 /**
109  * Maintains the callback to be notified when data received from remote
110  * Bluetooth device.
111  */
112 static CAEDRDataReceivedCallback g_edrPacketReceivedCallback = NULL;
113
114 static void CAReceiveHandler(void *data)
115 {
116     OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler..");
117     // Input validation
118     VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
119
120     bool isAttached = false;
121     JNIEnv* env;
122     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
123     if (JNI_OK != res)
124     {
125         OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
126         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
127
128         if (JNI_OK != res)
129         {
130             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
131             return;
132         }
133         isAttached = true;
134     }
135
136     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data;
137
138     while (true != *(ctx->stopFlag))
139     {
140         if (!CAEDRNativeIsEnableBTAdapter(env))
141         {
142             OIC_LOG(INFO, TAG, "BT adapter is not enabled");
143             break;
144         }
145
146         // if new socket object is added in socket list after below logic is ran.
147         // new socket will be started to read after next while loop
148         uint32_t length = CAEDRGetSocketListLength();
149         if (0 != length)
150         {
151             for (uint32_t idx = 0; idx < length; idx++)
152             {
153                 CAEDRNativeReadData(env, idx);
154             }
155         }
156     }
157
158     if (isAttached)
159     {
160         (*g_jvm)->DetachCurrentThread(g_jvm);
161     }
162
163     OICFree(ctx);
164
165     OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
166 }
167
168 static void CAAcceptHandler(void *data)
169 {
170     OIC_LOG(DEBUG, TAG, "AcceptThread start");
171
172     VERIFY_NON_NULL_VOID(data, TAG, "data is null");
173
174     bool isAttached = false;
175     JNIEnv* env;
176     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
177     if (JNI_OK != res)
178     {
179         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
180         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
181
182         if (JNI_OK != res)
183         {
184             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
185             return;
186         }
187         isAttached = true;
188     }
189
190     jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
191     if (!jni_obj_BTServerSocket)
192     {
193         OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
194
195         if (isAttached)
196         {
197             (*g_jvm)->DetachCurrentThread(g_jvm);
198         }
199
200         return;
201     }
202
203     ca_mutex_lock(g_mutexServerSocket);
204     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
205     ca_mutex_unlock(g_mutexServerSocket);
206
207     CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
208
209     // it should be initialized for restart accept thread
210     ca_mutex_lock(g_mutexAcceptServer);
211     g_stopAccept = false;
212     ca_mutex_unlock(g_mutexAcceptServer);
213
214     while (true != *(ctx->stopFlag))
215     {
216         // when BT state is changed with Off. its thread will be stopped
217         if (!CAEDRNativeIsEnableBTAdapter(env))
218         {
219             OIC_LOG(INFO, TAG, "BT adapter is not enabled");
220             ca_mutex_lock(g_mutexAcceptServer);
221             g_stopAccept = true;
222             ca_mutex_unlock(g_mutexAcceptServer);
223             ca_mutex_lock(g_mutexServerSocket);
224             g_serverSocket = NULL;
225             ca_mutex_unlock(g_mutexServerSocket);
226         }
227         else
228         {
229             CAEDRNativeAccept(env, g_serverSocket);
230         }
231     }
232
233     if (isAttached)
234     {
235         (*g_jvm)->DetachCurrentThread(g_jvm);
236     }
237
238     OICFree(ctx);
239
240     OIC_LOG(DEBUG, TAG, "AcceptThread finish");
241
242     return;
243 }
244
245 /**
246  * implement for adapter common method.
247  */
248 CAResult_t CAEDRServerStart()
249 {
250     if (!g_threadPoolHandle)
251     {
252         return CA_STATUS_NOT_INITIALIZED;
253     }
254
255     CAResult_t res = CAEDRServerStartAcceptThread();
256     if (CA_STATUS_OK == res)
257     {
258         res = CAEDRStartReceiveThread(false);
259         if (CA_STATUS_OK != res)
260         {
261             OIC_LOG(ERROR, TAG, "failed to start receive thread");
262             CAEDRServerStop();
263             return CA_STATUS_FAILED;
264         }
265     }
266
267     return res;
268 }
269
270 CAResult_t CAEDRServerStop()
271 {
272     CAEDRStopReceiveThread();
273
274     ca_mutex_lock(g_mutexAcceptServer);
275     g_stopAccept = true;
276     ca_mutex_unlock(g_mutexAcceptServer);
277
278     if (!g_jvm)
279     {
280         OIC_LOG(DEBUG, TAG, "g_jvm is null");
281         return CA_STATUS_FAILED;
282     }
283
284     bool isAttached = false;
285     JNIEnv* env;
286     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
287     if (JNI_OK != res)
288     {
289         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
290         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
291
292         if (JNI_OK != res)
293         {
294             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
295             return CA_STATUS_FAILED;
296         }
297         isAttached = true;
298     }
299
300     CAEDRNatvieCloseServerTask(env);
301
302     if (isAttached)
303     {
304         (*g_jvm)->DetachCurrentThread(g_jvm);
305     }
306
307     return CA_STATUS_OK;
308 }
309
310 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
311 {
312     g_edrPacketReceivedCallback = packetReceivedCallback;
313 }
314
315 static void CAEDRServerDestroyMutex()
316 {
317     if (g_mutexReceiveServer)
318     {
319         ca_mutex_free(g_mutexReceiveServer);
320         g_mutexReceiveServer = NULL;
321     }
322
323     if (g_mutexAcceptServer)
324     {
325         ca_mutex_free(g_mutexAcceptServer);
326         g_mutexAcceptServer = NULL;
327     }
328
329     if (g_mutexServerSocket)
330     {
331         ca_mutex_free(g_mutexServerSocket);
332         g_mutexServerSocket = NULL;
333     }
334
335     if (g_mutexStateList)
336     {
337         ca_mutex_free(g_mutexStateList);
338         g_mutexStateList = NULL;
339     }
340
341     if (g_mutexObjectList)
342     {
343         ca_mutex_free(g_mutexObjectList);
344         g_mutexObjectList = NULL;
345     }
346 }
347
348 static CAResult_t CAEDRServerCreateMutex()
349 {
350     g_mutexReceiveServer = ca_mutex_new();
351     if (!g_mutexReceiveServer)
352     {
353         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
354         return CA_STATUS_FAILED;
355     }
356
357     g_mutexAcceptServer = ca_mutex_new();
358     if (!g_mutexAcceptServer)
359     {
360         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
361
362         CAEDRServerDestroyMutex();
363         return CA_STATUS_FAILED;
364     }
365
366     g_mutexServerSocket = ca_mutex_new();
367     if (!g_mutexServerSocket)
368     {
369         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
370
371         CAEDRServerDestroyMutex();
372         return CA_STATUS_FAILED;
373     }
374
375     g_mutexStateList = ca_mutex_new();
376     if (!g_mutexStateList)
377     {
378         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
379
380         CAEDRServerDestroyMutex();
381         return CA_STATUS_FAILED;
382     }
383
384     g_mutexObjectList = ca_mutex_new();
385     if (!g_mutexObjectList)
386     {
387         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
388
389         CAEDRServerDestroyMutex();
390         return CA_STATUS_FAILED;
391     }
392
393     return CA_STATUS_OK;
394 }
395
396 void CAEDRServerJniInit()
397 {
398     OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
399     g_jvm = CANativeJNIGetJavaVM();
400 }
401
402 CAResult_t CAEDRServerInitialize(ca_thread_pool_t handle)
403 {
404     OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
405     VERIFY_NON_NULL(handle, TAG, "handle is NULL");
406
407     g_threadPoolHandle = handle;
408     CAEDRServerJniInit();
409
410     return CAEDRServerCreateMutex();
411 }
412
413 CAResult_t CAEDRServerStartAcceptThread()
414 {
415     bool isAttached = false;
416     JNIEnv* env;
417     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
418     if (JNI_OK != res)
419     {
420         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
421         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
422
423         if (JNI_OK != res)
424         {
425             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
426             return CA_STATUS_FAILED;
427         }
428         isAttached = true;
429     }
430
431     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
432     if (jni_address)
433     {
434         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
435         OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
436         (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
437     }
438
439     ca_mutex_lock(g_mutexStateList);
440     CAEDRNativeCreateDeviceStateList();
441     ca_mutex_unlock(g_mutexStateList);
442
443     ca_mutex_lock(g_mutexObjectList);
444     CAEDRNativeCreateDeviceSocketList();
445     ca_mutex_unlock(g_mutexObjectList);
446
447     if (isAttached)
448     {
449         (*g_jvm)->DetachCurrentThread(g_jvm);
450     }
451
452     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
453             sizeof(CAAdapterReceiveThreadContext_t));
454     if (!ctx)
455     {
456         OIC_LOG(ERROR, TAG, "Out of memory!");
457         return CA_MEMORY_ALLOC_FAILED;
458     }
459
460     ctx->stopFlag = &g_stopAccept;
461     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
462     {
463         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
464         OICFree((void *) ctx);
465         return CA_STATUS_FAILED;
466     }
467
468     return CA_STATUS_OK;
469 }
470
471 void CAEDRServerTerminate()
472 {
473     OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
474
475     if (!g_jvm)
476     {
477         return;
478     }
479     bool isAttached = false;
480     JNIEnv* env;
481     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
482     if (JNI_OK != res)
483     {
484         OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer");
485         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
486
487         if (JNI_OK != res)
488         {
489             OIC_LOG(ERROR, TAG, "AttachCurrentThread failed");
490             return;
491         }
492         isAttached = true;
493     }
494
495     CAEDRNativeSocketCloseToAll(env);
496
497     if (isAttached)
498     {
499         (*g_jvm)->DetachCurrentThread(g_jvm);
500     }
501
502     CAEDRNativeRemoveAllDeviceState();
503     CAEDRNativeRemoveAllDeviceSocket(env);
504
505     // delete mutex
506     CAEDRServerDestroyMutex();
507 }
508
509 CAResult_t CAEDRStartReceiveThread(bool isSecured)
510 {
511     OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
512
513     ca_mutex_lock(g_mutexReceiveServer);
514
515     /**
516      * The task to listen for data from unicast is added to the thread pool.
517      * This is a blocking call is made where we try to receive some data..
518      * We will keep waiting until some data is received.
519      * This task will be terminated when thread pool is freed on stopping the adapters.
520      * Thread context will be freed by thread on exit.
521      */
522     CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) OICMalloc(
523             sizeof(CAAdapterReceiveThreadContext_t));
524     if (!ctx)
525     {
526         OIC_LOG(ERROR, TAG, "Out of memory!");
527         ca_mutex_unlock(g_mutexReceiveServer);
528         return CA_MEMORY_ALLOC_FAILED;
529     }
530
531     g_stopUnicast = false;
532     ctx->stopFlag = &g_stopUnicast;
533     ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
534     if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
535     {
536         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
537         ca_mutex_unlock(g_mutexReceiveServer);
538         OICFree((void *) ctx);
539         return CA_STATUS_FAILED;
540     }
541     ca_mutex_unlock(g_mutexReceiveServer);
542
543     OIC_LOG(DEBUG, TAG, "OUT");
544     return CA_STATUS_OK;
545 }
546
547 CAResult_t CAEDRStopReceiveThread()
548 {
549     OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
550
551     ca_mutex_lock(g_mutexReceiveServer);
552     g_stopUnicast = true;
553     ca_mutex_unlock(g_mutexReceiveServer);
554
555     return CA_STATUS_OK;
556 }
557
558 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id)
559 {
560     if ((*env)->ExceptionCheck(env))
561     {
562         (*env)->ExceptionDescribe(env);
563         (*env)->ExceptionClear(env);
564         OIC_LOG(ERROR, TAG, "env error!!");
565         return CA_STATUS_FAILED;
566     }
567
568     jobject jni_obj_inputStream = CAEDRNativeGetInputStream(id);
569     if (!jni_obj_inputStream)
570     {
571         OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
572         return CA_STATUS_FAILED;
573     }
574
575     jmethodID jni_mid_available = CAGetJNIMethodID(env, "java/io/InputStream", "available", "()I");
576     if (!jni_mid_available)
577     {
578         OIC_LOG(ERROR, TAG, "jni_mid_available is null");
579         return CA_STATUS_FAILED;
580     }
581
582     jint available = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_available);
583
584     if (0 < available)
585     {
586         jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
587         if (!jni_obj_socket)
588         {
589             OIC_LOG(ERROR, TAG, "jni_obj_socket is null");
590             return CA_STATUS_FAILED;
591         }
592         jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
593         if (!jni_str_address)
594         {
595             OIC_LOG(ERROR, TAG, "jni_str_address is null");
596             return CA_STATUS_FAILED;
597         }
598
599         const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
600         if (!address)
601         {
602             OIC_LOG(ERROR, TAG, "address is null");
603             (*env)->DeleteLocalRef(env, jni_str_address);
604             return CA_STATUS_FAILED;
605         }
606
607         OIC_LOG_V(DEBUG, TAG, "get InputStream..%d, %s", id, address);
608         jmethodID jni_mid_read = CAGetJNIMethodID(env, "java/io/InputStream", "read", "([BII)I");
609         if (!jni_mid_read)
610         {
611             OIC_LOG(ERROR, TAG, "jni_mid_read is null");
612             (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
613             (*env)->DeleteLocalRef(env, jni_str_address);
614             return CA_STATUS_FAILED;
615         }
616
617         CAConnectedDeviceInfo_t *deviceInfo =
618                 (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(address);
619
620         (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
621         (*env)->DeleteLocalRef(env, jni_str_address);
622         if (!deviceInfo)
623         {
624             OIC_LOG(ERROR, TAG, "failed to get device info from list");
625             return CA_STATUS_FAILED;
626         }
627
628         jint bufSize = (deviceInfo->totalDataLen == 0) ?
629                 EDR_MAX_HEADER_LEN : deviceInfo->totalDataLen;
630         if (!deviceInfo->recvData)
631         {
632             deviceInfo->recvData = OICCalloc(1, bufSize);
633             if (!deviceInfo->recvData)
634             {
635                 OIC_LOG(ERROR, TAG, "out of memory");
636                 return CA_STATUS_FAILED;
637             }
638         }
639
640         jint remainSize = (jint) bufSize - deviceInfo->recvDataLen;
641         if (0 >= remainSize)
642         {
643             OIC_LOG(ERROR, TAG, "remainSize value is invalid.");
644             return CA_STATUS_FAILED;
645         }
646         jbyteArray jbuf = (*env)->NewByteArray(env, remainSize);
647         if (!jbuf)
648         {
649             OIC_LOG(ERROR, TAG, "jbuf is null");
650             return CA_STATUS_FAILED;
651         }
652
653         jint recvLen = (*env)->CallIntMethod(env, jni_obj_inputStream, jni_mid_read,
654                                              jbuf, (jint) 0, remainSize);
655         if (-1 == recvLen)
656         {
657             OIC_LOG(ERROR, TAG, "recvLen is -1");
658             (*env)->DeleteLocalRef(env, jbuf);
659             return CA_STATUS_FAILED;
660         }
661
662         jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
663         if (!buf)
664         {
665             OIC_LOG(ERROR, TAG, "buf is null");
666             (*env)->DeleteLocalRef(env, jbuf);
667             return CA_STATUS_FAILED;
668         }
669         memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*) buf, recvLen);
670         deviceInfo->recvDataLen += recvLen;
671
672         (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
673         (*env)->DeleteLocalRef(env, jbuf);
674
675         OIC_LOG(DEBUG, TAG, "read something from InputStream");
676
677         if (!deviceInfo->totalDataLen)
678         {
679             coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
680                     ((unsigned char *) deviceInfo->recvData)[0] >> 4);
681             size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
682             if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
683             {
684                 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
685                                                                          deviceInfo->recvDataLen);
686                 OIC_LOG_V(DEBUG, TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
687
688                 uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
689                 if (!newBuf)
690                 {
691                     OIC_LOG(ERROR, TAG, "out of memory");
692                     return CA_STATUS_FAILED;
693                 }
694                 deviceInfo->recvData = newBuf;
695             }
696         }
697
698         if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
699         {
700             if ((*env)->ExceptionCheck(env))
701             {
702                 OIC_LOG(ERROR, TAG, "read Error!!!");
703                 (*env)->ExceptionDescribe(env);
704                 (*env)->ExceptionClear(env);
705
706                 // update state to disconnect
707                 // the socket will be close next read thread routine
708                 ca_mutex_lock(g_mutexStateList);
709                 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
710                 ca_mutex_unlock(g_mutexStateList);
711
712                 return CA_STATUS_FAILED;
713             }
714
715             if (g_edrPacketReceivedCallback)
716             {
717                 OIC_LOG_V(DEBUG, TAG,"data will be sent to callback routine: \
718                           %s, %d", deviceInfo->recvData, deviceInfo->recvDataLen);
719
720                 uint32_t sentLength = 0;
721                 g_edrPacketReceivedCallback(address, (void*) deviceInfo->recvData,
722                                             deviceInfo->recvDataLen, &sentLength);
723
724                 OICFree(deviceInfo->recvData);
725                 deviceInfo->recvData = NULL;
726                 deviceInfo->recvDataLen = 0;
727                 deviceInfo->totalDataLen = 0;
728             }
729         }
730     }
731
732     return CA_STATUS_OK;
733 }
734
735 void CANativeStartListenTask(JNIEnv *env)
736 {
737     jobject jni_obj_BTServerSocket = CAEDRNativeListen(env);
738     if (!jni_obj_BTServerSocket)
739     {
740         OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
741         return;
742     }
743
744     ca_mutex_lock(g_mutexServerSocket);
745     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
746     ca_mutex_unlock(g_mutexServerSocket);
747 }
748
749 jobject CAEDRNativeListen(JNIEnv *env)
750 {
751     OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - IN");
752
753     if (!CAEDRNativeIsEnableBTAdapter(env))
754     {
755         OIC_LOG(INFO, TAG, "BT adapter is not enabled");
756         return NULL;
757     }
758
759     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
760     if (!jni_cid_BTAdapter)
761     {
762         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
763         return NULL;
764     }
765
766     // get BTadpater
767     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
768                                                                     "getDefaultAdapter",
769                                                                     METHODID_OBJECTNONPARAM);
770     if (!jni_mid_getDefaultAdapter)
771     {
772         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
773         return NULL;
774     }
775
776     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
777                                                                jni_mid_getDefaultAdapter);
778     if (!jni_obj_BTAdapter)
779     {
780         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
781         return NULL;
782     }
783
784     // get listen method ID
785     jmethodID jni_mid_listen = (*env)->GetMethodID(
786             env, jni_cid_BTAdapter, "listenUsingInsecureRfcommWithServiceRecord",
787             "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
788     if (!jni_mid_listen)
789     {
790         OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
791         return NULL;
792     }
793     // listenUsingInsecureRfcommWithServiceRecord  / listenUsingRfcommWithServiceRecord
794     // setting UUID
795     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
796     if (!jni_cid_uuid)
797     {
798         OIC_LOG(ERROR, TAG, "jni_mid_listen is null");
799         return NULL;
800     }
801
802     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(
803             env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
804     if (!jni_mid_fromString)
805     {
806         OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
807         return NULL;
808     }
809
810     jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID);
811     if (!jni_uuid)
812     {
813         OIC_LOG(ERROR, TAG, "jni_uuid is null");
814         return NULL;
815     }
816     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
817                                                           jni_uuid);
818     if (!jni_obj_uuid)
819     {
820         OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
821         return NULL;
822     }
823
824     // create socket
825     jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
826     if (!jni_name)
827     {
828         OIC_LOG(ERROR, TAG, "jni_name is null");
829         return NULL;
830     }
831     jobject jni_obj_BTServerSocket = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_listen,
832                                                              jni_name, jni_obj_uuid);
833     if (!jni_obj_BTServerSocket)
834     {
835         OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null");
836         return NULL;
837     }
838
839     OIC_LOG(DEBUG, TAG, "CAEDRNativeListen - OUT");
840
841     return jni_obj_BTServerSocket;
842 }
843
844 void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
845 {
846     OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - IN");
847
848     if (NULL != serverSocketObject)
849     {
850         jmethodID jni_mid_accept = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
851                                                     "accept",
852                                                     "()Landroid/bluetooth/BluetoothSocket;");
853         if (!jni_mid_accept)
854         {
855             OIC_LOG(ERROR, TAG, "jni_mid_accept is null");
856             return;
857         }
858
859         OIC_LOG(DEBUG, TAG, "waiting for the new connection request...");
860
861         jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, serverSocketObject,
862                                                             jni_mid_accept);
863         if (!jni_obj_BTSocket)
864         {
865             OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null");
866
867             if ((*env)->ExceptionCheck(env))
868             {
869                 OIC_LOG(ERROR, TAG, "socket might closed or timeout!!!");
870                 (*env)->ExceptionDescribe(env);
871                 (*env)->ExceptionClear(env);
872                 return;
873             }
874         }
875
876         // get remote address
877         jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
878         if (!j_str_address)
879         {
880             OIC_LOG(ERROR, TAG, "j_str_address is null");
881             return;
882         }
883
884         const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
885         OIC_LOG_V(DEBUG, TAG, "received the connection request from [%s]", address);
886
887         // set socket to list
888         jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
889         if (!jni_socket)
890         {
891             OIC_LOG(ERROR, TAG, "jni_socket is null");
892             (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
893             return;
894         }
895         ca_mutex_lock(g_mutexObjectList);
896         CAEDRNativeAddDeviceSocketToList(env, jni_socket);
897         (*env)->DeleteGlobalRef(env, jni_socket);
898         (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
899         ca_mutex_unlock(g_mutexObjectList);
900
901         // update state
902         ca_mutex_lock(g_mutexStateList);
903         CAEDRUpdateDeviceState(STATE_CONNECTED, address);
904         ca_mutex_unlock(g_mutexStateList);
905
906         (*env)->ReleaseStringUTFChars(env, j_str_address, address);
907         (*env)->DeleteLocalRef(env, j_str_address);
908
909         OIC_LOG_V(DEBUG, TAG, "connected with [%s]", address);
910     }
911     else
912     {
913         OIC_LOG(DEBUG, TAG, "serverSocket is close previously");
914     }
915
916     OIC_LOG(DEBUG, TAG, "CAEDRNativeAccept - OUT");
917 }
918
919 /**
920  * InputStream & BluetoothServerSocket will be close for Terminating.
921  */
922 void CAEDRNatvieCloseServerTask(JNIEnv* env)
923 {
924     if (g_serverSocket)
925     {
926         OIC_LOG(DEBUG, TAG, "Accept Resource will be close");
927
928         jmethodID jni_mid_close = CAGetJNIMethodID(env, CLASSPATH_BT_SERVER_SOCKET,
929                                                    "close", "()V");
930         if (!jni_mid_close)
931         {
932             OIC_LOG(ERROR, TAG, "jni_mid_close is null");
933             return;
934         }
935
936         (*env)->CallVoidMethod(env, g_serverSocket, jni_mid_close);
937         (*env)->DeleteGlobalRef(env, g_serverSocket);
938         g_serverSocket = NULL;
939
940         OIC_LOG(DEBUG, TAG, "close accept obj");
941     }
942 }