Merge branch 'master' into resource-manipulation
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / caleserver.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 <jni.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <android/log.h>
25 #include <unistd.h>
26 #include "caleserver.h"
27 #include "caleutils.h"
28 #include "caleinterface.h"
29 #include "caadapterutils.h"
30
31 #include "logger.h"
32 #include "oic_malloc.h"
33 #include "cathreadpool.h"
34 #include "camutex.h"
35 #include "uarraylist.h"
36 #include "org_iotivity_ca_CaLeServerInterface.h"
37
38 #define TAG PCF("CA_LE_SERVER")
39
40 static JavaVM *g_jvm = NULL;
41 static jobject g_context = NULL;
42 static jobject g_bluetoothGattServer = NULL;
43 static jobject g_bluetoothGattServerCallback = NULL;
44 static jobject g_leAdvertiseCallback = NULL;
45
46 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
47 static CABLEErrorHandleCallback g_serverErrorCallback;
48
49 static u_arraylist_t *g_connectedDeviceList = NULL;
50 static ca_thread_pool_t g_threadPoolHandle = NULL;
51
52 static bool g_isStartServer = false;
53 static bool g_isInitializedServer = false;
54
55 static CABLEServerDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
56 static ca_mutex g_bleReqRespCbMutex = NULL;
57 static ca_mutex g_bleClientBDAddressMutex = NULL;
58 static ca_mutex g_connectedDeviceListMutex = NULL;
59
60 void CALEServerJNISetContext()
61 {
62     OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
63     g_context = (jobject) CANativeJNIGetContext();
64 }
65
66 void CALeServerJniInit()
67 {
68     OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
69     g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
70 }
71
72 CAResult_t CALEServerCreateJniInterfaceObject()
73 {
74     OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
75
76     if (!g_context)
77     {
78         OIC_LOG(ERROR, TAG, "g_context is null");
79         return CA_STATUS_FAILED;
80     }
81
82     if (!g_jvm)
83     {
84         OIC_LOG(ERROR, TAG, "g_jvm is null");
85         return CA_STATUS_FAILED;
86     }
87
88     bool isAttached = false;
89     JNIEnv* env;
90     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
91     if (JNI_OK != res)
92     {
93         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
94         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
95
96         if (JNI_OK != res)
97         {
98             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
99             return CA_STATUS_FAILED;
100         }
101         isAttached = true;
102     }
103
104     jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
105     if (!jni_LEInterface)
106     {
107         OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
108         goto exit;
109     }
110
111     jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
112                                                                  "()V");
113     if (!LeInterfaceConstructorMethod)
114     {
115         OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
116         goto exit;
117     }
118
119     (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
120     OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
121
122     if (isAttached)
123     {
124         (*g_jvm)->DetachCurrentThread(g_jvm);
125     }
126
127     return CA_STATUS_OK;
128
129     exit:
130
131     if (isAttached)
132     {
133         (*g_jvm)->DetachCurrentThread(g_jvm);
134     }
135
136     return CA_STATUS_FAILED;
137 }
138
139 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
140 {
141     OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
142     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
143     VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
144
145     if (!g_bluetoothGattServer)
146     {
147         OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
148         return NULL;
149     }
150
151     if (!CALEIsEnableBTAdapter(env))
152     {
153         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
154         return NULL;
155     }
156
157     OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
158
159     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
160                                                            "android/bluetooth/BluetoothGattServer");
161     if (!jni_cid_bluetoothGattServer)
162     {
163         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
164         return NULL;
165     }
166
167     jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
168                                                             "BluetoothGattService");
169     if (!jni_cid_bluetoothGattService)
170     {
171         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
172         return NULL;
173     }
174
175     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
176                                                                    "BluetoothGattCharacteristic");
177     if (!jni_cid_bluetoothGattService)
178     {
179         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
180         return NULL;
181     }
182
183     jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
184                                                        "getService",
185                                                        "(Ljava/util/UUID;)Landroid/bluetooth/"
186                                                        "BluetoothGattService;");
187     if (!jni_cid_bluetoothGattService)
188     {
189         OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
190         return NULL;
191     }
192
193     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
194     if (!jni_obj_serviceUUID)
195     {
196         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
197         return NULL;
198     }
199
200     jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
201                                                                     jni_mid_getService,
202                                                                     jni_obj_serviceUUID);
203     if (!jni_obj_bluetoothGattService)
204     {
205         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
206         return NULL;
207     }
208
209     jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
210                                                               "getCharacteristic",
211                                                               "(Ljava/util/UUID;)"
212                                                               "Landroid/bluetooth/"
213                                                               "BluetoothGattCharacteristic;");
214     if (!jni_mid_getCharacteristic)
215     {
216         OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
217         return NULL;
218     }
219
220     jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
221                                                          OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
222     if (!jni_obj_responseUUID)
223     {
224         OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
225         return NULL;
226     }
227
228     jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
229             env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
230     if (!jni_obj_bluetoothGattCharacteristic)
231     {
232         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
233         return NULL;
234     }
235
236     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
237                                                      "setValue", "([B)Z");
238     if (!jni_mid_setValue)
239     {
240         OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
241         return NULL;
242     }
243
244     jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
245                                                               jni_obj_bluetoothGattCharacteristic,
246                                                               jni_mid_setValue, responseData);
247     if (JNI_FALSE == jni_boolean_setValue)
248     {
249         OIC_LOG(ERROR, TAG, "Fail to set response data");
250     }
251
252     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
253     return jni_obj_bluetoothGattCharacteristic;
254 }
255
256 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
257 {
258     OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponseData");
259     VERIFY_NON_NULL(responseData, TAG, "responseData is null");
260     VERIFY_NON_NULL(device, TAG, "device is null");
261     VERIFY_NON_NULL(env, TAG, "env is null");
262
263     if (!CALEIsEnableBTAdapter(env))
264     {
265         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
266         return CA_ADAPTER_NOT_ENABLED;
267     }
268
269     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
270                                                            "android/bluetooth/BluetoothGattServer");
271     if (!jni_cid_bluetoothGattServer)
272     {
273         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
274         return CA_STATUS_FAILED;
275     }
276
277     jmethodID jni_mid_notifyCharacteristicChanged = (*env)->GetMethodID(
278             env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
279             "(Landroid/bluetooth/BluetoothDevice;"
280             "Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
281     if (!jni_mid_notifyCharacteristicChanged)
282     {
283         OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
284         return CA_STATUS_FAILED;
285     }
286
287     jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
288             env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
289             JNI_FALSE);
290     if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
291     {
292         OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
293         return CA_SEND_FAILED;
294     }
295
296     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponseData");
297     return CA_STATUS_OK;
298 }
299
300 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
301                                         jint offset, jbyteArray value)
302 {
303     OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
304     VERIFY_NON_NULL(env, TAG, "env is null");
305     VERIFY_NON_NULL(device, TAG, "device is null");
306     VERIFY_NON_NULL(value, TAG, "value is null");
307
308     OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
309
310     if (!CALEIsEnableBTAdapter(env))
311     {
312         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
313         return CA_ADAPTER_NOT_ENABLED;
314     }
315
316     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
317                                                            "android/bluetooth/BluetoothGattServer");
318     if (!jni_cid_bluetoothGattServer)
319     {
320         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
321         return CA_STATUS_FAILED;
322     }
323
324     jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
325                                                          "sendResponse",
326                                                          "(Landroid/bluetooth/BluetoothDevice;"
327                                                          "III[B)Z");
328     if (!jni_mid_sendResponse)
329     {
330         OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
331         return CA_STATUS_FAILED;
332     }
333
334     jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
335                                                                   jni_mid_sendResponse, device,
336                                                                   requestId, status, offset,
337                                                                   value);
338     if (JNI_FALSE == jni_boolean_sendResponse)
339     {
340         OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
341         return CA_SEND_FAILED;
342     }
343
344     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
345     return CA_STATUS_OK;
346 }
347
348 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
349 {
350     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
351     VERIFY_NON_NULL(env, TAG, "env is null");
352     VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
353
354     if (!CALEIsEnableBTAdapter(env))
355     {
356         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
357         return CA_ADAPTER_NOT_ENABLED;
358     }
359
360     jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
361                                                          "android/bluetooth/le/"
362                                                          "AdvertiseSettings$Builder");
363     if (!jni_cid_AdvertiseSettings)
364     {
365         OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
366         return CA_STATUS_FAILED;
367     }
368
369     jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
370                                                               "<init>", "()V");
371     if (!jni_mid_AdvertiseSettings)
372     {
373         OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
374         return CA_STATUS_FAILED;
375     }
376
377     jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
378                                                       jni_mid_AdvertiseSettings);
379     if (!jni_AdvertiseSettings)
380     {
381         OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
382         return CA_STATUS_FAILED;
383     }
384
385     jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
386                                                              "setAdvertiseMode",
387                                                              "(I)Landroid/bluetooth/le/"
388                                                              "AdvertiseSettings$Builder;");
389     if (!jni_mid_setAdvertiseMode)
390     {
391         OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
392         return CA_STATUS_FAILED;
393     }
394
395     // 0: Low power, 1: Balanced
396     jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
397                                                                 jni_mid_setAdvertiseMode, 0);
398     if (!jni_obj_setAdvertiseMode)
399     {
400         OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
401         return CA_STATUS_FAILED;
402     }
403
404     jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
405                                                            "setConnectable",
406                                                            "(Z)Landroid/bluetooth/le/"
407                                                            "AdvertiseSettings$Builder;");
408     if (!jni_mid_setConnectable)
409     {
410         OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
411         return CA_STATUS_FAILED;
412     }
413
414     jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
415                                                               jni_mid_setConnectable, JNI_TRUE);
416     if (!jni_obj_setConnectable)
417     {
418         OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
419         return CA_STATUS_FAILED;
420     }
421
422     jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
423                                                        "(I)Landroid/bluetooth/le/"
424                                                        "AdvertiseSettings$Builder;");
425     if (!jni_mid_setTimeout)
426     {
427         OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
428         return CA_STATUS_FAILED;
429     }
430
431     //A value of 0 will disable the time limit
432     jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
433                                                           jni_mid_setTimeout, 0);
434     if (!jni_obj_setTimeout)
435     {
436         OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
437         return CA_STATUS_FAILED;
438     }
439
440     jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
441                                                             "android/bluetooth/le/"
442                                                             "AdvertiseData$Builder");
443     if (!jni_cid_AdvertiseDataBuilder)
444     {
445         OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
446         return CA_STATUS_FAILED;
447     }
448
449     jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
450                                                                  "<init>", "()V");
451     if (!jni_mid_AdvertiseDataBuilder)
452     {
453         OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
454         return CA_STATUS_FAILED;
455     }
456
457     jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
458                                                          jni_mid_AdvertiseDataBuilder);
459     if (!jni_AdvertiseDataBuilder)
460     {
461         OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
462         return CA_STATUS_FAILED;
463     }
464
465     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
466     if (!jni_obj_serviceUUID)
467     {
468         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
469         return CA_STATUS_FAILED;
470     }
471
472     jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
473     if (!jni_ParcelUuid)
474     {
475         OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
476         return CA_STATUS_FAILED;
477     }
478
479     jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
480                                                            "addServiceUuid",
481                                                            "(Landroid/os/ParcelUuid;)Landroid/"
482                                                            "bluetooth/le/AdvertiseData$Builder;");
483     if (!jni_mid_addServiceUuid)
484     {
485         OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
486         return CA_STATUS_FAILED;
487     }
488
489     jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
490                                                               jni_mid_addServiceUuid,
491                                                               jni_ParcelUuid);
492     if (!jni_obj_addServiceUuid)
493     {
494         OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
495         return CA_STATUS_FAILED;
496     }
497
498     jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
499     if (!jni_cid_BTAdapter)
500     {
501         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
502         return CA_STATUS_FAILED;
503     }
504
505     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
506                                                                     "getDefaultAdapter",
507                                                                     "()Landroid/bluetooth/"
508                                                                     "BluetoothAdapter;");
509     if (!jni_mid_getDefaultAdapter)
510     {
511         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
512         return CA_STATUS_FAILED;
513     }
514
515     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
516                                                                jni_mid_getDefaultAdapter);
517     if (!jni_obj_BTAdapter)
518     {
519         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
520         return CA_STATUS_FAILED;
521     }
522
523     jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
524                                                                      "getBluetoothLeAdvertiser",
525                                                                      "()Landroid/bluetooth/le/"
526                                                                      "BluetoothLeAdvertiser;");
527     if (!jni_mid_getBluetoothLeAdvertiser)
528     {
529         OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
530         return CA_STATUS_FAILED;
531     }
532
533     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
534             env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
535     if (!jni_obj_getBluetoothLeAdvertiser)
536     {
537         OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
538         return CA_STATUS_FAILED;
539     }
540
541     jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
542                                                                       jni_cid_AdvertiseSettings,
543                                                                       "build",
544                                                                       "()Landroid/bluetooth/le/"
545                                                                       "AdvertiseSettings;");
546     if (!jni_mid_build_LeAdvertiseSettings)
547     {
548         OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
549         return CA_STATUS_FAILED;
550     }
551
552     jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
553             env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
554     if (!jni_obj_build_LeAdvertiseSettings)
555     {
556         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
557         return CA_STATUS_FAILED;
558     }
559
560     jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
561                                                                   "build",
562                                                                   "()Landroid/bluetooth/le/"
563                                                                   "AdvertiseData;");
564     if (!jni_mid_build_LeAdvertiseData)
565     {
566         OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
567         return CA_STATUS_FAILED;
568     }
569
570     jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
571                                                                      jni_mid_build_LeAdvertiseData);
572     if (!jni_obj_build_LeAdvertiseData)
573     {
574         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
575         return CA_STATUS_FAILED;
576     }
577
578     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
579                                                     "android/bluetooth/le/BluetoothLeAdvertiser");
580     if (!jni_cid_leAdvertiser)
581     {
582         OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
583         return CA_STATUS_FAILED;
584     }
585
586     jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
587                                                              "startAdvertising",
588                                                              "(Landroid/bluetooth/le/"
589                                                              "AdvertiseSettings;Landroid/bluetooth/"
590                                                              "le/AdvertiseData;Landroid/bluetooth/"
591                                                              "le/AdvertiseCallback;)V");
592     if (!jni_mid_startAdvertising)
593     {
594         OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
595         return CA_STATUS_FAILED;
596     }
597
598     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
599                            jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
600                            advertiseCallback);
601
602     if ((*env)->ExceptionCheck(env))
603     {
604         OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
605         (*env)->ExceptionDescribe(env);
606         (*env)->ExceptionClear(env);
607         return CA_STATUS_FAILED;
608     }
609
610     OIC_LOG(DEBUG, TAG, "Advertising started!!");
611
612     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
613     return CA_STATUS_OK;
614 }
615
616 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
617 {
618     OIC_LOG(DEBUG, TAG, "IN - LEServerStopAdvertise");
619     VERIFY_NON_NULL(env, TAG, "env is null");
620     VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
621
622     if (!CALEIsEnableBTAdapter(env))
623     {
624         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
625         return CA_ADAPTER_NOT_ENABLED;
626     }
627
628     jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
629     if (!jni_cid_BTAdapter)
630     {
631         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
632         return CA_STATUS_FAILED;
633     }
634
635     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
636                                                     "android/bluetooth/le/BluetoothLeAdvertiser");
637     if (!jni_cid_leAdvertiser)
638     {
639         OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
640         return CA_STATUS_FAILED;
641     }
642
643     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
644                                                                     "getDefaultAdapter",
645                                                                     "()Landroid/bluetooth/"
646                                                                     "BluetoothAdapter;");
647     if (!jni_cid_leAdvertiser)
648     {
649         OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
650         return CA_STATUS_FAILED;
651     }
652
653     jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
654                                                                      "getBluetoothLeAdvertiser",
655                                                                      "()Landroid/bluetooth/le/"
656                                                                      "BluetoothLeAdvertiser;");
657     if (!jni_mid_getBTLeAdvertiser)
658     {
659         OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
660         return CA_STATUS_FAILED;
661     }
662
663     jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
664                                                             "stopAdvertising",
665                                                             "(Landroid/bluetooth/le/"
666                                                             "AdvertiseCallback;)V");
667     if (!jni_mid_stopAdvertising)
668     {
669         OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
670         return CA_STATUS_FAILED;
671     }
672
673     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
674                                                                jni_mid_getDefaultAdapter);
675     if (!jni_obj_BTAdapter)
676     {
677         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
678         return CA_STATUS_FAILED;
679     }
680
681     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
682                                                                         jni_mid_getBTLeAdvertiser);
683     if (!jni_obj_getBluetoothLeAdvertiser)
684     {
685         OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
686         return CA_STATUS_FAILED;
687     }
688
689     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
690                            advertiseCallback);
691     if ((*env)->ExceptionCheck(env))
692     {
693         OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
694         (*env)->ExceptionDescribe(env);
695         (*env)->ExceptionClear(env);
696         return CA_STATUS_FAILED;
697     }
698
699     OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
700
701     OIC_LOG(DEBUG, TAG, "OUT - LEServerStopAdvertise");
702     return CA_STATUS_OK;
703 }
704
705 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
706 {
707     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
708     VERIFY_NON_NULL(env, TAG, "env is null");
709     VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
710
711     if (!CALEIsEnableBTAdapter(env))
712     {
713         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
714         return CA_ADAPTER_NOT_ENABLED;
715     }
716
717     if (g_isStartServer)
718     {
719         OIC_LOG(DEBUG, TAG, "Gatt server already started");
720     }
721
722     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
723
724     // open gatt server
725     jobject bluetoothGattServer = CALEServerOpenGattServer(env);
726     if (!bluetoothGattServer)
727     {
728         OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
729         return CA_STATUS_FAILED;
730     }
731
732     g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
733     if (!g_bluetoothGattServer)
734     {
735         OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
736         return CA_STATUS_FAILED;
737     }
738
739     // create gatt service
740     jobject bluetoothGattService = CALEServerCreateGattService(env);
741     if (!bluetoothGattService)
742     {
743         OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
744         return CA_STATUS_FAILED;
745     }
746
747     // add gatt service
748     CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
749                                               bluetoothGattService);
750     if (CA_STATUS_OK != res)
751     {
752         OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
753     }
754     return res;
755 }
756
757 jobject CALEServerOpenGattServer(JNIEnv *env)
758 {
759     OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
760     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
761
762     if (!CALEIsEnableBTAdapter(env))
763     {
764         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
765         return NULL;
766     }
767
768     jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
769     if (!jni_cid_context)
770     {
771         OIC_LOG(ERROR, TAG, "jni_cid_context is null");
772         return NULL;
773     }
774
775     jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
776     if (!jni_cid_bluetoothManager)
777     {
778         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
779         return NULL;
780     }
781
782     jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
783                                                                  "BLUETOOTH_SERVICE",
784                                                                  "Ljava/lang/String;");
785     if (!jni_fid_bluetoothService)
786     {
787         OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
788         return NULL;
789     }
790
791     jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
792                                                              "getSystemService",
793                                                              "(Ljava/lang/String;)"
794                                                              "Ljava/lang/Object;");
795     if (!jni_mid_getSystemService)
796     {
797         OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
798         return NULL;
799     }
800
801     jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
802                                                            "openGattServer",
803                                                            "(Landroid/content/Context;"
804                                                            "Landroid/bluetooth/"
805                                                            "BluetoothGattServerCallback;)"
806                                                            "Landroid/bluetooth/"
807                                                            "BluetoothGattServer;");
808     if (!jni_mid_openGattServer)
809     {
810         OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
811         return NULL;
812     }
813
814     jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
815                                                                     jni_fid_bluetoothService);
816     if (!jni_obj_bluetoothService)
817     {
818         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
819         return NULL;
820     }
821
822     jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
823                                                                 jni_mid_getSystemService,
824                                                                 jni_obj_bluetoothService);
825     if (!jni_obj_bluetoothManager)
826     {
827         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
828         return NULL;
829     }
830
831     jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
832                                                                    jni_mid_openGattServer,
833                                                                    g_context,
834                                                                    g_bluetoothGattServerCallback);
835     if (!jni_obj_bluetoothGattServer)
836     {
837         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
838         return NULL;
839     }
840
841     OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
842     return jni_obj_bluetoothGattServer;
843 }
844
845 jobject CALEServerCreateGattService(JNIEnv *env)
846 {
847     OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
848     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
849
850     if (!CALEIsEnableBTAdapter(env))
851     {
852         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
853         return NULL;
854     }
855
856     jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
857                                                             "BluetoothGattService");
858     if (!jni_cid_bluetoothGattService)
859     {
860         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
861         return NULL;
862     }
863
864     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
865                                                                    "BluetoothGattCharacteristic");
866     if (!jni_cid_bluetoothGattCharacteristic)
867     {
868         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
869         return NULL;
870     }
871
872     jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
873                                                             "SERVICE_TYPE_PRIMARY", "I");
874     if (!jni_fid_serviceType)
875     {
876         OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
877         return NULL;
878     }
879
880     jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
881                                                                jni_cid_bluetoothGattCharacteristic,
882                                                                "PROPERTY_READ", "I");
883     if (!jni_fid_readProperties)
884     {
885         OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
886         return NULL;
887     }
888
889 #ifdef USE_PROPERTY_WRITE_RESPONSE
890     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
891                                                                 jni_cid_bluetoothGattCharacteristic,
892                                                                 "PROPERTY_WRITE", "I");
893 #else
894     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
895                                                                 jni_cid_bluetoothGattCharacteristic,
896                                                                 "PROPERTY_WRITE_NO_RESPONSE", "I");
897 #endif
898
899     if (!jni_fid_writeProperties)
900     {
901         OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
902         return NULL;
903     }
904
905     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
906                                                                 jni_cid_bluetoothGattCharacteristic,
907                                                                 "PERMISSION_READ", "I");
908     if (!jni_fid_readPermissions)
909     {
910         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
911         return NULL;
912     }
913
914     jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
915             env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
916     if (!jni_fid_writePermissions)
917     {
918         OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
919         return NULL;
920     }
921
922     jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
923                                                                  "<init>", "(Ljava/util/UUID;I)V");
924     if (!jni_mid_bluetoothGattService)
925     {
926         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
927         return NULL;
928     }
929
930     jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
931                                                               "addCharacteristic",
932                                                               "(Landroid/bluetooth/"
933                                                               "BluetoothGattCharacteristic;)Z");
934     if (!jni_mid_addCharacteristic)
935     {
936         OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
937         return NULL;
938     }
939
940     jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
941             env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
942     if (!jni_mid_bluetoothGattCharacteristic)
943     {
944         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
945         return NULL;
946     }
947
948     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
949     if (!jni_obj_serviceUUID)
950     {
951         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
952         return NULL;
953     }
954
955     jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
956                                                          jni_fid_serviceType);
957     jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
958                                                          jni_mid_bluetoothGattService,
959                                                          jni_obj_serviceUUID, jni_int_serviceType);
960     if (!jni_bluetoothGattService)
961     {
962         OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
963         return NULL;
964     }
965
966     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
967     if (!jni_obj_readUuid)
968     {
969         OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
970         return NULL;
971     }
972
973     jint jni_int_readProperties = (*env)->GetStaticIntField(env,
974                                                             jni_cid_bluetoothGattCharacteristic,
975                                                             jni_fid_readProperties);
976
977     jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
978                                                              jni_cid_bluetoothGattCharacteristic,
979                                                              jni_fid_readPermissions);
980
981     jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
982                                                        jni_mid_bluetoothGattCharacteristic,
983                                                        jni_obj_readUuid, jni_int_readProperties,
984                                                        jni_int_readPermissions);
985     if (!jni_readCharacteristic)
986     {
987         OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
988         return NULL;
989     }
990
991     CAResult_t res = CALEServerAddDescriptor(env, jni_readCharacteristic);
992     if (CA_STATUS_OK != res)
993     {
994         OIC_LOG(ERROR, TAG, "CALEServerAddDescriptor has failed");
995         return NULL;
996     }
997
998     jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
999             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1000     if (!jni_boolean_addReadCharacteristic)
1001     {
1002         OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1003         return NULL;
1004     }
1005
1006     jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1007     if (!jni_obj_writeUuid)
1008     {
1009         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1010         return NULL;
1011     }
1012
1013     jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1014                                                              jni_cid_bluetoothGattCharacteristic,
1015                                                              jni_fid_writeProperties);
1016
1017     jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1018                                                               jni_cid_bluetoothGattCharacteristic,
1019                                                               jni_fid_writePermissions);
1020
1021     jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1022                                                         jni_mid_bluetoothGattCharacteristic,
1023                                                         jni_obj_writeUuid, jni_int_writeProperties,
1024                                                         jni_int_writePermissions);
1025     if (!jni_writeCharacteristic)
1026     {
1027         OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1028         return NULL;
1029     }
1030
1031     jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1032             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1033     if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1034     {
1035         OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1036         return NULL;
1037     }
1038
1039     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1040     return jni_bluetoothGattService;
1041 }
1042
1043 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1044 {
1045     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDescriptor");
1046     VERIFY_NON_NULL(env, TAG, "env is null");
1047     VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1048
1049     jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1050                                                                "BluetoothGattDescriptor");
1051     if (!jni_cid_bluetoothGattDescriptor)
1052     {
1053         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1054         return CA_STATUS_FAILED;
1055     }
1056
1057     jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1058                                                                     jni_cid_bluetoothGattDescriptor,
1059                                                                     "<init>",
1060                                                                     "(Ljava/util/UUID;I)V");
1061     if (!jni_mid_bluetoothGattDescriptor)
1062     {
1063         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1064         return CA_STATUS_FAILED;
1065     }
1066
1067     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1068                                                                 jni_cid_bluetoothGattDescriptor,
1069                                                                 "PERMISSION_READ", "I");
1070     if (!jni_fid_readPermissions)
1071     {
1072         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1073         return CA_STATUS_FAILED;
1074     }
1075
1076     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1077     if (!jni_obj_readUuid)
1078     {
1079         OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1080         return CA_STATUS_FAILED;
1081     }
1082
1083     jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1084                                                              jni_fid_readPermissions);
1085
1086     OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1087
1088     jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1089                                                    jni_mid_bluetoothGattDescriptor,
1090                                                    jni_obj_readUuid, jni_int_readPermissions);
1091     if (!jni_readDescriptor)
1092     {
1093         OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1094         return CA_STATUS_FAILED;
1095     }
1096
1097     jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1098                                                           "BluetoothGattCharacteristic");
1099     if (!jni_cid_GattCharacteristic)
1100     {
1101         OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1102         return CA_STATUS_FAILED;
1103     }
1104
1105     jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1106                                                           "addDescriptor",
1107                                                           "(Landroid/bluetooth/"
1108                                                           "BluetoothGattDescriptor;)Z");
1109     if (!jni_mid_addDescriptor)
1110     {
1111         OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1112         return CA_STATUS_FAILED;
1113     }
1114
1115     jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1116                                                                    jni_mid_addDescriptor,
1117                                                                    jni_readDescriptor);
1118
1119     if (JNI_FALSE == jni_boolean_addDescriptor)
1120     {
1121         OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1122         return CA_STATUS_FAILED;
1123     }
1124     else
1125     {
1126         OIC_LOG(DEBUG, TAG, "addDescriptor success");
1127     }
1128
1129     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDescriptor");
1130     return CA_STATUS_OK;
1131 }
1132
1133 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1134                                           jobject bluetoothGattService)
1135 {
1136     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1137     VERIFY_NON_NULL(env, TAG, "env is null");
1138     VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1139     VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1140
1141     if (!CALEIsEnableBTAdapter(env))
1142     {
1143         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1144         return CA_ADAPTER_NOT_ENABLED;
1145     }
1146
1147     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1148                                                            "android/bluetooth/BluetoothGattServer");
1149     if (!jni_cid_bluetoothGattServer)
1150     {
1151         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1152         return CA_STATUS_FAILED;
1153     }
1154
1155     jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1156                                                        "addService",
1157                                                        "(Landroid/bluetooth/BluetoothGattService;)"
1158                                                        "Z");
1159     if (!jni_mid_addService)
1160     {
1161         OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1162         return CA_STATUS_FAILED;
1163     }
1164
1165     jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1166                                                                 jni_mid_addService,
1167                                                                 bluetoothGattService);
1168
1169     if (JNI_FALSE == jni_boolean_addService)
1170     {
1171         OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1172         return CA_STATUS_FAILED;
1173     }
1174
1175     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1176     return CA_STATUS_OK;
1177 }
1178
1179 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1180 {
1181     OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1182     VERIFY_NON_NULL(env, TAG, "env is null");
1183     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1184
1185     if (!CALEIsEnableBTAdapter(env))
1186     {
1187         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1188         return CA_ADAPTER_NOT_ENABLED;
1189     }
1190
1191     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1192                                                            "android/bluetooth/BluetoothGattServer");
1193     if (!jni_cid_bluetoothGattServer)
1194     {
1195         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1196         return CA_STATUS_FAILED;
1197     }
1198
1199     jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1200                                                     "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1201     if (!jni_mid_connect)
1202     {
1203         OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1204         return CA_STATUS_FAILED;
1205     }
1206
1207     jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1208                                                              jni_mid_connect, bluetoothDevice,
1209                                                              JNI_FALSE);
1210     if (JNI_FALSE == jni_boolean_connect)
1211     {
1212         OIC_LOG(ERROR, TAG, "Fail to connect");
1213         return CA_STATUS_FAILED;
1214     }
1215
1216     OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1217     return CA_STATUS_OK;
1218 }
1219
1220 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1221 {
1222     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1223     VERIFY_NON_NULL(env, TAG, "env is null");
1224
1225     ca_mutex_lock(g_connectedDeviceListMutex);
1226     if (!g_connectedDeviceList)
1227     {
1228         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1229         ca_mutex_unlock(g_connectedDeviceListMutex);
1230         return CA_STATUS_FAILED;
1231     }
1232
1233     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1234     for (uint32_t index = 0; index < length; index++)
1235     {
1236         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1237         if (!jarrayObj)
1238         {
1239             OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1240             continue;
1241         }
1242
1243         // disconnect for device obj
1244         CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1245         if (CA_STATUS_OK != res)
1246         {
1247             OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1248             continue;
1249         }
1250     }
1251
1252     ca_mutex_unlock(g_connectedDeviceListMutex);
1253     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1254     return CA_STATUS_OK;
1255 }
1256
1257 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1258 {
1259     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1260     VERIFY_NON_NULL(env, TAG, "env is null");
1261     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1262
1263     if (!CALEIsEnableBTAdapter(env))
1264     {
1265         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1266         return CA_ADAPTER_NOT_ENABLED;
1267     }
1268
1269     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1270                                                            "android/bluetooth/BluetoothGattServer");
1271     if (!jni_cid_bluetoothGattServer)
1272     {
1273         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1274         return CA_STATUS_FAILED;
1275     }
1276
1277     jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1278                                                              "cancelConnection",
1279                                                              "(Landroid/bluetooth/BluetoothDevice;)"
1280                                                              "V");
1281     if (!jni_mid_cancelConnection)
1282     {
1283         OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1284         return CA_STATUS_FAILED;
1285     }
1286
1287     (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1288
1289     if ((*env)->ExceptionCheck(env))
1290     {
1291         OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1292         (*env)->ExceptionDescribe(env);
1293         (*env)->ExceptionClear(env);
1294         return CA_STATUS_FAILED;
1295     }
1296
1297     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1298     return CA_STATUS_OK;
1299 }
1300
1301 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1302 {
1303     OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1304     VERIFY_NON_NULL(env, TAG, "env is null");
1305     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1306     VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1307
1308     if (!CALEIsEnableBTAdapter(env))
1309     {
1310         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1311         return CA_ADAPTER_NOT_ENABLED;
1312     }
1313
1314     jobject responseChar = CALEServerSetResponseData(env, responseData);
1315     if (!responseChar)
1316     {
1317         OIC_LOG(ERROR, TAG, "responseChar is null");
1318         return CA_STATUS_FAILED;
1319     }
1320
1321     CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1322     if (CA_STATUS_OK != result)
1323     {
1324         OIC_LOG(ERROR, TAG, "Fail to send response data");
1325         return result;
1326     }
1327
1328     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1329     return result;
1330 }
1331
1332 CAResult_t CALEServerInitialize(ca_thread_pool_t handle)
1333 {
1334     OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1335
1336     CALeServerJniInit();
1337
1338     if (!g_jvm)
1339     {
1340         OIC_LOG(ERROR, TAG, "g_jvm is null");
1341         return CA_STATUS_FAILED;
1342     }
1343
1344     bool isAttached = false;
1345     JNIEnv* env;
1346     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1347     if (JNI_OK != res)
1348     {
1349         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1350         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1351
1352         if (JNI_OK != res)
1353         {
1354             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1355             return CA_STATUS_FAILED;
1356         }
1357         isAttached = true;
1358     }
1359
1360     CAResult_t ret = CALECheckPlatformVersion(env, 21);
1361     if (CA_STATUS_OK != ret)
1362     {
1363         OIC_LOG(ERROR, TAG, "it is not supported");
1364
1365         if (isAttached)
1366         {
1367             (*g_jvm)->DetachCurrentThread(g_jvm);
1368         }
1369         return ret;
1370     }
1371
1372     g_threadPoolHandle = handle;
1373
1374     ret = CALEServerInitMutexVaraibles();
1375     if (CA_STATUS_OK != ret)
1376     {
1377         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1378
1379         if (isAttached)
1380         {
1381             (*g_jvm)->DetachCurrentThread(g_jvm);
1382         }
1383         return CA_STATUS_FAILED;
1384     }
1385
1386     CALEServerJNISetContext();
1387     CALEServerCreateCachedDeviceList();
1388
1389     ret = CALEServerCreateJniInterfaceObject();
1390     if (CA_STATUS_OK != ret)
1391     {
1392         OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1393
1394         if (isAttached)
1395         {
1396             (*g_jvm)->DetachCurrentThread(g_jvm);
1397         }
1398         return CA_STATUS_FAILED;
1399     }
1400
1401     if (isAttached)
1402     {
1403         (*g_jvm)->DetachCurrentThread(g_jvm);
1404     }
1405
1406     g_isInitializedServer = true;
1407     OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1408     return CA_STATUS_OK;
1409 }
1410
1411 void CALEServerTerminate()
1412 {
1413     OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1414
1415     if (!g_jvm)
1416     {
1417         OIC_LOG(ERROR, TAG, "g_jvm is null");
1418         return;
1419     }
1420
1421     bool isAttached = false;
1422     JNIEnv* env;
1423     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1424     if (JNI_OK != res)
1425     {
1426         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1427         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1428
1429         if (JNI_OK != res)
1430         {
1431             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1432             return;
1433         }
1434         isAttached = true;
1435     }
1436
1437     CAResult_t ret = CALEServerStopMulticastServer(0);
1438     if (CA_STATUS_OK != ret)
1439     {
1440         OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
1441     }
1442
1443     ret = CALEServerDisconnectAllDevices(env);
1444     if (CA_STATUS_OK != ret)
1445     {
1446         OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
1447     }
1448
1449     ret = CALEServerRemoveAllDevices(env);
1450     if (CA_STATUS_OK != ret)
1451     {
1452         OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
1453     }
1454
1455     if (g_leAdvertiseCallback)
1456     {
1457         (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
1458     }
1459
1460     if (g_bluetoothGattServer)
1461     {
1462         (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
1463     }
1464
1465     if (g_bluetoothGattServerCallback)
1466     {
1467         (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
1468     }
1469
1470     CALEServerTerminateMutexVaraibles();
1471     CALEServerTerminateConditionVaraibles();
1472
1473     g_isStartServer = false;
1474     g_isInitializedServer = false;
1475
1476     if (isAttached)
1477     {
1478         (*g_jvm)->DetachCurrentThread(g_jvm);
1479     }
1480
1481     OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1482 }
1483
1484 CAResult_t CALEServerSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
1485 {
1486     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessage(%s, %s)", address, data);
1487     VERIFY_NON_NULL(address, TAG, "address is null");
1488     VERIFY_NON_NULL(data, TAG, "data is null");
1489
1490     if (!g_jvm)
1491     {
1492         OIC_LOG(ERROR, TAG, "g_jvm is null");
1493         return CA_STATUS_FAILED;
1494     }
1495
1496     bool isAttached = false;
1497     JNIEnv* env;
1498     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1499     if (JNI_OK != res)
1500     {
1501         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1502         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1503
1504         if (JNI_OK != res)
1505         {
1506             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1507             return CA_STATUS_FAILED;
1508         }
1509         isAttached = true;
1510     }
1511
1512     CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1513     if (CA_STATUS_OK != ret)
1514     {
1515         OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1516     }
1517
1518     if (isAttached)
1519     {
1520         (*g_jvm)->DetachCurrentThread(g_jvm);
1521     }
1522
1523     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessage");
1524     return ret;
1525 }
1526
1527 CAResult_t CALEServerSendMulticastMessage(const char* data, uint32_t dataLen)
1528 {
1529     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessage(%s)", data);
1530     VERIFY_NON_NULL(data, TAG, "data is null");
1531
1532     if (!g_jvm)
1533     {
1534         OIC_LOG(ERROR, TAG, "g_jvm is null");
1535         return CA_STATUS_FAILED;
1536     }
1537
1538     bool isAttached = false;
1539     JNIEnv* env;
1540     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1541     if (JNI_OK != res)
1542     {
1543         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1544         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1545
1546         if (JNI_OK != res)
1547         {
1548             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1549             return CA_STATUS_FAILED;
1550         }
1551         isAttached = true;
1552     }
1553
1554     CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1555     if (CA_STATUS_OK != ret)
1556     {
1557         OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1558     }
1559
1560     if (isAttached)
1561     {
1562         (*g_jvm)->DetachCurrentThread(g_jvm);
1563     }
1564
1565     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessage");
1566     return ret;
1567 }
1568
1569 CAResult_t CALEServerStartMulticastServer()
1570 {
1571     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1572
1573     if (!g_isInitializedServer)
1574     {
1575         OIC_LOG(INFO, TAG, "server is not initialized");
1576         return CA_STATUS_FAILED;
1577     }
1578
1579     if (g_isStartServer)
1580     {
1581         OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1582         return CA_STATUS_FAILED;
1583     }
1584
1585     if (!g_jvm)
1586     {
1587         OIC_LOG(ERROR, TAG, "g_jvm is null");
1588         return CA_STATUS_FAILED;
1589     }
1590
1591     bool isAttached = false;
1592     JNIEnv* env;
1593     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1594     if (JNI_OK != res)
1595     {
1596         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1597         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1598
1599         if (JNI_OK != res)
1600         {
1601             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1602             return CA_STATUS_FAILED;
1603         }
1604         isAttached = true;
1605     }
1606
1607     g_isStartServer = true;
1608
1609     // start gatt server
1610     CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1611     if (CA_STATUS_OK != ret)
1612     {
1613         OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1614         return ret;
1615     }
1616
1617     // start advertise
1618     ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1619     if (CA_STATUS_OK != ret)
1620     {
1621         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1622     }
1623
1624     if (isAttached)
1625     {
1626         (*g_jvm)->DetachCurrentThread(g_jvm);
1627     }
1628
1629     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1630     return ret;
1631 }
1632
1633 CAResult_t CALEServerStopMulticastServer()
1634 {
1635     OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1636
1637     if (false == g_isStartServer)
1638     {
1639         OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1640         return CA_STATUS_FAILED;
1641     }
1642
1643     if (!g_jvm)
1644     {
1645         OIC_LOG(ERROR, TAG, "g_jvm is null");
1646         return CA_STATUS_FAILED;
1647     }
1648
1649     bool isAttached = false;
1650     JNIEnv* env;
1651     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1652     if (JNI_OK != res)
1653     {
1654         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1655         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1656
1657         if (JNI_OK != res)
1658         {
1659             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1660             return CA_STATUS_FAILED;
1661         }
1662         isAttached = true;
1663     }
1664
1665     CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1666     if (CA_STATUS_OK != ret)
1667     {
1668         OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1669     }
1670
1671     g_isStartServer = false;
1672
1673     if (isAttached)
1674     {
1675         (*g_jvm)->DetachCurrentThread(g_jvm);
1676     }
1677
1678     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1679     return ret;
1680 }
1681
1682 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1683 {
1684     OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1685     g_packetReceiveCallback = callback;
1686 }
1687
1688 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const char* data,
1689                                             uint32_t dataLen)
1690 {
1691     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessageImpl, address: %s, data: %s",
1692             address, data);
1693     VERIFY_NON_NULL(env, TAG, "env is null");
1694     VERIFY_NON_NULL(address, TAG, "address is null");
1695     VERIFY_NON_NULL(data, TAG, "data is null");
1696
1697     if (!g_connectedDeviceList)
1698     {
1699         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1700         return CA_STATUS_FAILED;
1701     }
1702
1703     jobject jni_obj_bluetoothDevice = NULL;
1704     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1705     for (uint32_t index = 0; index < length; index++)
1706     {
1707         OIC_LOG(DEBUG, TAG, "check device address");
1708         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1709         if (!jarrayObj)
1710         {
1711             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1712             return CA_STATUS_FAILED;
1713         }
1714
1715         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1716         if (!jni_setAddress)
1717         {
1718             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1719             return CA_STATUS_FAILED;
1720         }
1721         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1722         if (!setAddress)
1723         {
1724             OIC_LOG(ERROR, TAG, "setAddress is null");
1725             return CA_STATUS_FAILED;
1726         }
1727
1728         OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1729         OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1730
1731         if (!strcmp(setAddress, address))
1732         {
1733             OIC_LOG(DEBUG, TAG, "found the device");
1734             jni_obj_bluetoothDevice = jarrayObj;
1735             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1736             break;
1737         }
1738         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1739     }
1740
1741     if (jni_obj_bluetoothDevice)
1742     {
1743         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1744         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1745
1746         CAResult_t res = CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
1747         if (CA_STATUS_OK != res)
1748         {
1749             OIC_LOG(ERROR, TAG, "send has failed");
1750             return CA_SEND_FAILED;
1751         }
1752     }
1753     else
1754     {
1755         OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1756         return CA_STATUS_FAILED;
1757     }
1758
1759     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessageImpl");
1760     return CA_STATUS_OK;
1761 }
1762
1763 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen)
1764 {
1765     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1766     VERIFY_NON_NULL(env, TAG, "env is null");
1767     VERIFY_NON_NULL(data, TAG, "data is null");
1768
1769     if (!g_connectedDeviceList)
1770     {
1771         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1772         return CA_STATUS_FAILED;
1773     }
1774
1775     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1776     for (uint32_t index = 0; index < length; index++)
1777     {
1778         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1779         if (!jarrayObj)
1780         {
1781             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1782             return CA_STATUS_FAILED;
1783         }
1784
1785         // send data for all device
1786         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1787         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1788         CAResult_t res = CALEServerSend(env, jarrayObj, jni_bytearr_data);
1789         if (CA_STATUS_OK != res)
1790         {
1791             OIC_LOG(ERROR, TAG, "send has failed");
1792             return CA_SEND_FAILED;
1793         }
1794     }
1795
1796     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessageImpl");
1797     return CA_STATUS_OK;
1798 }
1799
1800 void CALEServerCreateCachedDeviceList()
1801 {
1802     OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateCachedDeviceList");
1803
1804     ca_mutex_lock(g_connectedDeviceListMutex);
1805     // create new object array
1806     if (!g_connectedDeviceList)
1807     {
1808         OIC_LOG(DEBUG, TAG, "Create device list");
1809         g_connectedDeviceList = u_arraylist_create();
1810     }
1811     ca_mutex_unlock(g_connectedDeviceListMutex);
1812
1813     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
1814 }
1815
1816 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1817 {
1818     OIC_LOG(DEBUG, TAG, "IN - CALEServerIsDeviceInList");
1819     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1820     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1821
1822     if (!g_connectedDeviceList)
1823     {
1824         OIC_LOG(ERROR, TAG, "list is null");
1825         return false;
1826     }
1827
1828     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1829     for (uint32_t index = 0; index < length; index++)
1830     {
1831         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1832
1833         if (!jarrayObj)
1834         {
1835             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1836             return false;
1837         }
1838
1839         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1840         if (!jni_setAddress)
1841         {
1842             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1843             return false;
1844         }
1845
1846         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1847         if (!setAddress)
1848         {
1849             OIC_LOG(ERROR, TAG, "setAddress is null");
1850             return false;
1851         }
1852
1853         if (!strcmp(remoteAddress, setAddress))
1854         {
1855             OIC_LOG(ERROR, TAG, "the device is already set");
1856             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1857             return true;
1858         }
1859         else
1860         {
1861             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1862             continue;
1863         }
1864     }
1865
1866     OIC_LOG(DEBUG, TAG, "there are no device in the list");
1867     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
1868     return false;
1869 }
1870
1871 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1872 {
1873     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
1874     VERIFY_NON_NULL(device, TAG, "device is null");
1875     VERIFY_NON_NULL(env, TAG, "env is null");
1876
1877     ca_mutex_lock(g_connectedDeviceListMutex);
1878
1879     if (!g_connectedDeviceList)
1880     {
1881         OIC_LOG(ERROR, TAG, "list is null");
1882         ca_mutex_unlock(g_connectedDeviceListMutex);
1883         return CA_STATUS_FAILED;
1884     }
1885
1886     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1887     if (!jni_remoteAddress)
1888     {
1889         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
1890         ca_mutex_unlock(g_connectedDeviceListMutex);
1891         return CA_STATUS_FAILED;
1892     }
1893
1894     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1895     if (!remoteAddress)
1896     {
1897         OIC_LOG(ERROR, TAG, "remoteAddress is null");
1898         ca_mutex_unlock(g_connectedDeviceListMutex);
1899         return CA_STATUS_FAILED;
1900     }
1901
1902     if (false == CALEServerIsDeviceInList(env, remoteAddress))
1903     {
1904         jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
1905         u_arraylist_add(g_connectedDeviceList, jni_obj_device);
1906         OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
1907     }
1908
1909     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
1910     ca_mutex_unlock(g_connectedDeviceListMutex);
1911     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
1912     return CA_STATUS_OK;
1913 }
1914
1915 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
1916 {
1917     OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
1918     VERIFY_NON_NULL(env, TAG, "env is null");
1919
1920     ca_mutex_lock(g_connectedDeviceListMutex);
1921     if (!g_connectedDeviceList)
1922     {
1923         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1924         ca_mutex_unlock(g_connectedDeviceListMutex);
1925         return CA_STATUS_FAILED;
1926     }
1927
1928     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1929     for (uint32_t index = 0; index < length; index++)
1930     {
1931         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1932         if (jarrayObj)
1933         {
1934             (*env)->DeleteGlobalRef(env, jarrayObj);
1935         }
1936     }
1937
1938     OICFree(g_connectedDeviceList);
1939     g_connectedDeviceList = NULL;
1940     ca_mutex_unlock(g_connectedDeviceListMutex);
1941
1942     OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
1943     return CA_STATUS_OK;
1944 }
1945
1946 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
1947 {
1948     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
1949     VERIFY_NON_NULL(env, TAG, "env is null");
1950     VERIFY_NON_NULL(address, TAG, "address is null");
1951
1952     ca_mutex_lock(g_connectedDeviceListMutex);
1953     if (!g_connectedDeviceList)
1954     {
1955         OIC_LOG(ERROR, TAG, "no deviceList");
1956         ca_mutex_unlock(g_connectedDeviceListMutex);
1957         return CA_STATUS_FAILED;
1958     }
1959
1960     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1961     for (uint32_t index = 0; index < length; index++)
1962     {
1963         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1964
1965         if (jarrayObj)
1966         {
1967             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1968             if (!jni_setAddress)
1969             {
1970                 OIC_LOG(ERROR, TAG, "wrong device address");
1971                 continue;
1972             }
1973             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1974             if (!setAddress)
1975             {
1976                 OIC_LOG(ERROR, TAG, "setAddress is null");
1977                 continue;
1978             }
1979
1980             const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
1981             if (!remoteAddress)
1982             {
1983                 OIC_LOG(ERROR, TAG, "remoteAddress is null");
1984                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1985                 continue;
1986             }
1987
1988             if (!strcmp(setAddress, remoteAddress))
1989             {
1990                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
1991
1992                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1993                 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
1994                 (*env)->DeleteGlobalRef(env, jarrayObj);
1995
1996                 CAResult_t res = CALEServerReorderinglist(index);
1997                 if (CA_STATUS_OK != res)
1998                 {
1999                     OIC_LOG(ERROR, TAG, "CALEServerReorderinglist has failed");
2000                     ca_mutex_unlock(g_connectedDeviceListMutex);
2001                     return res;
2002                 }
2003                 ca_mutex_unlock(g_connectedDeviceListMutex);
2004                 return CA_STATUS_OK;
2005             }
2006             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2007             (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2008         }
2009     }
2010
2011     ca_mutex_unlock(g_connectedDeviceListMutex);
2012
2013     OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2014
2015     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2016     return CA_STATUS_FAILED;
2017 }
2018
2019 CAResult_t CALEServerReorderinglist(uint32_t index)
2020 {
2021     if (!g_connectedDeviceList)
2022     {
2023         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2024         return CA_STATUS_FAILED;
2025     }
2026
2027     if (index >= g_connectedDeviceList->length)
2028     {
2029         OIC_LOG(ERROR, TAG, "index is not available");
2030         return CA_STATUS_FAILED;
2031     }
2032
2033     if (index < g_connectedDeviceList->length - 1)
2034     {
2035         memmove(&g_connectedDeviceList->data[index], &g_connectedDeviceList->data[index + 1],
2036                 (g_connectedDeviceList->length - index - 1) * sizeof(void *));
2037     }
2038
2039     g_connectedDeviceList->size--;
2040     g_connectedDeviceList->length--;
2041
2042     return CA_STATUS_OK;
2043 }
2044
2045 JNIEXPORT void JNICALL
2046 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2047                                                                          jobject callback)
2048 {
2049     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Gatt Server Callback");
2050     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2051     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
2052
2053     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2054 }
2055
2056 JNIEXPORT void JNICALL
2057 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2058                                                                                   jobject obj,
2059                                                                                   jobject callback)
2060 {
2061     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Advertise Callback");
2062     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2063     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
2064
2065     g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2066 }
2067
2068 JNIEXPORT void JNICALL
2069 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2070         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2071 {
2072     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server ConnectionStateChange Callback");
2073     OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2074
2075     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2076     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2077
2078     jclass jni_cid_bluetoothProfile = (*env)->FindClass(env, "android/bluetooth/BluetoothProfile");
2079     if (!jni_cid_bluetoothProfile)
2080     {
2081         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothProfile is null");
2082         return;
2083     }
2084
2085     jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
2086                                                                 "STATE_CONNECTED", "I");
2087     if(!jni_fid_state_connected)
2088     {
2089         OIC_LOG(ERROR, TAG, "jni_fid_state_connected is null");
2090         return;
2091     }
2092
2093     jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
2094                                                                    "STATE_DISCONNECTED", "I");
2095     if(!jni_fid_state_disconnected)
2096     {
2097         OIC_LOG(ERROR, TAG, "jni_fid_state_disconnected is null");
2098         return;
2099     }
2100
2101     // STATE_CONNECTED
2102     jint jni_int_state_connected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
2103                                                              jni_fid_state_connected);
2104
2105     // STATE_DISCONNECTED
2106     jint jni_int_state_disconnected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
2107                                                                 jni_fid_state_disconnected);
2108
2109     if (newState == jni_int_state_connected)
2110     {
2111
2112         OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2113
2114         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2115         if (!jni_remoteAddress)
2116         {
2117             OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2118             return;
2119         }
2120
2121         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2122         if (!remoteAddress)
2123         {
2124             OIC_LOG(ERROR, TAG, "remoteAddress is null");
2125             return;
2126         }
2127
2128         if (false == CALEServerIsDeviceInList(env, remoteAddress))
2129         {
2130             OIC_LOG(DEBUG, TAG, "add connected device to cache");
2131             CALEServerAddDeviceToList(env, device);
2132         }
2133         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2134     }
2135     else if (newState == jni_int_state_disconnected)
2136     {
2137         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2138     }
2139     else
2140     {
2141         OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2142                 status);
2143     }
2144 }
2145
2146 JNIEXPORT void JNICALL
2147 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2148                                                                              jobject obj,
2149                                                                              jint status,
2150                                                                              jobject gattService)
2151 {
2152     OIC_LOG_V(DEBUG, TAG, "CaLeServerInterface - Gatt Service Added Callback(%d)", status);
2153 }
2154
2155 JNIEXPORT void JNICALL
2156 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2157         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset,
2158         jobject characteristic, jbyteArray data)
2159 {
2160     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Read Request Callback");
2161     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2162     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2163
2164 #ifdef USE_PROPERTY_WRITE_RESPONSE
2165     CALEServerSendResponse(env, device, requestId, 0, offset, NULL);
2166 #endif
2167
2168 }
2169
2170 JNIEXPORT void JNICALL
2171 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2172         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic,
2173         jbyteArray data, jboolean preparedWrite, jboolean responseNeeded, jint offset,
2174         jbyteArray value)
2175 {
2176     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Write Request Callback");
2177     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2178     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2179     VERIFY_NON_NULL_VOID(value, TAG, "value is null");
2180     VERIFY_NON_NULL_VOID(data, TAG, "data is null");
2181
2182 #ifdef USE_PROPERTY_WRITE_RESPONSE
2183     CALEServerSendResponse(env, device, requestId, 0, offset, value);
2184 #endif
2185
2186     // get Byte Array and covert to char*
2187     jint length = (*env)->GetArrayLength(env, data);
2188
2189     jboolean isCopy;
2190     jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2191
2192     char* requestData = NULL;
2193     requestData = (char*) OICMalloc(sizeof(char) * length + 1);
2194     if (!requestData)
2195     {
2196         OIC_LOG(ERROR, TAG, "requestData is null");
2197         return;
2198     }
2199
2200     memcpy(requestData, (const char*) jni_byte_requestData, length);
2201     requestData[length] = '\0';
2202     (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2203
2204     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2205     if (!jni_address)
2206     {
2207         OIC_LOG(ERROR, TAG, "jni_address is null");
2208         OICFree(requestData);
2209         return;
2210     }
2211
2212     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2213     if (!address)
2214     {
2215         OIC_LOG(ERROR, TAG, "address is null");
2216         OICFree(requestData);
2217         return;
2218     }
2219
2220     OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %s, %d", address, requestData, length);
2221
2222     ca_mutex_lock(g_bleClientBDAddressMutex);
2223     uint32_t sentLength = 0;
2224     g_CABLEServerDataReceivedCallback(address, OIC_GATT_SERVICE_UUID, requestData, length,
2225                                       &sentLength);
2226     ca_mutex_unlock(g_bleClientBDAddressMutex);
2227
2228     (*env)->ReleaseStringUTFChars(env, jni_address, address);
2229 }
2230
2231 JNIEXPORT void JNICALL
2232 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorReadRequestCallback(
2233         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
2234 {
2235     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorReadRequestCallback");
2236 }
2237
2238 JNIEXPORT void JNICALL
2239 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorWriteRequestCallback(
2240         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
2241         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
2242 {
2243     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorWriteRequestCallback");
2244 }
2245
2246 JNIEXPORT void JNICALL
2247 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerExecuteWriteCallback(JNIEnv *env,
2248                                                                              jobject obj,
2249                                                                              jobject device,
2250                                                                              jint requestId,
2251                                                                              jboolean execute)
2252 {
2253     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerExecuteWriteCallback");
2254     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2255     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2256
2257 //    CALEServerSendResponse(env, device, requestId, 0, 0, NULL);
2258 }
2259
2260 JNIEXPORT void JNICALL
2261 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2262                                                                                  jobject obj,
2263                                                                                  jobject device,
2264                                                                                  jint status)
2265 {
2266     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Notification Sent Callback");
2267 }
2268
2269 JNIEXPORT void JNICALL
2270 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(
2271         JNIEnv *env, jobject obj, jobject settingsInEffect)
2272 {
2273     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - LE Advertise Start Success Callback");
2274 }
2275
2276 JNIEXPORT void JNICALL
2277 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2278                                                                             jobject obj,
2279                                                                             jint errorCode)
2280 {
2281     OIC_LOG_V(ERROR, TAG, "CaLeServerInterface - LE Advertise Start Failure Callback(%)",
2282               errorCode);
2283 }
2284
2285 /**
2286  * adapter common
2287  */
2288
2289 CAResult_t CAStartLEGattServer()
2290 {
2291     OIC_LOG(DEBUG, TAG, "IN");
2292
2293     CAResult_t ret = CALEServerInitMutexVaraibles();
2294     if (CA_STATUS_OK != ret)
2295     {
2296         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed!");
2297         CALEServerTerminateMutexVaraibles();
2298         return CA_SERVER_NOT_STARTED;
2299     }
2300
2301     ret = CALEServerInitConditionVaraibles();
2302     if (CA_STATUS_OK != ret)
2303     {
2304         OIC_LOG(ERROR, TAG, "CALEServerInitConditionVaraibles has failed!");
2305         CALEServerTerminateConditionVaraibles();
2306         return CA_SERVER_NOT_STARTED;
2307     }
2308
2309     // start gatt service
2310     CALEServerStartMulticastServer();
2311
2312     OIC_LOG(DEBUG, TAG, "OUT");
2313     return CA_STATUS_OK;
2314 }
2315
2316 CAResult_t CAStopLEGattServer()
2317 {
2318     OIC_LOG(DEBUG, TAG, "IN");
2319
2320     OIC_LOG(DEBUG, TAG, "OUT");
2321     return CA_STATUS_OK;
2322 }
2323
2324 void CATerminateLEGattServer()
2325 {
2326     OIC_LOG(DEBUG, TAG, "IN");
2327
2328     OIC_LOG(DEBUG, TAG, "Terminat Gatt Server");
2329     CALEServerTerminate();
2330
2331     OIC_LOG(DEBUG, TAG, "OUT");
2332 }
2333
2334 void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
2335 {
2336     OIC_LOG(DEBUG, TAG, "IN");
2337
2338     ca_mutex_lock(g_bleReqRespCbMutex);
2339     g_CABLEServerDataReceivedCallback = callback;
2340     ca_mutex_unlock(g_bleReqRespCbMutex);
2341
2342     OIC_LOG(DEBUG, TAG, "OUT");
2343 }
2344
2345 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2346 {
2347     g_serverErrorCallback = callback;
2348 }
2349
2350 CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *charValue,
2351                                                const uint32_t charValueLen)
2352 {
2353     CAResult_t result = CA_SEND_FAILED;
2354     OIC_LOG(DEBUG, TAG, "IN");
2355     VERIFY_NON_NULL(address, TAG, "env is null");
2356     VERIFY_NON_NULL(charValue, TAG, "device is null");
2357
2358     if (address)
2359     {
2360         OIC_LOG(DEBUG, TAG, "CALEServerSendUnicastData");
2361         result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2362     }
2363
2364     OIC_LOG(DEBUG, TAG, "OUT");
2365
2366     return result;
2367 }
2368
2369 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
2370                                                    uint32_t charValueLen)
2371 {
2372     OIC_LOG(DEBUG, TAG, "IN");
2373     VERIFY_NON_NULL(charValue, TAG, "device is null");
2374
2375     OIC_LOG(DEBUG, TAG, "CALEServerSendMulticastMessage");
2376     CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2377
2378     OIC_LOG(DEBUG, TAG, "OUT");
2379     return result;
2380 }
2381
2382 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2383 {
2384     OIC_LOG(DEBUG, TAG, "IN");
2385
2386     CALEServerInitialize(handle);
2387
2388     OIC_LOG(DEBUG, TAG, "OUT");
2389 }
2390
2391 CAResult_t CALEServerInitMutexVaraibles()
2392 {
2393     OIC_LOG(DEBUG, TAG, "IN");
2394     if (NULL == g_bleReqRespCbMutex)
2395     {
2396         g_bleReqRespCbMutex = ca_mutex_new();
2397         if (NULL == g_bleReqRespCbMutex)
2398         {
2399             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2400             return CA_STATUS_FAILED;
2401         }
2402     }
2403
2404     if (NULL == g_bleClientBDAddressMutex)
2405     {
2406         g_bleClientBDAddressMutex = ca_mutex_new();
2407         if (NULL == g_bleClientBDAddressMutex)
2408         {
2409             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2410             return CA_STATUS_FAILED;
2411         }
2412     }
2413
2414     if (NULL == g_connectedDeviceListMutex)
2415     {
2416         g_connectedDeviceListMutex = ca_mutex_new();
2417         if (NULL == g_connectedDeviceListMutex)
2418         {
2419             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2420             return CA_STATUS_FAILED;
2421         }
2422     }
2423
2424     OIC_LOG(DEBUG, TAG, "OUT");
2425     return CA_STATUS_OK;
2426 }
2427
2428 CAResult_t CALEServerInitConditionVaraibles()
2429 {
2430     OIC_LOG(DEBUG, TAG, "this method is not supported");
2431     return CA_STATUS_OK;
2432 }
2433
2434 void CALEServerTerminateMutexVaraibles()
2435 {
2436     OIC_LOG(DEBUG, TAG, "IN");
2437
2438     ca_mutex_free(g_bleReqRespCbMutex);
2439     g_bleReqRespCbMutex = NULL;
2440
2441     ca_mutex_free(g_bleClientBDAddressMutex);
2442     g_bleClientBDAddressMutex = NULL;
2443
2444     ca_mutex_free(g_connectedDeviceListMutex);
2445     g_connectedDeviceListMutex = NULL;
2446
2447     OIC_LOG(DEBUG, TAG, "OUT");
2448 }
2449
2450 void CALEServerTerminateConditionVaraibles()
2451 {
2452     OIC_LOG(DEBUG, TAG, "this method is not supported");
2453 }