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