Fixed prevent and klock work issues reported.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / android / caedrclient.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <jni.h>
4
5 #include "caedrinterface.h"
6 #include "caedrutils.h"
7 #include "caedrclient.h"
8 #include "caleserver.h"
9 #include "logger.h"
10 #include "oic_malloc.h"
11 #include "uthreadpool.h" /* for thread pool */
12 #include "umutex.h"
13 #include "caadapterutils.h"
14 #include "com_iotivity_jar_CAEDRInterface.h"
15
16 //#define DEBUG_MODE
17 #define TAG PCF("CA_EDR_CLIENT")
18
19 static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
20 static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;";
21 static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter";
22 static const char *CLASSPATH_BT_UUID = "java/util/UUID";
23
24 static const uint32_t STATE_CONNECTED = 1;
25 static const uint32_t STATE_DISCONNECTED = 0;
26
27 static u_thread_pool_t gThreadPoolHandle = NULL;
28
29 static JavaVM *g_jvm;
30 static jobject gContext;
31
32 // server socket instance
33 static jobject gServerSocketObject = NULL;
34
35 /**
36  * @var gMutexUnicastServer
37  * @brief Mutex to synchronize unicast server
38  */
39 static u_mutex gMutexUnicastServer = NULL;
40
41 /**
42  * @var gStopUnicast
43  * @brief Flag to control the Receive Unicast Data Thread
44  */
45 static bool gStopUnicast = FALSE;
46
47 /**
48  * @var gMutexMulticastServer
49  * @brief Mutex to synchronize secure multicast server
50  */
51 static u_mutex gMutexMulticastServer = NULL;
52
53 /**
54  * @var gStopMulticast
55  * @brief Flag to control the Receive Multicast Data Thread
56  */
57 static bool gStopMulticast = FALSE;
58
59 /**
60  * @var gStopAccept
61  * @brief Flag to control the Accept Thread
62  */
63 static bool gStopAccept = FALSE;
64
65 typedef struct send_data {
66     char* address;
67     char* data;
68     uint32_t id;
69 } data_t;
70
71 /**
72  @brief Thread context information for unicast, multicast and secured unicast server
73  */
74 typedef struct
75 {
76     bool *stopFlag;
77     CAAdapterServerType_t type;
78 } CAAdapterReceiveThreadContext_t;
79
80 typedef struct
81 {
82     bool *stopFlag;
83 } CAAdapterAcceptThreadContext_t;
84
85 /**
86  * implement for BT-EDR adapter common method
87  */
88 CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
89 {
90     OIC_LOG_V(DEBUG, TAG, "IN - CAEDRGetInterfaceInformation");
91
92     CALocalConnectivity_t *netInfo = NULL;
93
94     int32_t netInfoSize = 1;
95
96     netInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * netInfoSize);
97     if(NULL == netInfo)
98     {
99         OIC_LOG_V(ERROR, TAG, "Invalid input..");
100         return CA_MEMORY_ALLOC_FAILED;
101     }
102     memset(netInfo, 0, sizeof(CALocalConnectivity_t) * netInfoSize);
103
104     char *macAddress = NULL;
105     CAResult_t ret = CAEDRGetInterfaceInfo(&macAddress);
106     OIC_LOG_V(ERROR, TAG, "address : %s", macAddress);
107     if (CA_STATUS_OK != ret || NULL == macAddress)
108     {
109         OIC_LOG_V(ERROR, TAG, "Failed to get interface info [%d]", ret);
110
111         OICFree(netInfo);
112         OICFree(macAddress);
113         return ret;
114     }
115
116     // Create local endpoint using util function
117     CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_EDR, macAddress);
118     if (NULL == endpoint)
119     {
120         OIC_LOG_V(ERROR, TAG, "Failed to create Local Endpoint!",
121                   CA_MEMORY_ALLOC_FAILED);
122         OICFree(netInfo);
123         OICFree(macAddress);
124         return CA_MEMORY_ALLOC_FAILED;
125     }
126
127     // copy unicast server information
128     endpoint->isSecured = CA_FALSE;
129     memcpy(&netInfo[0], endpoint, sizeof(CALocalConnectivity_t));
130     *info = netInfo;
131
132     OICFree(macAddress);
133     CAAdapterFreeLocalEndpoint(endpoint);
134
135     OIC_LOG_V(DEBUG, TAG, "OUT - CAEDRGetInterfaceInformation");
136     return CA_STATUS_OK;
137 }
138
139 void CAEDRTerminateClient()
140 {
141     OIC_LOG(DEBUG, TAG, "IN");
142     CAEDRTerminate();
143     OIC_LOG(DEBUG, TAG, "OUT");
144 }
145
146 CAResult_t CAEDRManagerReadData(void)
147 {
148     OIC_LOG_V(DEBUG, TAG, "IN");
149     OIC_LOG_V(DEBUG, TAG, "OUT");
150     return CA_NOT_SUPPORTED;
151 }
152
153 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
154                                       void *data, uint32_t dataLength, uint32_t *sentLength)
155 {
156     OIC_LOG_V(DEBUG, TAG, "IN");
157     CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
158     OIC_LOG_V(DEBUG, TAG, "OUT");
159     return CA_STATUS_OK;
160 }
161
162
163 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, void *data,
164                                         uint32_t dataLength, uint32_t *sentLength)
165 {
166     OIC_LOG_V(DEBUG, TAG, "IN");
167     CAEDRSendMulticastMessage((const char*) data, dataLength);
168     OIC_LOG_V(DEBUG, TAG, "OUT");
169     return CA_STATUS_OK;
170 }
171
172 void CAEDRClientUnsetCallbacks(void)
173 {
174     OIC_LOG_V(DEBUG, TAG, "IN");
175
176     OIC_LOG_V(DEBUG, TAG, "OUT");
177 }
178
179 void CAEDRClientDisconnectAll(void)
180 {
181     OIC_LOG_V(DEBUG, TAG, "IN");
182
183     OIC_LOG_V(DEBUG, TAG, "OUT");
184 }
185
186 CAResult_t CAEDRGetAdapterEnableState(CABool_t *state)
187 {
188     OIC_LOG_V(DEBUG, TAG, "IN");
189
190     jboolean isAttached = FALSE;
191     JNIEnv* env;
192     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
193     if(res != JNI_OK)
194     {
195         OIC_LOG_V(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer");
196         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
197
198         if(res != JNI_OK)
199         {
200             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
201             return CA_STATUS_FAILED;
202         }
203         isAttached = TRUE;
204     }
205     jboolean ret = CAEDRNativeIsEnableBTAdapter(env);
206     if(ret)
207     {
208         *state = CA_TRUE;
209     }
210     else
211     {
212         *state = CA_FALSE;
213     }
214
215     if(isAttached)
216         (*g_jvm)->DetachCurrentThread(g_jvm);
217
218     OIC_LOG_V(DEBUG, TAG, "OUT");
219     return CA_STATUS_OK;
220 }
221
222 ////////////////////////////////////////////////////////////////////////////////////////////////////
223 //FIXME getting context
224
225 void CAEDRJniSetContext()
226 {
227     OIC_LOG_V(DEBUG, TAG, "CAEDRJniSetContext");
228
229     gContext = CANativeJNIGetContext();
230 }
231
232 void CAEDRCreateJNIInterfaceObject(jobject context)
233 {
234     JNIEnv* env;
235     OIC_LOG_V(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject");
236
237     if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
238     {
239         OIC_LOG_V(DEBUG, TAG, "[EDRCore] Could not get JNIEnv pointer");
240         return;
241     }
242
243     //getApplicationContext
244     jclass contextClass = (*env)->FindClass(env, "android/content/Context");
245     if (contextClass == 0)
246     {
247         OIC_LOG_V(DEBUG, TAG, "[EDRCore] Could not get context object class");
248         return;
249     }
250
251     jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
252             "getApplicationContext", "()Landroid/content/Context;");
253     if (getApplicationContextMethod == 0)
254     {
255         OIC_LOG_V(DEBUG, TAG, "[EDRCore] Could not get getApplicationContext method");
256         return;
257     }
258
259     //Create EDRJniInterface instance
260     jclass EDRJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAEDRInterface");
261     if (!EDRJniInterface)
262     {
263         OIC_LOG_V(DEBUG, TAG, "[EDRCore] Could not get CAEDRInterface class");
264         return;
265     }
266
267     jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env,
268             EDRJniInterface, "<init>", "(Landroid/content/Context;)V");
269     if (!EDRInterfaceConstructorMethod)
270     {
271         OIC_LOG_V(DEBUG, TAG, "[EDRCore] Could not get CAEDRInterface constructor method");
272         return;
273     }
274
275     (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context);
276     OIC_LOG_V(DEBUG, TAG, "[EDRCore] NewObject Success");
277
278 }
279
280 static void CAEDRDestroyMutex()
281 {
282     OIC_LOG(DEBUG, TAG, "IN");
283
284     if (gMutexUnicastServer)
285     {
286         u_mutex_free(gMutexUnicastServer);
287         gMutexUnicastServer = NULL;
288     }
289
290 #ifdef __WITH_DTLS__
291
292 #endif
293
294     if (gMutexMulticastServer)
295     {
296         u_mutex_free(gMutexMulticastServer);
297         gMutexMulticastServer = NULL;
298     }
299
300     OIC_LOG(DEBUG, TAG, "OUT");
301 }
302
303 static CAResult_t CAEDRCreateMutex()
304 {
305     OIC_LOG(DEBUG, TAG, "IN");
306
307     gMutexUnicastServer = u_mutex_new();
308     if (!gMutexUnicastServer)
309     {
310         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
311         return CA_STATUS_FAILED;
312     }
313
314 #ifdef __WITH_DTLS__
315
316 #endif
317
318     gMutexMulticastServer = u_mutex_new();
319     if (!gMutexMulticastServer)
320     {
321         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
322
323         CAEDRDestroyMutex();
324         return CA_STATUS_FAILED;
325     }
326
327     OIC_LOG(DEBUG, TAG, "OUT");
328     return CA_STATUS_OK;
329 }
330
331 void CAEDRInitialize(u_thread_pool_t handle)
332 {
333     OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
334
335     gThreadPoolHandle = handle;
336
337     CAEDRCoreJniInit();
338
339     CAEDRJniSetContext();
340
341     // init mutex
342     CAEDRCreateMutex();
343
344     jboolean isAttached = FALSE;
345     JNIEnv* env;
346     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
347     if(res != JNI_OK)
348     {
349         OIC_LOG_V(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
350         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
351
352         if(res != JNI_OK)
353         {
354             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
355             return;
356         }
357         isAttached = TRUE;
358     }
359
360     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
361     if(jni_address)
362     {
363         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
364         OIC_LOG_V(DEBUG, TAG, "My BT Address is %s ", localAddress);
365     }
366
367     CAEDRNativeCreateDeviceStateList();
368     CAEDRNativeCreateDeviceSocketList();
369
370     if(isAttached)
371         (*g_jvm)->DetachCurrentThread(g_jvm);
372
373     if(gContext)
374     {
375         //FIXME
376         CAEDRCreateJNIInterfaceObject(gContext); /* create java CAEDRInterface instance*/
377     }
378
379     OIC_LOG(DEBUG, TAG, "OUT");
380 }
381
382 void CAEDRTerminate()
383 {
384     OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
385
386     jboolean isAttached = FALSE;
387     JNIEnv* env;
388     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
389     if(res != JNI_OK)
390     {
391         OIC_LOG_V(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer");
392         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
393
394         if(res != JNI_OK)
395         {
396             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
397             return;
398         }
399         isAttached = TRUE;
400     }
401
402     gStopAccept = TRUE;
403     gStopMulticast = TRUE;
404     gStopUnicast = TRUE;
405
406     CAEDRNativeSocketCloseToAll(env);
407
408     // delete mutex
409     CAEDRDestroyMutex();
410
411     CAEDRNativeRemoveAllDeviceState();
412     CAEDRNativeRemoveAllDeviceSocket(env);
413
414     if(isAttached)
415         (*g_jvm)->DetachCurrentThread(g_jvm);
416 }
417
418 void CAEDRCoreJniInit()
419 {
420     OIC_LOG_V(DEBUG, TAG, "CAEdrClientJniInit");
421     g_jvm = CANativeJNIGetJavaVM();
422 }
423
424 int32_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
425 {
426     OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
427
428     CAEDRSendUnicastMessageImpl(address, data, dataLen);
429     return 0;
430 }
431
432 int32_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
433 {
434     OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
435
436     jboolean isAttached = FALSE;
437     JNIEnv* env;
438     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
439     if(res != JNI_OK)
440     {
441         OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer");
442         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
443
444         if(res != JNI_OK)
445         {
446             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
447             return 0;
448         }
449         isAttached = TRUE;
450     }
451
452     CAEDRSendMulticastMessageImpl(env, data, dataLen);
453
454     OIC_LOG_V(DEBUG, TAG, "sent data");
455
456     if(isAttached)
457     {
458         OIC_LOG_V(DEBUG, TAG, "DetachCurrentThread");
459 //        (*g_jvm)->DetachCurrentThread(g_jvm);
460     }
461
462     OIC_LOG_V(DEBUG, TAG, "OUT - CAEDRSendMulticastMessage");
463     return 1;
464 }
465
466 CAResult_t CAEDRGetInterfaceInfo(char **address)
467 {
468     CAEDRGetLocalAddress(address);
469     return CA_STATUS_OK;
470 }
471
472 void CAEDRGetLocalAddress(char** address)
473 {
474     jboolean isAttached = FALSE;
475     JNIEnv* env;
476     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
477     if(res != JNI_OK)
478     {
479         OIC_LOG_V(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer");
480         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
481         if(res != JNI_OK)
482         {
483             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
484             return;
485         }
486         isAttached = TRUE;
487     }
488
489     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
490     if(jni_address)
491     {
492         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
493         *address = (char*)OICMalloc(strlen(localAddress) + 1);
494         if (*address == NULL)
495         {
496             return;
497         }
498         memcpy(*address, localAddress, strlen(localAddress));
499     }
500
501     OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
502     if(isAttached)
503         (*g_jvm)->DetachCurrentThread(g_jvm);
504 }
505
506 int32_t CAEDRSendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
507 {
508     OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data);
509
510     jboolean isAttached = FALSE;
511     JNIEnv* env;
512     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
513     if(res != JNI_OK)
514     {
515         OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer");
516         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
517         if(res != JNI_OK)
518         {
519             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
520             return 0;
521         }
522         isAttached = TRUE;
523     }
524
525     OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
526
527     // get bonded device list
528     jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
529     if(!jni_arrayPairedDevices)
530     {
531         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
532         return 0;
533     }
534     // Get information from array of devices
535     jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
536     jsize i;
537     for( i = 0 ; i < length ; i++ )
538     {
539         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] start to check device");
540         // get name, address from BT device
541         jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
542
543         jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
544         jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName", "()Ljava/lang/String;");
545         jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress", "()Ljava/lang/String;");
546
547         jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
548
549         if(j_str_name)
550         {
551             const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
552             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
553             (*env)->ReleaseStringUTFChars(env, j_str_name, name);
554         }
555
556         jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
557         const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
558         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
559
560         // find address
561         if(!strcmp(remoteAddress, address))
562         {
563             CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
564         }
565     }
566
567     if(isAttached)
568         (*g_jvm)->DetachCurrentThread(g_jvm);
569
570     return 1;
571 }
572
573 int32_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
574 {
575     OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
576
577     // get bonded device list
578     jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
579     if(!jni_arrayPairedDevices)
580     {
581         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
582         return 0;
583     }
584     // Get information from array of devices
585     jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
586     jsize i;
587     for( i = 0 ; i < length ; i++ )
588     {
589         // get name, address from BT device
590         jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
591
592         jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
593         jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice, "getName", "()Ljava/lang/String;");
594         jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice, "getAddress", "()Ljava/lang/String;");
595
596         jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
597
598         if(j_str_name)
599         {
600             const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
601             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
602             (*env)->ReleaseStringUTFChars(env, j_str_name, name);
603         }
604
605         jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
606         const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
607         OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
608
609         // find address
610         CAEDRNativeSendData(env, remoteAddress, data, dataLen, i);
611     }
612
613     return 1;
614 }
615
616 /**
617  * EDR Method
618  */
619 void CAEDRNativeSendData(JNIEnv *env, const char* address, const char* data, uint32_t dataLength, uint32_t id)
620 {
621     OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData logic start : %s, %d", data, dataLength);
622
623     if(!CAEDRNativeIsEnableBTAdapter(env))
624     {
625         OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
626         return;
627     }
628
629     if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
630     {
631         // connect before send data
632         OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
633
634         if(NULL == address)
635         {
636             OIC_LOG(DEBUG, TAG, "[EDR][Native] remote address is empty");
637             return;
638         }
639         else
640         {
641             CAEDRNativeConnect(env, address, id);
642         }
643     }
644
645     if(STATE_CONNECTED == CAEDRIsConnectedDevice(address))
646     {
647         if(!((*env)->ExceptionCheck(env)))
648         {
649             jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
650             if(!jni_cid_BTsocket)
651             {
652                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
653                 return;
654             }
655
656             jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getOutputStream", "()Ljava/io/OutputStream;");
657             if(!jni_mid_getOutputStream)
658             {
659                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
660                 return;
661             }
662             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream..%d", id);
663
664             jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
665             if(!jni_obj_socket)
666             {
667                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_socket is not available");
668                 return;
669             }
670
671             jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getOutputStream);
672             if(!jni_obj_outputStream)
673             {
674                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
675                 return;
676             }
677
678             OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
679
680             jclass jni_cid_OutputStream = (*env)->FindClass(env, "java/io/OutputStream");
681             if(!jni_cid_OutputStream)
682             {
683                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
684                 return;
685             }
686
687             jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write", "([BII)V");
688             if(!jni_mid_write)
689             {
690                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
691                 return;
692             }
693
694             jbyteArray jbuf;
695             jbuf = (*env)->NewByteArray(env, dataLength);
696             (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*)data);
697
698             (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint)0, (jint)dataLength);
699
700             if((*env)->ExceptionCheck(env))
701             {
702                 OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Error!!!");
703                 (*env)->ExceptionDescribe(env);
704                 (*env)->ExceptionClear(env);
705                 return;
706             }
707
708             OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
709         }
710         else
711         {
712             (*env)->ExceptionDescribe(env);
713             (*env)->ExceptionClear(env);
714             OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: error!!");
715             return;
716         }
717     }
718     else
719     {
720         OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
721     }
722 }
723
724 void CAEDRNativeConnect(JNIEnv *env, const char* address, uint32_t id)
725 {
726     OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
727
728     if(!CAEDRNativeIsEnableBTAdapter(env))
729     {
730         OIC_LOG(DEBUG, TAG, "BT adpater is not enable");
731         return;
732     }
733
734     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
735     if(!jni_cid_BTAdapter)
736     {
737         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
738         return;
739     }
740
741     // get BTadpater
742     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
743     if(!jni_mid_getDefaultAdapter)
744     {
745         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null");
746         return;
747     }
748
749     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
750     if(!jni_obj_BTAdapter)
751     {
752         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null");
753         return;
754     }
755
756     // get remote bluetooth device
757     jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getRemoteDevice",
758          "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;");
759     if(!jni_mid_getRemoteDevice)
760     {
761         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
762         return;
763     }
764
765     //jstring jni_address = (*env)->NewStringUTF(env, "B8:5E:7B:54:52:1C");
766     jstring jni_address = (*env)->NewStringUTF(env, address);
767     jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getRemoteDevice, jni_address);
768     if(!jni_obj_remoteBTDevice)
769     {
770         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
771         return;
772     }
773
774     // get create Rfcomm Socket method ID
775     jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
776     if(!jni_cid_BluetoothDevice)
777     {
778         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
779         return;
780     }
781
782     jmethodID jni_mid_createSocket = (*env)->GetMethodID(env, jni_cid_BluetoothDevice,
783          "createInsecureRfcommSocketToServiceRecord","(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;");
784     if(!jni_mid_createSocket) {
785         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null");
786         return;
787     }
788
789     // createInsecureRfcommSocketToServiceRecord / createRfcommSocketToServiceRecord
790     // setting UUID
791     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
792     if(!jni_cid_uuid)
793     {
794         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
795         return;
796     }
797
798     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
799             "(Ljava/lang/String;)Ljava/util/UUID;");
800     if(!jni_mid_fromString)
801     {
802         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null");
803         return;
804     }
805
806     jstring jni_uuid = (*env)->NewStringUTF(env, "00000000-0000-0000-0000-0000cdab0000");
807     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
808     if(!jni_obj_uuid)
809     {
810         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
811         return;
812     }
813     // create socket
814     jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice, jni_mid_createSocket, jni_obj_uuid);
815     if(!jni_obj_BTSocket)
816     {
817         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null");
818         return;
819     }
820
821     // connect
822     jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
823     if(!jni_cid_BTSocket)
824     {
825         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
826         return;
827     }
828
829     jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
830     if(!jni_mid_connect)
831     {
832         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
833         return;
834     }
835
836     OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
837     (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
838
839     if((*env)->ExceptionCheck(env))
840     {
841         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
842         (*env)->ExceptionDescribe(env);
843         (*env)->ExceptionClear(env);
844         return;
845     }
846
847     // set socket to list
848     jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
849     CAEDRNativeAddDeviceSocketToList(env, jni_socket);
850
851     // update state
852     CAEDRUpdateDeviceState(STATE_CONNECTED, address);
853
854     OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
855 }
856
857 void CAEDRNativeSocketClose(JNIEnv *env, const char* address, uint32_t id)
858 {
859
860     jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
861     if(!jni_cid_BTSocket)
862     {
863         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
864         return;
865     }
866
867     jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
868     if(!jni_mid_close)
869     {
870         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_mid_close is null");
871         return;
872     }
873
874     jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
875     if(!jni_obj_socket)
876     {
877         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: jni_obj_socket is not available");
878         return;
879     }
880
881     (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
882
883     if((*env)->ExceptionCheck(env))
884     {
885         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!");
886         (*env)->ExceptionDescribe(env);
887         (*env)->ExceptionClear(env);
888         return;
889     }
890
891     // remove socket to list
892     CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
893
894     // update state
895     CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
896
897     OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
898 }
899
900 void CAEDRInitializeClient(u_thread_pool_t handle)
901 {
902     OIC_LOG(DEBUG, TAG, "IN");
903     CAEDRInitialize(handle);
904     OIC_LOG(DEBUG, TAG, "OUT");
905 }