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