Fix incorrect usages of OIC_LOG_V macro.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_edr_adapter / android / caedrclient.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 "caedrclient.h"
28 #include "caleserver.h"
29 #include "logger.h"
30 #include "oic_malloc.h"
31 #include "uthreadpool.h" /* for thread pool */
32 #include "umutex.h"
33 #include "uarraylist.h"
34 #include "caadapterutils.h"
35
36 //#define DEBUG_MODE
37 #define TAG PCF("CA_EDR_CLIENT")
38
39 static const char *METHODID_OBJECTNONPARAM = "()Landroid/bluetooth/BluetoothAdapter;";
40 static const char *METHODID_STRINGNONPARAM = "()Ljava/lang/String;";
41 static const char *CLASSPATH_BT_ADPATER = "android/bluetooth/BluetoothAdapter";
42 static const char *CLASSPATH_BT_UUID = "java/util/UUID";
43
44 static const uint32_t MAX_PDU_BUFFER = 1024;
45
46 static u_arraylist_t *g_deviceStateList = NULL;
47 static u_arraylist_t *g_deviceObjectList = NULL;
48
49 static u_thread_pool_t g_threadPoolHandle = NULL;
50
51 static JavaVM *g_jvm;
52 static jobject g_context;
53
54 static jbyteArray g_sendBuffer;
55
56 /**
57  * @var g_mutexSocketListManager
58  * @brief Mutex to synchronize socket list update
59  */
60 static u_mutex g_mutexSocketListManager;
61
62 // server socket instance
63 static jobject g_serverSocketObject = NULL;
64
65 /**
66  * @var g_mutexUnicastServer
67  * @brief Mutex to synchronize unicast server
68  */
69 static u_mutex g_mutexUnicastServer = NULL;
70
71 /**
72  * @var g_stopUnicast
73  * @brief Flag to control the Receive Unicast Data Thread
74  */
75 static bool g_stopUnicast = false;
76
77 /**
78  * @var g_mutexMulticastServer
79  * @brief Mutex to synchronize secure multicast server
80  */
81 static u_mutex g_mutexMulticastServer = NULL;
82
83 /**
84  * @var g_stopMulticast
85  * @brief Flag to control the Receive Multicast Data Thread
86  */
87 static bool g_stopMulticast = false;
88
89 /**
90  * @var g_stopAccept
91  * @brief Flag to control the Accept Thread
92  */
93 static bool g_stopAccept = false;
94
95 typedef struct send_data {
96     char* address;
97     char* data;
98     uint32_t id;
99 } data_t;
100
101 /**
102  @brief Thread context information for unicast, multicast and secured unicast server
103  */
104 typedef struct
105 {
106     bool *stopFlag;
107     CAAdapterServerType_t type;
108 } CAAdapterReceiveThreadContext_t;
109
110 typedef struct
111 {
112     bool *stopFlag;
113 } CAAdapterAcceptThreadContext_t;
114
115
116 // TODO: It will be updated when android EDR support is added
117 CAResult_t CAEDRGetInterfaceInformation(CALocalConnectivity_t **info)
118 {
119     OIC_LOG(DEBUG, TAG, "IN");
120
121     OIC_LOG(DEBUG, TAG, "OUT");
122     return CA_STATUS_OK;
123 }
124
125 void CAEDRClientTerminate()
126 {
127     OIC_LOG(DEBUG, TAG, "IN");
128     CAEDRTerminate();
129     OIC_LOG(DEBUG, TAG, "OUT");
130 }
131
132 CAResult_t CAEDRManagerReadData(void)
133 {
134     OIC_LOG(DEBUG, TAG, "IN");
135     OIC_LOG(DEBUG, TAG, "OUT");
136     return CA_NOT_SUPPORTED;
137 }
138
139 CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress, const char *serviceUUID,
140                                       const void *data, uint32_t dataLength, uint32_t *sentLength)
141 {
142     OIC_LOG(DEBUG, TAG, "IN");
143     CAEDRSendUnicastMessage(remoteAddress, (const char*) data, dataLength);
144     OIC_LOG(DEBUG, TAG, "OUT");
145     return CA_STATUS_OK;
146 }
147
148
149 CAResult_t CAEDRClientSendMulticastData(const char *serviceUUID, const void *data,
150                                         uint32_t dataLength, uint32_t *sentLength)
151 {
152     OIC_LOG(DEBUG, TAG, "IN");
153     CAEDRSendMulticastMessage((const char*) data, dataLength);
154     OIC_LOG(DEBUG, TAG, "OUT");
155     return CA_STATUS_OK;
156 }
157
158 // TODO: It will be updated when android EDR support is added
159 void CAEDRClientUnsetCallbacks(void)
160 {
161     OIC_LOG(DEBUG, TAG, "IN");
162
163     OIC_LOG(DEBUG, TAG, "OUT");
164 }
165
166 // TODO: It will be updated when android EDR support is added
167 void CAEDRClientDisconnectAll(void)
168 {
169     OIC_LOG(DEBUG, TAG, "IN");
170
171     OIC_LOG(DEBUG, TAG, "OUT");
172 }
173
174 CAResult_t CAEDRGetAdapterEnableState(bool *state)
175 {
176     OIC_LOG(DEBUG, TAG, "IN");
177     if (!g_jvm)
178     {
179         OIC_LOG(ERROR, TAG, "g_jvm is null");
180         return CA_STATUS_INVALID_PARAM;
181     }
182     jboolean isAttached = JNI_FALSE;
183     JNIEnv* env;
184     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
185     if(res != JNI_OK)
186     {
187         OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer");
188         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
189
190         if(res != JNI_OK)
191         {
192             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
193             return CA_STATUS_INVALID_PARAM;
194         }
195         isAttached = JNI_TRUE;
196     }
197     jboolean ret = CAEDRNativeIsEnableBTAdapter(env);
198     if(ret)
199     {
200         *state = true;
201     }
202     else
203     {
204         *state = false;
205     }
206
207     if(isAttached)
208         (*g_jvm)->DetachCurrentThread(g_jvm);
209
210     OIC_LOG(DEBUG, TAG, "OUT");
211     return CA_STATUS_OK;
212 }
213
214 ////////////////////////////////////////////////////////////////////////////////////////////////////
215 //FIXME getting context
216
217 void CAEDRJniSetContext(jobject context)
218 {
219     OIC_LOG(DEBUG, TAG, "caedrSetObject");
220
221     if (!context)
222     {
223         OIC_LOG(ERROR, TAG, "context is null");
224         return;
225     }
226     jboolean isAttached = JNI_FALSE;
227     JNIEnv* env;
228     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
229     if(res != JNI_OK)
230     {
231         OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
232         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
233
234         if(res != JNI_OK)
235         {
236             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
237             return;
238         }
239         isAttached = JNI_TRUE;
240     }
241
242     g_context = (*env)->NewGlobalRef(env, context);
243
244     if(isAttached)
245         (*g_jvm)->DetachCurrentThread(g_jvm);
246 }
247
248 void CAEDRCreateJNIInterfaceObject(jobject context)
249 {
250     JNIEnv* env;
251     OIC_LOG(DEBUG, TAG, "[EDRCore] CAEDRCreateJNIInterfaceObject");
252
253     if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
254     {
255         OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get JNIEnv pointer");
256         return;
257     }
258
259     //getApplicationContext
260     jclass contextClass = (*env)->FindClass(env, "android/content/Context");
261     if (contextClass == 0)
262     {
263         OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get context object class");
264         return;
265     }
266
267     jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
268             "getApplicationContext", "()Landroid/content/Context;");
269     if (getApplicationContextMethod == 0)
270     {
271         OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get getApplicationContext method");
272         return;
273     }
274
275     jobject gApplicationContext = (*env)->CallObjectMethod(env, context,
276             getApplicationContextMethod);
277     OIC_LOG_V(DEBUG, TAG,
278             "[WIFICore] Saving Android application context object %p", gApplicationContext);
279
280    //Create WiFiInterface instance
281     jclass WiFiJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAEDRInterface");
282     if (!WiFiJniInterface)
283     {
284         OIC_LOG(DEBUG, TAG, "[EDRCore] Could not get CAWiFiInterface class");
285         return;
286     }
287
288     jmethodID WiFiInterfaceConstructorMethod = (*env)->GetMethodID(env,
289             WiFiJniInterface, "<init>", "(Landroid/content/Context;)V");
290     if (!WiFiInterfaceConstructorMethod)
291     {
292         OIC_LOG(ERROR, TAG, "[EDRCore] Could not get CAWiFiInterface constructor method");
293         return;
294     }
295
296     (*env)->NewObject(env, WiFiJniInterface, WiFiInterfaceConstructorMethod, gApplicationContext);
297     OIC_LOG(DEBUG, TAG, "[EDRCore] Create CAWiFiInterface instance");
298     OIC_LOG(DEBUG, TAG, "[EDRCore] NewObject Success");
299
300 }
301
302 static void CAEDRDestroyMutex()
303 {
304     OIC_LOG(DEBUG, TAG, "IN");
305
306     if (g_mutexUnicastServer)
307     {
308         u_mutex_free(g_mutexUnicastServer);
309         g_mutexUnicastServer = NULL;
310     }
311
312     if (g_mutexMulticastServer)
313     {
314         u_mutex_free(g_mutexMulticastServer);
315         g_mutexMulticastServer = NULL;
316     }
317
318     if(g_mutexSocketListManager)
319     {
320         u_mutex_free(g_mutexSocketListManager);
321         g_mutexSocketListManager = NULL;
322     }
323
324     OIC_LOG(DEBUG, TAG, "OUT");
325 }
326
327 static CAResult_t CAEDRCreateMutex()
328 {
329     OIC_LOG(DEBUG, TAG, "IN");
330
331     g_mutexUnicastServer = u_mutex_new();
332     if (!g_mutexUnicastServer)
333     {
334         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
335         return CA_STATUS_FAILED;
336     }
337
338     g_mutexMulticastServer = u_mutex_new();
339     if (!g_mutexMulticastServer)
340     {
341         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
342
343         CAEDRDestroyMutex();
344         return CA_STATUS_FAILED;
345     }
346
347     g_mutexSocketListManager = u_mutex_new();
348     if (!g_mutexSocketListManager)
349     {
350         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
351
352         CAEDRDestroyMutex();
353         return CA_STATUS_FAILED;
354     }
355
356     OIC_LOG(DEBUG, TAG, "OUT");
357     return CA_STATUS_OK;
358 }
359
360 void CAEDRInitialize(u_thread_pool_t handle)
361 {
362     OIC_LOG(DEBUG, TAG, "CAEDRInitialize");
363
364     g_threadPoolHandle = handle;
365
366     // init mutex
367     CAEDRCreateMutex();
368
369     jboolean isAttached = JNI_FALSE;
370     JNIEnv* env;
371     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
372     if(res != JNI_OK)
373     {
374         OIC_LOG(DEBUG, TAG, "CAEDRInitialize - Could not get JNIEnv pointer");
375         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
376
377         if(res != JNI_OK)
378         {
379             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
380             return;
381         }
382         isAttached = JNI_TRUE;
383     }
384
385     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
386     if(jni_address)
387     {
388         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
389         OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
390     }
391
392     CAEDRNativeCreateDeviceStateList();
393     CAEDRNativeCreateDeviceSocketList();
394
395     if(isAttached)
396         (*g_jvm)->DetachCurrentThread(g_jvm);
397
398  //   CAEDRCreateJNIInterfaceObject(gContext); /* create java CAEDRInterface instance*/
399
400     OIC_LOG(DEBUG, TAG, "OUT");
401 }
402
403 void CAEDRTerminate()
404 {
405     OIC_LOG(DEBUG, TAG, "CAEDRTerminate");
406
407     jboolean isAttached = JNI_FALSE;
408     JNIEnv* env;
409     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
410     if(res != JNI_OK)
411     {
412         OIC_LOG(DEBUG, TAG, "CAEDRTerminate - Could not get JNIEnv pointer");
413         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
414
415         if(res != JNI_OK)
416         {
417             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
418             return;
419         }
420         isAttached = JNI_TRUE;
421     }
422
423     g_stopAccept = true;
424     g_stopMulticast = true;
425     g_stopUnicast = true;
426
427     if(isAttached)
428         (*g_jvm)->DetachCurrentThread(g_jvm);
429
430     if(g_context)
431     {
432         (*env)->DeleteGlobalRef(env, g_context);
433     }
434     // delete mutex
435     CAEDRDestroyMutex();
436
437     CAEDRNativeRemoveAllDeviceState();
438     CAEDRNativeRemoveAllDeviceSocket(env);
439 }
440
441 void CAEDRCoreJniInit(JNIEnv *env, JavaVM *jvm)
442 {
443     OIC_LOG(DEBUG, TAG, "CAEdrClientJniInit");
444     g_jvm = jvm;
445
446     CAEDRServerJniInit(env, jvm);
447 }
448
449 CAResult_t CAEDRSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
450 {
451     OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessage(%s, %s)", address, data);
452
453     CAEDRSendUnicastMessageImpl(address, data, dataLen);
454     return CA_STATUS_OK;
455 }
456
457 CAResult_t CAEDRSendMulticastMessage(const char* data, uint32_t dataLen)
458 {
459     OIC_LOG_V(DEBUG, TAG, "CAEDRSendMulticastMessage(%s)", data);
460
461     jboolean isAttached = JNI_FALSE;
462     JNIEnv* env;
463     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
464     if(res != JNI_OK)
465     {
466         OIC_LOG(DEBUG, TAG, "CAEDRSendMulticastMessage - Could not get JNIEnv pointer");
467         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
468
469         if(res != JNI_OK)
470         {
471             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
472             return CA_STATUS_INVALID_PARAM;
473         }
474         isAttached = JNI_TRUE;
475     }
476
477     CAEDRSendMulticastMessageImpl(env, data, dataLen);
478
479     OIC_LOG(DEBUG, TAG, "sent data");
480
481     if(isAttached)
482     {
483         OIC_LOG(DEBUG, TAG, "DetachCurrentThread");
484         (*g_jvm)->DetachCurrentThread(g_jvm);
485     }
486
487     OIC_LOG(DEBUG, TAG, "OUT - CAEDRSendMulticastMessage");
488     return CA_STATUS_OK;
489 }
490
491 CAResult_t CAEDRGetInterfaceInfo(char **address)
492 {
493     CAEDRGetLocalAddress(address);
494     return CA_STATUS_OK;
495 }
496
497 void CAEDRGetLocalAddress(char **address)
498 {
499     jboolean isAttached = JNI_FALSE;
500     JNIEnv* env;
501     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
502     if(res != JNI_OK)
503     {
504         OIC_LOG(DEBUG, TAG, "CAEDRGetLocalAddress - Could not get JNIEnv pointer");
505         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
506         if(res != JNI_OK)
507         {
508             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
509             return;
510         }
511         isAttached = JNI_TRUE;
512     }
513
514     jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
515     if(jni_address)
516     {
517         const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
518         *address = (char*)OICMalloc(strlen(localAddress) + 1);
519         if (*address == NULL)
520         {
521             if (isAttached)
522                 (*g_jvm)->DetachCurrentThread(g_jvm);
523             return;
524         }
525         memcpy(*address, localAddress, strlen(localAddress));
526     }
527
528     OIC_LOG_V(DEBUG, TAG, "Local Address : %s", *address);
529     if (isAttached)
530         (*g_jvm)->DetachCurrentThread(g_jvm);
531 }
532
533 CAResult_t CAEDRSendUnicastMessageImpl(const char* address, const char* data,
534     uint32_t dataLen)
535 {
536     OIC_LOG_V(DEBUG, TAG, "CAEDRSendUnicastMessageImpl, address: %s, data: %s", address, data);
537
538     jboolean isAttached = JNI_FALSE;
539     JNIEnv* env;
540     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
541     if(res != JNI_OK)
542     {
543         OIC_LOG(DEBUG, TAG, "CAEDRSendUnicastMessageImpl - Could not get JNIEnv pointer");
544         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
545         if(res != JNI_OK)
546         {
547             OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
548             return CA_STATUS_INVALID_PARAM;
549         }
550         isAttached = TRUE;
551     }
552
553     OIC_LOG(DEBUG, TAG, "[EDR][Native] set byteArray for data");
554     if(g_sendBuffer)
555     {
556         (*env)->DeleteGlobalRef(env, g_sendBuffer);
557     }
558     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
559     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*)data);
560     g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
561
562     // get bonded device list
563     jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
564     if(!jni_arrayPairedDevices)
565     {
566         OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
567         if (isAttached)
568             (*g_jvm)->DetachCurrentThread(g_jvm);
569         return CA_STATUS_INVALID_PARAM;
570     }
571     // Get information from array of devices
572     jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
573     jsize i;
574     for( i = 0 ; i < length ; i++ )
575     {
576         OIC_LOG(DEBUG, TAG, "[EDR][Native] start to check device");
577         // get name, address from BT device
578         jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
579
580         jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
581         jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice,
582                 "getName", "()Ljava/lang/String;");
583         jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice,
584                 "getAddress", "()Ljava/lang/String;");
585
586         jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
587
588         if(j_str_name)
589         {
590             const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
591             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
592             (*env)->ReleaseStringUTFChars(env, j_str_name, name);
593         }
594
595         jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
596         const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
597         OIC_LOG_V(DEBUG, TAG,
598                 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
599
600         if (!remoteAddress) {
601             OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
602             if (isAttached)
603                 (*g_jvm)->DetachCurrentThread(g_jvm);
604             return CA_STATUS_INVALID_PARAM;
605         }
606         if (!address) {
607             OIC_LOG(ERROR, TAG, "[EDR][Native] address is null");
608             if (isAttached)
609                 (*g_jvm)->DetachCurrentThread(g_jvm);
610             return CA_STATUS_INVALID_PARAM;
611         }
612         // find address
613         if(!strcmp(remoteAddress, address))
614         {
615             CAEDRNativeSendData(env, remoteAddress, data, i);
616         }
617     }
618
619     if (isAttached)
620         (*g_jvm)->DetachCurrentThread(g_jvm);
621
622     return CA_STATUS_OK;
623 }
624
625 CAResult_t CAEDRSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
626 {
627     OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
628
629     // get bonded device list
630     jobjectArray jni_arrayPairedDevices = CAEDRNativeGetBondedDevices(env);
631     if(!jni_arrayPairedDevices)
632     {
633         OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_arrayPairedDevices is empty");
634         return CA_STATUS_INVALID_PARAM;
635     }
636     // Get information from array of devices
637     jsize length = (*env)->GetArrayLength(env, jni_arrayPairedDevices);
638     jsize i;
639     for( i = 0 ; i < length ; i++ )
640     {
641         // get name, address from BT device
642         jobject j_obj_device = (*env)->GetObjectArrayElement(env, jni_arrayPairedDevices, i);
643
644         jclass jni_cid_BTDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
645         jmethodID j_mid_getName = (*env)->GetMethodID(env, jni_cid_BTDevice,
646                 "getName", "()Ljava/lang/String;");
647         jmethodID j_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTDevice,
648                 "getAddress", "()Ljava/lang/String;");
649
650         jstring j_str_name = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getName);
651
652         if(j_str_name)
653         {
654             const char * name = (*env)->GetStringUTFChars(env, j_str_name, NULL);
655             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] getBondedDevices: ~~device name is %s", name);
656             (*env)->ReleaseStringUTFChars(env, j_str_name, name);
657         }
658
659         jstring j_str_address = (*env)->CallObjectMethod(env, j_obj_device, j_mid_getAddress);
660         const char * remoteAddress = (*env)->GetStringUTFChars(env, j_str_address, NULL);
661         OIC_LOG_V(DEBUG, TAG,
662                 "[EDR][Native] getBondedDevices: ~~device address is %s", remoteAddress);
663
664         // find address
665         CAEDRNativeSendData(env, remoteAddress, data, i);
666     }
667
668     return CA_STATUS_OK;
669 }
670
671 /**
672  * EDR Method
673  */
674 void CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data, uint32_t id)
675 {
676     OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData logic start");
677
678     if(STATE_DISCONNECTED == CAEDRIsConnectedDevice(address))
679     {
680         // connect before send data
681         OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data");
682
683         if(NULL == address)
684         {
685             OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty");
686             return;
687         }
688         else
689         {
690             CAEDRNativeConnect(env, address, id);
691         }
692     }
693
694     if(STATE_CONNECTED == CAEDRIsConnectedDevice(address))
695     {
696         if(!((*env)->ExceptionCheck(env)))
697         {
698             jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
699             if(!jni_cid_BTsocket)
700             {
701                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null");
702                 return;
703             }
704
705             jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env,
706                     jni_cid_BTsocket, "getOutputStream",
707                     "()Ljava/io/OutputStream;");
708             if(!jni_mid_getOutputStream)
709             {
710                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null");
711                 return;
712             }
713             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream..%d", id);
714
715             jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
716             if(!jni_obj_socket)
717             {
718                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available");
719                 return;
720             }
721
722             jobject jni_obj_outputStream = (*env)->CallObjectMethod(env,
723                     jni_obj_socket, jni_mid_getOutputStream);
724             if(!jni_obj_outputStream)
725             {
726                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null");
727                 return;
728             }
729
730             OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream..");
731
732             jclass jni_cid_OutputStream = (*env)->FindClass(env, "java/io/OutputStream");
733             if(!jni_cid_OutputStream)
734             {
735                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null");
736                 return;
737             }
738
739             jmethodID jni_mid_write = (*env)->GetMethodID(env,
740                     jni_cid_OutputStream, "write", "([BII)V");
741             if(!jni_mid_write)
742             {
743                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null");
744                 return;
745             }
746
747             jbyteArray jbuf;
748             int length = strlen(data);
749             jbuf = (*env)->NewByteArray(env, length);
750             (*env)->SetByteArrayRegion(env, jbuf, 0, length, (jbyte*)data);
751
752             (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write,
753                     jbuf, (jint) 0, (jint) length);
754
755             if((*env)->ExceptionCheck(env))
756             {
757                 OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!");
758                 (*env)->ExceptionDescribe(env);
759                 (*env)->ExceptionClear(env);
760                 return;
761             }
762
763             OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success");
764
765             // remove socket to list
766             CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
767
768             // update state
769             CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
770         }
771         else
772         {
773             (*env)->ExceptionDescribe(env);
774             (*env)->ExceptionClear(env);
775             OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: error!!");
776             return;
777         }
778     }
779     else
780     {
781         OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!");
782     }
783 }
784
785 void CAEDRNativeConnect(JNIEnv *env, const char *address, uint32_t id)
786 {
787     OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect..");
788
789     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
790     if(!jni_cid_BTAdapter)
791     {
792         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTAdapter is null");
793         return;
794     }
795
796     // get BTadpater
797     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
798             jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
799     if(!jni_mid_getDefaultAdapter)
800     {
801         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getDefaultAdapter is null");
802         return;
803     }
804
805     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
806             jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
807     if(!jni_obj_BTAdapter)
808     {
809         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTAdapter is null");
810         return;
811     }
812
813     // get remote bluetooth device
814     jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env,
815             jni_cid_BTAdapter, "getRemoteDevice",
816             "(Ljava/lang/String;)Landroid/bluetooth/BluetoothDevice;");
817     if(!jni_mid_getRemoteDevice)
818     {
819         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_getRemoteDevice is null");
820         return;
821     }
822
823     //jstring jni_address = (*env)->NewStringUTF(env, "B8:5E:7B:54:52:1C");
824     jstring jni_address = (*env)->NewStringUTF(env, address);
825     jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env,
826             jni_obj_BTAdapter, jni_mid_getRemoteDevice, jni_address);
827     if(!jni_obj_remoteBTDevice)
828     {
829         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_remoteBTDevice is null");
830         return;
831     }
832
833     // get create Rfcomm Socket method ID
834     jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
835     if(!jni_cid_BluetoothDevice)
836     {
837         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BluetoothDevice is null");
838         return;
839     }
840
841     jmethodID jni_mid_createSocket = (*env)->GetMethodID(env,
842             jni_cid_BluetoothDevice,
843             "createInsecureRfcommSocketToServiceRecord",
844             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;");
845     if(!jni_mid_createSocket) {
846         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_createSocket is null");
847         return;
848     }
849
850     // createInsecureRfcommSocketToServiceRecord / createRfcommSocketToServiceRecord
851     // setting UUID
852     jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
853     if(!jni_cid_uuid)
854     {
855         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_uuid is null");
856         return;
857     }
858
859     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
860             "(Ljava/lang/String;)Ljava/util/UUID;");
861     if(!jni_mid_fromString)
862     {
863         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_fromString is null");
864         return;
865     }
866
867     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid,
868             jni_mid_fromString, OIC_EDR_SERVICE_ID);
869     if(!jni_obj_uuid)
870     {
871         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_uuid is null");
872         return;
873     }
874     // create socket
875     jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env,
876             jni_obj_remoteBTDevice, jni_mid_createSocket, jni_obj_uuid);
877     if(!jni_obj_BTSocket)
878     {
879         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_obj_BTSocket is null");
880         return;
881     }
882
883     // connect
884     jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
885     if(!jni_cid_BTSocket)
886     {
887         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_cid_BTSocket is null");
888         return;
889     }
890
891     jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V");
892     if(!jni_mid_connect)
893     {
894         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: jni_mid_connect is null");
895         return;
896     }
897
898     OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: initiating connection...");
899     (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect);
900
901     if((*env)->ExceptionCheck(env))
902     {
903         OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: Connect is Failed!!!");
904         (*env)->ExceptionDescribe(env);
905         (*env)->ExceptionClear(env);
906         return;
907     }
908
909     // set socket to list
910     jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
911     CAEDRNativeAddDeviceSocketToList(env, jni_socket);
912
913     // update state
914     CAEDRUpdateDeviceState(STATE_CONNECTED, address);
915
916     OIC_LOG(DEBUG, TAG, "[EDR][Native] btConnect: connected");
917 }
918
919 void CAEDRNativeSocketClose(JNIEnv *env, const char *address, uint32_t id)
920 {
921
922     jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
923     if(!jni_cid_BTSocket)
924     {
925         OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
926         return;
927     }
928
929     jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
930     if(!jni_mid_close)
931     {
932         OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null");
933         return;
934     }
935
936     jobject jni_obj_socket = CAEDRNativeGetDeviceSocket(id);
937     if(!jni_obj_socket)
938     {
939         OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available");
940         return;
941     }
942
943     (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
944
945     if((*env)->ExceptionCheck(env))
946     {
947         OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!");
948         (*env)->ExceptionDescribe(env);
949         (*env)->ExceptionClear(env);
950         return;
951     }
952
953     // remove socket to list
954     CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
955
956     // update state
957     CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
958
959     OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
960 }
961
962
963 /**
964  * BT State List
965  */
966 void CAEDRNativeCreateDeviceStateList()
967 {
968     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList");
969
970     // create new object array
971     if (g_deviceStateList == NULL)
972     {
973         OIC_LOG(DEBUG, TAG, "Create device list");
974
975         g_deviceStateList = u_arraylist_create();
976     }
977 }
978
979 void CAEDRUpdateDeviceState(CAConnectedState_t state, const char *address)
980 {
981     state_t *newstate = (state_t*) OICCalloc(1, sizeof(state_t));
982     if (!newstate) {
983         OIC_LOG(ERROR, TAG, "[EDR][Native] newstate is null");
984         return;
985     }
986     strcpy(newstate->address, address);
987     newstate->state = state;
988
989     CAEDRNativeAddDeviceStateToList(newstate);
990 }
991
992 void CAEDRNativeAddDeviceStateToList(state_t *state)
993 {
994     if(!state)
995     {
996         OIC_LOG(ERROR, TAG, "[EDR][Native] device is null");
997         return;
998     }
999
1000     if(!g_deviceStateList)
1001     {
1002         OIC_LOG(ERROR, TAG, "[EDR][Native] gdevice_list is null");
1003         return;
1004     }
1005
1006     if(CAEDRNativeIsDeviceInList(state->address)) {
1007         CAEDRNativeRemoveDevice(state->address); // delete previous state for update new state
1008     }
1009     u_arraylist_add(g_deviceStateList, state);          // update new state
1010     OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d", state->state);
1011 }
1012
1013 jboolean CAEDRNativeIsDeviceInList(const char* remoteAddress){
1014
1015     jint index;
1016     if (!remoteAddress) {
1017         OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
1018         return JNI_TRUE;
1019     }
1020     for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1021     {
1022         state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1023         if(!state)
1024         {
1025             OIC_LOG(ERROR, TAG, "[EDR][Native] state_t object is null");
1026             return JNI_TRUE;
1027         }
1028
1029         if(!strcmp(remoteAddress, state->address))
1030         {
1031             OIC_LOG(DEBUG, TAG, "the device is already set");
1032             return JNI_TRUE;
1033         }
1034         else
1035         {
1036             continue;
1037         }
1038     }
1039
1040     OIC_LOG(DEBUG, TAG, "there are no the device in list.");
1041     return JNI_FALSE;
1042 }
1043
1044 void CAEDRNativeRemoveAllDeviceState()
1045 {
1046     OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveAllDevices");
1047
1048     if(!g_deviceStateList)
1049     {
1050         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
1051         return;
1052     }
1053
1054     jint index;
1055     for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1056     {
1057         state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1058         if(!state)
1059         {
1060             OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1061             continue;
1062         }
1063         OICFree(state);
1064     }
1065
1066     OICFree(g_deviceStateList);
1067     g_deviceStateList = NULL;
1068     return;
1069 }
1070
1071 void CAEDRNativeRemoveDevice(const char *remoteAddress)
1072 {
1073     OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceforStateList");
1074
1075     if(!g_deviceStateList)
1076     {
1077         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
1078         return;
1079     }
1080     if (!remoteAddress) {
1081         OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
1082         return;
1083     }
1084
1085     jint index;
1086     for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1087     {
1088         state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1089         if(!state)
1090         {
1091             OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
1092             continue;
1093         }
1094
1095         if(!strcmp(state->address, remoteAddress))
1096         {
1097             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove state : %s", remoteAddress);
1098             OICFree(state);
1099
1100             CAEDRReorderingDeviceList(index);
1101             break;
1102         }
1103     }
1104     return;
1105 }
1106
1107 CAConnectedState_t CAEDRIsConnectedDevice(const char *remoteAddress)
1108 {
1109     OIC_LOG(DEBUG, TAG, "CAEDRIsConnectedDevice");
1110
1111     if(!g_deviceStateList)
1112     {
1113         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
1114         return STATE_DISCONNECTED;
1115     }
1116
1117     jint index;
1118     for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
1119     {
1120         state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
1121         if(!state)
1122         {
1123             OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
1124             continue;
1125         }
1126
1127         if(!strcmp(state->address, remoteAddress))
1128         {
1129             OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not");
1130
1131             return state->state;
1132         }
1133     }
1134     return STATE_DISCONNECTED;
1135 }
1136
1137 void CAEDRReorderingDeviceList(uint32_t index)
1138 {
1139     if (index >= g_deviceStateList->length)
1140     {
1141         return;
1142     }
1143
1144     if (index < g_deviceStateList->length - 1)
1145     {
1146         memmove(&g_deviceStateList->data[index], &g_deviceStateList->data[index + 1],
1147                 (g_deviceStateList->length - index - 1) * sizeof(void *));
1148     }
1149
1150     g_deviceStateList->size--;
1151     g_deviceStateList->length--;
1152 }
1153
1154 /**
1155  * Device Socket Object List
1156  */
1157 void CAEDRNativeCreateDeviceSocketList()
1158 {
1159     OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceSocketList");
1160
1161     // create new object array
1162     if (g_deviceObjectList == NULL)
1163     {
1164         OIC_LOG(DEBUG, TAG, "Create Device object list");
1165
1166         g_deviceObjectList = u_arraylist_create();
1167     }
1168 }
1169
1170 void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
1171 {
1172     OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeAddDeviceobjToList");
1173
1174     if(!deviceSocket)
1175     {
1176         OIC_LOG(ERROR, TAG, "[EDR][Native] Device is null");
1177         return;
1178     }
1179
1180     if(!g_deviceObjectList)
1181     {
1182         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1183         return;
1184     }
1185
1186     jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1187     if(!jni_remoteAddress)
1188     {
1189         OIC_LOG(ERROR, TAG, "[EDR][Native] jni_remoteAddress is null");
1190         return;
1191     }
1192
1193     u_mutex_lock(g_mutexSocketListManager);
1194
1195     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1196
1197     if(!CAEDRNativeIsDeviceSocketInList(env, remoteAddress))
1198     {
1199         jobject gDeviceSocker = (*env)->NewGlobalRef(env, deviceSocket);
1200         u_arraylist_add(g_deviceObjectList, gDeviceSocker);
1201         OIC_LOG(DEBUG, TAG, "Set Socket Object to Array");
1202     }
1203
1204     u_mutex_unlock(g_mutexSocketListManager);
1205 }
1206
1207 jboolean CAEDRNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress)
1208 {
1209     OIC_LOG(DEBUG, TAG, "[EDR][Native] CANativeIsDeviceObjInList");
1210
1211     jint index;
1212
1213     if (!remoteAddress) {
1214         OIC_LOG(ERROR, TAG, "[EDR][Native] remoteAddress is null");
1215         return JNI_TRUE;
1216     }
1217     for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1218     {
1219
1220         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1221         if(!jarrayObj)
1222         {
1223             OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1224             return JNI_TRUE;
1225         }
1226
1227         jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1228         if(!jni_setAddress)
1229         {
1230             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null");
1231             return JNI_TRUE;
1232         }
1233
1234         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1235         if(!setAddress)
1236         {
1237             OIC_LOG(DEBUG, TAG, "[EDR][Native] setAddress is null");
1238             return JNI_TRUE;
1239         }
1240
1241         if(!strcmp(remoteAddress, setAddress))
1242         {
1243             OIC_LOG(DEBUG, TAG, "the device is already set");
1244             return JNI_TRUE;
1245         }
1246         else
1247         {
1248             continue;
1249         }
1250     }
1251
1252     OIC_LOG(DEBUG, TAG, "there are no the Device obejct in list. we can add");
1253     return JNI_FALSE;
1254 }
1255
1256 void CAEDRNativeRemoveAllDeviceSocket(JNIEnv *env)
1257 {
1258     OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList");
1259
1260     if(!g_deviceObjectList)
1261     {
1262         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1263         return;
1264     }
1265
1266     jint index;
1267     for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1268     {
1269         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1270         if(!jarrayObj)
1271         {
1272             OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1273             return;
1274         }
1275         (*env)->DeleteGlobalRef(env, jarrayObj);
1276     }
1277
1278     OICFree(g_deviceObjectList);
1279     g_deviceObjectList = NULL;
1280     return;
1281 }
1282
1283 void CAEDRNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket)
1284 {
1285     OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDeviceSocket");
1286
1287     if(!g_deviceObjectList)
1288     {
1289         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1290         return;
1291     }
1292
1293     u_mutex_lock(g_mutexSocketListManager);
1294
1295     jint index;
1296     for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1297     {
1298         jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1299         if(!jarrayObj)
1300         {
1301             OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
1302             continue;
1303         }
1304
1305         jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1306         if(!jni_setAddress)
1307         {
1308             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_setAddress is null");
1309             continue;
1310         }
1311         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1312
1313         jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1314         if(!jni_remoteAddress)
1315         {
1316             OIC_LOG(DEBUG, TAG, "[EDR][Native] jni_remoteAddress is null");
1317             continue;
1318         }
1319         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1320
1321         if(!strcmp(setAddress, remoteAddress))
1322         {
1323             OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress);
1324             (*env)->DeleteGlobalRef(env, jarrayObj);
1325
1326             CAEDRReorderingDeviceSocketList(index);
1327             break;
1328         }
1329     }
1330     u_mutex_unlock(g_mutexSocketListManager);
1331
1332     OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
1333     return;
1334 }
1335
1336 jobject CAEDRNativeGetDeviceSocket(uint32_t idx)
1337 {
1338     OIC_LOG(DEBUG, TAG, "CAEDRNativeGetDeviceSocket");
1339
1340     if(idx < 0)
1341     {
1342         OIC_LOG(DEBUG, TAG, "[EDR][Native] index is not available");
1343         return NULL;
1344     }
1345
1346     if(!g_deviceObjectList)
1347     {
1348         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1349         return NULL;
1350     }
1351
1352     jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, idx);
1353     if(!jarrayObj)
1354     {
1355         OIC_LOG(ERROR, TAG, "[EDR][Native] jarrayObj is not available");
1356         return NULL;
1357     }
1358     return jarrayObj;
1359 }
1360
1361 uint32_t CAEDRGetSocketListLength()
1362 {
1363     if(!g_deviceObjectList)
1364     {
1365         OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceObjectList is null");
1366         return 0;
1367     }
1368
1369     uint32_t length = u_arraylist_length(g_deviceObjectList);
1370
1371     return length;
1372 }
1373
1374 void CAEDRReorderingDeviceSocketList(uint32_t index)
1375 {
1376     if (index >= g_deviceObjectList->length)
1377     {
1378         return;
1379     }
1380
1381     if (index < g_deviceObjectList->length - 1)
1382     {
1383         memmove(&g_deviceObjectList->data[index], &g_deviceObjectList->data[index + 1],
1384                 (g_deviceObjectList->length - index - 1) * sizeof(void *));
1385     }
1386
1387     g_deviceObjectList->size--;
1388     g_deviceObjectList->length--;
1389 }
1390
1391 void CAEDRInitializeClient(u_thread_pool_t handle)
1392 {
1393     OIC_LOG(DEBUG, TAG, "IN");
1394     CAEDRInitialize(handle);
1395     OIC_LOG(DEBUG, TAG, "OUT");
1396 }
1397
1398