Merge branch 'master' into 'security-CKM' branch.
[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 #ifdef USE_PROPERTY_WRITE_RESPONSE
890     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
891                                                                 jni_cid_bluetoothGattCharacteristic,
892                                                                 "PROPERTY_WRITE", "I");
893 #else
894     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
895                                                                 jni_cid_bluetoothGattCharacteristic,
896                                                                 "PROPERTY_WRITE_NO_RESPONSE", "I");
897 #endif
898
899     if (!jni_fid_writeProperties)
900     {
901         OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
902         return NULL;
903     }
904
905     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
906                                                                 jni_cid_bluetoothGattCharacteristic,
907                                                                 "PERMISSION_READ", "I");
908     if (!jni_fid_readPermissions)
909     {
910         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
911         return NULL;
912     }
913
914     jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
915             env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
916     if (!jni_fid_writePermissions)
917     {
918         OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
919         return NULL;
920     }
921
922     jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
923                                                                  "<init>", "(Ljava/util/UUID;I)V");
924     if (!jni_mid_bluetoothGattService)
925     {
926         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
927         return NULL;
928     }
929
930     jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
931                                                               "addCharacteristic",
932                                                               "(Landroid/bluetooth/"
933                                                               "BluetoothGattCharacteristic;)Z");
934     if (!jni_mid_addCharacteristic)
935     {
936         OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
937         return NULL;
938     }
939
940     jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
941             env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
942     if (!jni_mid_bluetoothGattCharacteristic)
943     {
944         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
945         return NULL;
946     }
947
948     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
949     if (!jni_obj_serviceUUID)
950     {
951         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
952         return NULL;
953     }
954
955     jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
956                                                          jni_fid_serviceType);
957     jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
958                                                          jni_mid_bluetoothGattService,
959                                                          jni_obj_serviceUUID, jni_int_serviceType);
960     if (!jni_bluetoothGattService)
961     {
962         OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
963         return NULL;
964     }
965
966     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
967     if (!jni_obj_readUuid)
968     {
969         OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
970         return NULL;
971     }
972
973     jint jni_int_readProperties = (*env)->GetStaticIntField(env,
974                                                             jni_cid_bluetoothGattCharacteristic,
975                                                             jni_fid_readProperties);
976
977     jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
978                                                              jni_cid_bluetoothGattCharacteristic,
979                                                              jni_fid_readPermissions);
980
981     jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
982                                                               jni_cid_bluetoothGattCharacteristic,
983                                                               jni_fid_writePermissions);
984
985     jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
986                                                        jni_mid_bluetoothGattCharacteristic,
987                                                        jni_obj_readUuid, jni_int_readProperties,
988                                                        jni_int_readPermissions|
989                                                        jni_int_writePermissions);
990     if (!jni_readCharacteristic)
991     {
992         OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
993         return NULL;
994     }
995
996     jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
997             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
998     if (!jni_boolean_addReadCharacteristic)
999     {
1000         OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1001         return NULL;
1002     }
1003
1004     jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1005     if (!jni_obj_writeUuid)
1006     {
1007         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1008         return NULL;
1009     }
1010
1011     jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1012                                                              jni_cid_bluetoothGattCharacteristic,
1013                                                              jni_fid_writeProperties);
1014
1015     jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1016                                                         jni_mid_bluetoothGattCharacteristic,
1017                                                         jni_obj_writeUuid, jni_int_writeProperties,
1018                                                         jni_int_writePermissions);
1019     if (!jni_writeCharacteristic)
1020     {
1021         OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1022         return NULL;
1023     }
1024
1025     jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1026             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1027     if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1028     {
1029         OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1030         return NULL;
1031     }
1032
1033     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1034     return jni_bluetoothGattService;
1035 }
1036
1037 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1038 {
1039     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDescriptor");
1040     VERIFY_NON_NULL(env, TAG, "env is null");
1041     VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1042
1043     jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1044                                                                "BluetoothGattDescriptor");
1045     if (!jni_cid_bluetoothGattDescriptor)
1046     {
1047         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1048         return CA_STATUS_FAILED;
1049     }
1050
1051     jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1052                                                                     jni_cid_bluetoothGattDescriptor,
1053                                                                     "<init>",
1054                                                                     "(Ljava/util/UUID;I)V");
1055     if (!jni_mid_bluetoothGattDescriptor)
1056     {
1057         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1058         return CA_STATUS_FAILED;
1059     }
1060
1061     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1062                                                                 jni_cid_bluetoothGattDescriptor,
1063                                                                 "PERMISSION_READ", "I");
1064     if (!jni_fid_readPermissions)
1065     {
1066         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1067         return CA_STATUS_FAILED;
1068     }
1069
1070     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1071     if (!jni_obj_readUuid)
1072     {
1073         OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1074         return CA_STATUS_FAILED;
1075     }
1076
1077     jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1078                                                              jni_fid_readPermissions);
1079
1080     OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1081
1082     jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1083                                                    jni_mid_bluetoothGattDescriptor,
1084                                                    jni_obj_readUuid, jni_int_readPermissions);
1085     if (!jni_readDescriptor)
1086     {
1087         OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1088         return CA_STATUS_FAILED;
1089     }
1090
1091     jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1092                                                           "BluetoothGattCharacteristic");
1093     if (!jni_cid_GattCharacteristic)
1094     {
1095         OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1096         return CA_STATUS_FAILED;
1097     }
1098
1099     jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1100                                                           "addDescriptor",
1101                                                           "(Landroid/bluetooth/"
1102                                                           "BluetoothGattDescriptor;)Z");
1103     if (!jni_mid_addDescriptor)
1104     {
1105         OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1106         return CA_STATUS_FAILED;
1107     }
1108
1109     jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1110                                                                    jni_mid_addDescriptor,
1111                                                                    jni_readDescriptor);
1112
1113     if (JNI_FALSE == jni_boolean_addDescriptor)
1114     {
1115         OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1116         return CA_STATUS_FAILED;
1117     }
1118     else
1119     {
1120         OIC_LOG(DEBUG, TAG, "addDescriptor success");
1121     }
1122
1123     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDescriptor");
1124     return CA_STATUS_OK;
1125 }
1126
1127 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1128                                           jobject bluetoothGattService)
1129 {
1130     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1131     VERIFY_NON_NULL(env, TAG, "env is null");
1132     VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1133     VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1134
1135     if (!CALEIsEnableBTAdapter(env))
1136     {
1137         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1138         return CA_ADAPTER_NOT_ENABLED;
1139     }
1140
1141     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1142                                                            "android/bluetooth/BluetoothGattServer");
1143     if (!jni_cid_bluetoothGattServer)
1144     {
1145         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1146         return CA_STATUS_FAILED;
1147     }
1148
1149     jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1150                                                        "addService",
1151                                                        "(Landroid/bluetooth/BluetoothGattService;)"
1152                                                        "Z");
1153     if (!jni_mid_addService)
1154     {
1155         OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1156         return CA_STATUS_FAILED;
1157     }
1158
1159     jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1160                                                                 jni_mid_addService,
1161                                                                 bluetoothGattService);
1162
1163     if (JNI_FALSE == jni_boolean_addService)
1164     {
1165         OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1166         return CA_STATUS_FAILED;
1167     }
1168
1169     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1170     return CA_STATUS_OK;
1171 }
1172
1173 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1174 {
1175     OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1176     VERIFY_NON_NULL(env, TAG, "env is null");
1177     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1178
1179     if (!CALEIsEnableBTAdapter(env))
1180     {
1181         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1182         return CA_ADAPTER_NOT_ENABLED;
1183     }
1184
1185     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1186                                                            "android/bluetooth/BluetoothGattServer");
1187     if (!jni_cid_bluetoothGattServer)
1188     {
1189         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1190         return CA_STATUS_FAILED;
1191     }
1192
1193     jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1194                                                     "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1195     if (!jni_mid_connect)
1196     {
1197         OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1198         return CA_STATUS_FAILED;
1199     }
1200
1201     jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1202                                                              jni_mid_connect, bluetoothDevice,
1203                                                              JNI_FALSE);
1204     if (JNI_FALSE == jni_boolean_connect)
1205     {
1206         OIC_LOG(ERROR, TAG, "Fail to connect");
1207         return CA_STATUS_FAILED;
1208     }
1209
1210     OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1211     return CA_STATUS_OK;
1212 }
1213
1214 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1215 {
1216     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1217     VERIFY_NON_NULL(env, TAG, "env is null");
1218
1219     ca_mutex_lock(g_connectedDeviceListMutex);
1220     if (!g_connectedDeviceList)
1221     {
1222         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1223         ca_mutex_unlock(g_connectedDeviceListMutex);
1224         return CA_STATUS_FAILED;
1225     }
1226
1227     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1228     for (uint32_t index = 0; index < length; index++)
1229     {
1230         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1231         if (!jarrayObj)
1232         {
1233             OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1234             continue;
1235         }
1236
1237         // disconnect for device obj
1238         CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1239         if (CA_STATUS_OK != res)
1240         {
1241             OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1242             continue;
1243         }
1244     }
1245
1246     ca_mutex_unlock(g_connectedDeviceListMutex);
1247     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1248     return CA_STATUS_OK;
1249 }
1250
1251 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1252 {
1253     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1254     VERIFY_NON_NULL(env, TAG, "env is null");
1255     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1256
1257     if (!CALEIsEnableBTAdapter(env))
1258     {
1259         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1260         return CA_ADAPTER_NOT_ENABLED;
1261     }
1262
1263     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1264                                                            "android/bluetooth/BluetoothGattServer");
1265     if (!jni_cid_bluetoothGattServer)
1266     {
1267         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1268         return CA_STATUS_FAILED;
1269     }
1270
1271     jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1272                                                              "cancelConnection",
1273                                                              "(Landroid/bluetooth/BluetoothDevice;)"
1274                                                              "V");
1275     if (!jni_mid_cancelConnection)
1276     {
1277         OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1278         return CA_STATUS_FAILED;
1279     }
1280
1281     (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1282
1283     if ((*env)->ExceptionCheck(env))
1284     {
1285         OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1286         (*env)->ExceptionDescribe(env);
1287         (*env)->ExceptionClear(env);
1288         return CA_STATUS_FAILED;
1289     }
1290
1291     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1292     return CA_STATUS_OK;
1293 }
1294
1295 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1296 {
1297     // GATT CLOSE
1298     OIC_LOG(DEBUG, TAG, "GattServer Close");
1299     VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1300     VERIFY_NON_NULL(env, TAG, "env is null");
1301
1302     // get BluetoothGatt class
1303     OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1304     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
1305     if (!jni_cid_BluetoothGatt)
1306     {
1307         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1308         return CA_STATUS_FAILED;
1309     }
1310
1311     jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1312     if (!jni_mid_closeGatt)
1313     {
1314         OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1315         return CA_STATUS_OK;
1316     }
1317
1318     // call disconnect gatt method
1319     OIC_LOG(DEBUG, TAG, "request to close GATT");
1320     (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1321
1322     if ((*env)->ExceptionCheck(env))
1323     {
1324         OIC_LOG(ERROR, TAG, "closeGATT has failed");
1325         (*env)->ExceptionDescribe(env);
1326         (*env)->ExceptionClear(env);
1327         return CA_STATUS_FAILED;
1328     }
1329
1330     return CA_STATUS_OK;
1331 }
1332
1333 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1334 {
1335     OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1336     VERIFY_NON_NULL(env, TAG, "env is null");
1337     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1338     VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1339
1340     if (!CALEIsEnableBTAdapter(env))
1341     {
1342         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1343         return CA_ADAPTER_NOT_ENABLED;
1344     }
1345
1346     jobject responseChar = CALEServerSetResponseData(env, responseData);
1347     if (!responseChar)
1348     {
1349         OIC_LOG(ERROR, TAG, "responseChar is null");
1350         return CA_STATUS_FAILED;
1351     }
1352
1353     CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1354     if (CA_STATUS_OK != result)
1355     {
1356         OIC_LOG(ERROR, TAG, "Fail to send response data");
1357         return result;
1358     }
1359
1360     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1361     return result;
1362 }
1363
1364 CAResult_t CALEServerInitialize(ca_thread_pool_t handle)
1365 {
1366     OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1367
1368     CALeServerJniInit();
1369
1370     if (!g_jvm)
1371     {
1372         OIC_LOG(ERROR, TAG, "g_jvm is null");
1373         return CA_STATUS_FAILED;
1374     }
1375
1376     bool isAttached = false;
1377     JNIEnv* env;
1378     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1379     if (JNI_OK != res)
1380     {
1381         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1382         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1383
1384         if (JNI_OK != res)
1385         {
1386             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1387             return CA_STATUS_FAILED;
1388         }
1389         isAttached = true;
1390     }
1391
1392     CAResult_t ret = CALECheckPlatformVersion(env, 21);
1393     if (CA_STATUS_OK != ret)
1394     {
1395         OIC_LOG(ERROR, TAG, "it is not supported");
1396
1397         if (isAttached)
1398         {
1399             (*g_jvm)->DetachCurrentThread(g_jvm);
1400         }
1401         return ret;
1402     }
1403
1404     g_threadPoolHandle = handle;
1405
1406     ret = CALEServerInitMutexVaraibles();
1407     if (CA_STATUS_OK != ret)
1408     {
1409         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1410
1411         if (isAttached)
1412         {
1413             (*g_jvm)->DetachCurrentThread(g_jvm);
1414         }
1415         return CA_STATUS_FAILED;
1416     }
1417
1418     CALEServerJNISetContext();
1419     CALEServerCreateCachedDeviceList();
1420
1421     ret = CALEServerCreateJniInterfaceObject();
1422     if (CA_STATUS_OK != ret)
1423     {
1424         OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1425
1426         if (isAttached)
1427         {
1428             (*g_jvm)->DetachCurrentThread(g_jvm);
1429         }
1430         return CA_STATUS_FAILED;
1431     }
1432
1433     if (isAttached)
1434     {
1435         (*g_jvm)->DetachCurrentThread(g_jvm);
1436     }
1437
1438     g_isInitializedServer = true;
1439     OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1440     return CA_STATUS_OK;
1441 }
1442
1443 void CALEServerTerminate()
1444 {
1445     OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1446
1447     if (!g_jvm)
1448     {
1449         OIC_LOG(ERROR, TAG, "g_jvm is null");
1450         return;
1451     }
1452
1453     bool isAttached = false;
1454     JNIEnv* env;
1455     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1456     if (JNI_OK != res)
1457     {
1458         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1459         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1460
1461         if (JNI_OK != res)
1462         {
1463             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1464             return;
1465         }
1466         isAttached = true;
1467     }
1468
1469     CAResult_t ret = CALEServerStopMulticastServer(0);
1470     if (CA_STATUS_OK != ret)
1471     {
1472         OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
1473     }
1474
1475     ret = CALEServerDisconnectAllDevices(env);
1476     if (CA_STATUS_OK != ret)
1477     {
1478         OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
1479     }
1480
1481     ret = CALEServerRemoveAllDevices(env);
1482     if (CA_STATUS_OK != ret)
1483     {
1484         OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
1485     }
1486
1487     if (g_leAdvertiseCallback)
1488     {
1489         (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
1490     }
1491
1492     if (g_bluetoothGattServer)
1493     {
1494         (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
1495     }
1496
1497     if (g_bluetoothGattServerCallback)
1498     {
1499         (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
1500     }
1501
1502     CALEServerTerminateMutexVaraibles();
1503     CALEServerTerminateConditionVaraibles();
1504
1505     g_isStartServer = false;
1506     g_isInitializedServer = false;
1507
1508     if (isAttached)
1509     {
1510         (*g_jvm)->DetachCurrentThread(g_jvm);
1511     }
1512
1513     OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1514 }
1515
1516 CAResult_t CALEServerSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
1517 {
1518     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessage(%s, %s)", address, data);
1519     VERIFY_NON_NULL(address, TAG, "address is null");
1520     VERIFY_NON_NULL(data, TAG, "data is null");
1521
1522     if (!g_jvm)
1523     {
1524         OIC_LOG(ERROR, TAG, "g_jvm is null");
1525         return CA_STATUS_FAILED;
1526     }
1527
1528     bool isAttached = false;
1529     JNIEnv* env;
1530     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1531     if (JNI_OK != res)
1532     {
1533         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1534         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1535
1536         if (JNI_OK != res)
1537         {
1538             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1539             return CA_STATUS_FAILED;
1540         }
1541         isAttached = true;
1542     }
1543
1544     CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1545     if (CA_STATUS_OK != ret)
1546     {
1547         OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1548     }
1549
1550     if (isAttached)
1551     {
1552         (*g_jvm)->DetachCurrentThread(g_jvm);
1553     }
1554
1555     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessage");
1556     return ret;
1557 }
1558
1559 CAResult_t CALEServerSendMulticastMessage(const char* data, uint32_t dataLen)
1560 {
1561     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessage(%s)", data);
1562     VERIFY_NON_NULL(data, TAG, "data is null");
1563
1564     if (!g_jvm)
1565     {
1566         OIC_LOG(ERROR, TAG, "g_jvm is null");
1567         return CA_STATUS_FAILED;
1568     }
1569
1570     bool isAttached = false;
1571     JNIEnv* env;
1572     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1573     if (JNI_OK != res)
1574     {
1575         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1576         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1577
1578         if (JNI_OK != res)
1579         {
1580             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1581             return CA_STATUS_FAILED;
1582         }
1583         isAttached = true;
1584     }
1585
1586     CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1587     if (CA_STATUS_OK != ret)
1588     {
1589         OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1590     }
1591
1592     if (isAttached)
1593     {
1594         (*g_jvm)->DetachCurrentThread(g_jvm);
1595     }
1596
1597     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessage");
1598     return ret;
1599 }
1600
1601 CAResult_t CALEServerStartMulticastServer()
1602 {
1603     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1604
1605     if (!g_isInitializedServer)
1606     {
1607         OIC_LOG(INFO, TAG, "server is not initialized");
1608         return CA_STATUS_FAILED;
1609     }
1610
1611     if (g_isStartServer)
1612     {
1613         OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1614         return CA_STATUS_FAILED;
1615     }
1616
1617     if (!g_jvm)
1618     {
1619         OIC_LOG(ERROR, TAG, "g_jvm is null");
1620         return CA_STATUS_FAILED;
1621     }
1622
1623     bool isAttached = false;
1624     JNIEnv* env;
1625     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1626     if (JNI_OK != res)
1627     {
1628         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1629         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1630
1631         if (JNI_OK != res)
1632         {
1633             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1634             return CA_STATUS_FAILED;
1635         }
1636         isAttached = true;
1637     }
1638
1639     g_isStartServer = true;
1640
1641     // start gatt server
1642     CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1643     if (CA_STATUS_OK != ret)
1644     {
1645         OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1646         return ret;
1647     }
1648
1649     // start advertise
1650     ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1651     if (CA_STATUS_OK != ret)
1652     {
1653         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1654     }
1655
1656     if (isAttached)
1657     {
1658         (*g_jvm)->DetachCurrentThread(g_jvm);
1659     }
1660
1661     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1662     return ret;
1663 }
1664
1665 CAResult_t CALEServerStopMulticastServer()
1666 {
1667     OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1668
1669     if (false == g_isStartServer)
1670     {
1671         OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1672         return CA_STATUS_FAILED;
1673     }
1674
1675     if (!g_jvm)
1676     {
1677         OIC_LOG(ERROR, TAG, "g_jvm is null");
1678         return CA_STATUS_FAILED;
1679     }
1680
1681     bool isAttached = false;
1682     JNIEnv* env;
1683     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1684     if (JNI_OK != res)
1685     {
1686         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1687         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1688
1689         if (JNI_OK != res)
1690         {
1691             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1692             return CA_STATUS_FAILED;
1693         }
1694         isAttached = true;
1695     }
1696
1697     CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1698     if (CA_STATUS_OK != ret)
1699     {
1700         OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1701     }
1702
1703     g_isStartServer = false;
1704
1705     if (isAttached)
1706     {
1707         (*g_jvm)->DetachCurrentThread(g_jvm);
1708     }
1709
1710     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1711     return ret;
1712 }
1713
1714 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1715 {
1716     OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1717     g_packetReceiveCallback = callback;
1718 }
1719
1720 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const char* data,
1721                                             uint32_t dataLen)
1722 {
1723     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessageImpl, address: %s, data: %s",
1724             address, data);
1725     VERIFY_NON_NULL(env, TAG, "env is null");
1726     VERIFY_NON_NULL(address, TAG, "address is null");
1727     VERIFY_NON_NULL(data, TAG, "data is null");
1728
1729     if (!g_connectedDeviceList)
1730     {
1731         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1732         return CA_STATUS_FAILED;
1733     }
1734
1735     jobject jni_obj_bluetoothDevice = NULL;
1736     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1737     for (uint32_t index = 0; index < length; index++)
1738     {
1739         OIC_LOG(DEBUG, TAG, "check device address");
1740         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1741         if (!jarrayObj)
1742         {
1743             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1744             return CA_STATUS_FAILED;
1745         }
1746
1747         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1748         if (!jni_setAddress)
1749         {
1750             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1751             return CA_STATUS_FAILED;
1752         }
1753         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1754         if (!setAddress)
1755         {
1756             OIC_LOG(ERROR, TAG, "setAddress is null");
1757             return CA_STATUS_FAILED;
1758         }
1759
1760         OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1761         OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1762
1763         if (!strcmp(setAddress, address))
1764         {
1765             OIC_LOG(DEBUG, TAG, "found the device");
1766             jni_obj_bluetoothDevice = jarrayObj;
1767             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1768             break;
1769         }
1770         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1771     }
1772
1773     if (jni_obj_bluetoothDevice)
1774     {
1775         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1776         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1777
1778         CAResult_t res = CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
1779         if (CA_STATUS_OK != res)
1780         {
1781             OIC_LOG(ERROR, TAG, "send has failed");
1782             return CA_SEND_FAILED;
1783         }
1784     }
1785     else
1786     {
1787         OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1788         return CA_STATUS_FAILED;
1789     }
1790
1791     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessageImpl");
1792     return CA_STATUS_OK;
1793 }
1794
1795 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen)
1796 {
1797     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1798     VERIFY_NON_NULL(env, TAG, "env is null");
1799     VERIFY_NON_NULL(data, TAG, "data is null");
1800
1801     if (!g_connectedDeviceList)
1802     {
1803         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1804         return CA_STATUS_FAILED;
1805     }
1806
1807     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1808     for (uint32_t index = 0; index < length; index++)
1809     {
1810         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1811         if (!jarrayObj)
1812         {
1813             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1814             return CA_STATUS_FAILED;
1815         }
1816
1817         // send data for all device
1818         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1819         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1820         CAResult_t res = CALEServerSend(env, jarrayObj, jni_bytearr_data);
1821         if (CA_STATUS_OK != res)
1822         {
1823             OIC_LOG(ERROR, TAG, "send has failed");
1824             return CA_SEND_FAILED;
1825         }
1826     }
1827
1828     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessageImpl");
1829     return CA_STATUS_OK;
1830 }
1831
1832 void CALEServerCreateCachedDeviceList()
1833 {
1834     OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateCachedDeviceList");
1835
1836     ca_mutex_lock(g_connectedDeviceListMutex);
1837     // create new object array
1838     if (!g_connectedDeviceList)
1839     {
1840         OIC_LOG(DEBUG, TAG, "Create device list");
1841         g_connectedDeviceList = u_arraylist_create();
1842     }
1843     ca_mutex_unlock(g_connectedDeviceListMutex);
1844
1845     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
1846 }
1847
1848 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1849 {
1850     OIC_LOG(DEBUG, TAG, "IN - CALEServerIsDeviceInList");
1851     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1852     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1853
1854     if (!g_connectedDeviceList)
1855     {
1856         OIC_LOG(ERROR, TAG, "list is null");
1857         return false;
1858     }
1859
1860     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1861     for (uint32_t index = 0; index < length; index++)
1862     {
1863         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1864
1865         if (!jarrayObj)
1866         {
1867             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1868             return false;
1869         }
1870
1871         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1872         if (!jni_setAddress)
1873         {
1874             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1875             return false;
1876         }
1877
1878         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1879         if (!setAddress)
1880         {
1881             OIC_LOG(ERROR, TAG, "setAddress is null");
1882             return false;
1883         }
1884
1885         if (!strcmp(remoteAddress, setAddress))
1886         {
1887             OIC_LOG(ERROR, TAG, "the device is already set");
1888             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1889             return true;
1890         }
1891         else
1892         {
1893             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1894             continue;
1895         }
1896     }
1897
1898     OIC_LOG(DEBUG, TAG, "there are no device in the list");
1899     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
1900     return false;
1901 }
1902
1903 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1904 {
1905     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
1906     VERIFY_NON_NULL(device, TAG, "device is null");
1907     VERIFY_NON_NULL(env, TAG, "env is null");
1908
1909     ca_mutex_lock(g_connectedDeviceListMutex);
1910
1911     if (!g_connectedDeviceList)
1912     {
1913         OIC_LOG(ERROR, TAG, "list is null");
1914         ca_mutex_unlock(g_connectedDeviceListMutex);
1915         return CA_STATUS_FAILED;
1916     }
1917
1918     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1919     if (!jni_remoteAddress)
1920     {
1921         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
1922         ca_mutex_unlock(g_connectedDeviceListMutex);
1923         return CA_STATUS_FAILED;
1924     }
1925
1926     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1927     if (!remoteAddress)
1928     {
1929         OIC_LOG(ERROR, TAG, "remoteAddress is null");
1930         ca_mutex_unlock(g_connectedDeviceListMutex);
1931         return CA_STATUS_FAILED;
1932     }
1933
1934     if (false == CALEServerIsDeviceInList(env, remoteAddress))
1935     {
1936         jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
1937         u_arraylist_add(g_connectedDeviceList, jni_obj_device);
1938         OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
1939     }
1940
1941     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
1942     ca_mutex_unlock(g_connectedDeviceListMutex);
1943     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
1944     return CA_STATUS_OK;
1945 }
1946
1947 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
1948 {
1949     OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
1950     VERIFY_NON_NULL(env, TAG, "env is null");
1951
1952     ca_mutex_lock(g_connectedDeviceListMutex);
1953     if (!g_connectedDeviceList)
1954     {
1955         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1956         ca_mutex_unlock(g_connectedDeviceListMutex);
1957         return CA_STATUS_FAILED;
1958     }
1959
1960     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1961     for (uint32_t index = 0; index < length; index++)
1962     {
1963         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1964         if (jarrayObj)
1965         {
1966             (*env)->DeleteGlobalRef(env, jarrayObj);
1967         }
1968     }
1969
1970     OICFree(g_connectedDeviceList);
1971     g_connectedDeviceList = NULL;
1972     ca_mutex_unlock(g_connectedDeviceListMutex);
1973
1974     OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
1975     return CA_STATUS_OK;
1976 }
1977
1978 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
1979 {
1980     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
1981     VERIFY_NON_NULL(env, TAG, "env is null");
1982     VERIFY_NON_NULL(address, TAG, "address is null");
1983
1984     ca_mutex_lock(g_connectedDeviceListMutex);
1985     if (!g_connectedDeviceList)
1986     {
1987         OIC_LOG(ERROR, TAG, "no deviceList");
1988         ca_mutex_unlock(g_connectedDeviceListMutex);
1989         return CA_STATUS_FAILED;
1990     }
1991
1992     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1993     for (uint32_t index = 0; index < length; index++)
1994     {
1995         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1996
1997         if (jarrayObj)
1998         {
1999             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2000             if (!jni_setAddress)
2001             {
2002                 OIC_LOG(ERROR, TAG, "wrong device address");
2003                 continue;
2004             }
2005             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2006             if (!setAddress)
2007             {
2008                 OIC_LOG(ERROR, TAG, "setAddress is null");
2009                 continue;
2010             }
2011
2012             const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2013             if (!remoteAddress)
2014             {
2015                 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2016                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2017                 continue;
2018             }
2019
2020             if (!strcmp(setAddress, remoteAddress))
2021             {
2022                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2023
2024                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2025                 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2026                 (*env)->DeleteGlobalRef(env, jarrayObj);
2027
2028                 CAResult_t res = CALEServerReorderinglist(index);
2029                 if (CA_STATUS_OK != res)
2030                 {
2031                     OIC_LOG(ERROR, TAG, "CALEServerReorderinglist has failed");
2032                     ca_mutex_unlock(g_connectedDeviceListMutex);
2033                     return res;
2034                 }
2035                 ca_mutex_unlock(g_connectedDeviceListMutex);
2036                 return CA_STATUS_OK;
2037             }
2038             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2039             (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2040         }
2041     }
2042
2043     ca_mutex_unlock(g_connectedDeviceListMutex);
2044
2045     OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2046
2047     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2048     return CA_STATUS_FAILED;
2049 }
2050
2051 CAResult_t CALEServerReorderinglist(uint32_t index)
2052 {
2053     if (!g_connectedDeviceList)
2054     {
2055         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2056         return CA_STATUS_FAILED;
2057     }
2058
2059     if (index >= g_connectedDeviceList->length)
2060     {
2061         OIC_LOG(ERROR, TAG, "index is not available");
2062         return CA_STATUS_FAILED;
2063     }
2064
2065     if (index < g_connectedDeviceList->length - 1)
2066     {
2067         memmove(&g_connectedDeviceList->data[index], &g_connectedDeviceList->data[index + 1],
2068                 (g_connectedDeviceList->length - index - 1) * sizeof(void *));
2069     }
2070
2071     g_connectedDeviceList->size--;
2072     g_connectedDeviceList->length--;
2073
2074     return CA_STATUS_OK;
2075 }
2076
2077 JNIEXPORT void JNICALL
2078 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2079                                                                          jobject callback)
2080 {
2081     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Gatt Server Callback");
2082     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2083     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
2084
2085     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2086 }
2087
2088 JNIEXPORT void JNICALL
2089 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2090                                                                                   jobject obj,
2091                                                                                   jobject callback)
2092 {
2093     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Advertise Callback");
2094     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2095     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
2096
2097     g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2098 }
2099
2100 JNIEXPORT void JNICALL
2101 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2102         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2103 {
2104     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server ConnectionStateChange Callback");
2105     OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2106
2107     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2108     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2109
2110     jclass jni_cid_bluetoothProfile = (*env)->FindClass(env, "android/bluetooth/BluetoothProfile");
2111     if (!jni_cid_bluetoothProfile)
2112     {
2113         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothProfile is null");
2114         return;
2115     }
2116
2117     jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
2118                                                                 "STATE_CONNECTED", "I");
2119     if(!jni_fid_state_connected)
2120     {
2121         OIC_LOG(ERROR, TAG, "jni_fid_state_connected is null");
2122         return;
2123     }
2124
2125     jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
2126                                                                    "STATE_DISCONNECTED", "I");
2127     if(!jni_fid_state_disconnected)
2128     {
2129         OIC_LOG(ERROR, TAG, "jni_fid_state_disconnected is null");
2130         return;
2131     }
2132
2133     // STATE_CONNECTED
2134     jint jni_int_state_connected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
2135                                                              jni_fid_state_connected);
2136
2137     // STATE_DISCONNECTED
2138     jint jni_int_state_disconnected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
2139                                                                 jni_fid_state_disconnected);
2140
2141     if (newState == jni_int_state_connected)
2142     {
2143
2144         OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2145
2146         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2147         if (!jni_remoteAddress)
2148         {
2149             OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2150             return;
2151         }
2152
2153         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2154         if (!remoteAddress)
2155         {
2156             OIC_LOG(ERROR, TAG, "remoteAddress is null");
2157             return;
2158         }
2159
2160         if (false == CALEServerIsDeviceInList(env, remoteAddress))
2161         {
2162             OIC_LOG(DEBUG, TAG, "add connected device to cache");
2163             CALEServerAddDeviceToList(env, device);
2164         }
2165         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2166     }
2167     else if (newState == jni_int_state_disconnected)
2168     {
2169         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2170         CAResult_t res = CALEServerGattClose(env, g_bluetoothGattServer);
2171         if (CA_STATUS_OK != res)
2172         {
2173             OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2174         }
2175     }
2176     else
2177     {
2178         OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2179                 status);
2180     }
2181 }
2182
2183 JNIEXPORT void JNICALL
2184 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2185                                                                              jobject obj,
2186                                                                              jint status,
2187                                                                              jobject gattService)
2188 {
2189     OIC_LOG_V(DEBUG, TAG, "CaLeServerInterface - Gatt Service Added Callback(%d)", status);
2190 }
2191
2192 JNIEXPORT void JNICALL
2193 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2194         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset,
2195         jobject characteristic, jbyteArray data)
2196 {
2197     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Read Request Callback");
2198     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2199     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2200
2201 #ifdef USE_PROPERTY_WRITE_RESPONSE
2202     CALEServerSendResponse(env, device, requestId, 0, offset, NULL);
2203 #endif
2204
2205 }
2206
2207 JNIEXPORT void JNICALL
2208 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2209         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic,
2210         jbyteArray data, jboolean preparedWrite, jboolean responseNeeded, jint offset,
2211         jbyteArray value)
2212 {
2213     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Write Request Callback");
2214     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2215     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2216     VERIFY_NON_NULL_VOID(value, TAG, "value is null");
2217     VERIFY_NON_NULL_VOID(data, TAG, "data is null");
2218
2219 #ifdef USE_PROPERTY_WRITE_RESPONSE
2220     CALEServerSendResponse(env, device, requestId, 0, offset, value);
2221 #endif
2222
2223     // get Byte Array and covert to char*
2224     jint length = (*env)->GetArrayLength(env, data);
2225
2226     jboolean isCopy;
2227     jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2228
2229     char* requestData = NULL;
2230     requestData = (char*) OICMalloc(sizeof(char) * length + 1);
2231     if (!requestData)
2232     {
2233         OIC_LOG(ERROR, TAG, "requestData is null");
2234         return;
2235     }
2236
2237     memcpy(requestData, (const char*) jni_byte_requestData, length);
2238     requestData[length] = '\0';
2239     (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2240
2241     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2242     if (!jni_address)
2243     {
2244         OIC_LOG(ERROR, TAG, "jni_address is null");
2245         OICFree(requestData);
2246         return;
2247     }
2248
2249     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2250     if (!address)
2251     {
2252         OIC_LOG(ERROR, TAG, "address is null");
2253         OICFree(requestData);
2254         return;
2255     }
2256
2257     OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %s, %d", address, requestData, length);
2258
2259     ca_mutex_lock(g_bleClientBDAddressMutex);
2260     uint32_t sentLength = 0;
2261     g_CABLEServerDataReceivedCallback(address, requestData, length,
2262                                       &sentLength);
2263     ca_mutex_unlock(g_bleClientBDAddressMutex);
2264
2265     (*env)->ReleaseStringUTFChars(env, jni_address, address);
2266 }
2267
2268 JNIEXPORT void JNICALL
2269 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorReadRequestCallback(
2270         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
2271 {
2272     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorReadRequestCallback");
2273 }
2274
2275 JNIEXPORT void JNICALL
2276 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorWriteRequestCallback(
2277         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
2278         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
2279 {
2280     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorWriteRequestCallback");
2281 }
2282
2283 JNIEXPORT void JNICALL
2284 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerExecuteWriteCallback(JNIEnv *env,
2285                                                                              jobject obj,
2286                                                                              jobject device,
2287                                                                              jint requestId,
2288                                                                              jboolean execute)
2289 {
2290     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerExecuteWriteCallback");
2291     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2292     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2293
2294 //    CALEServerSendResponse(env, device, requestId, 0, 0, NULL);
2295 }
2296
2297 JNIEXPORT void JNICALL
2298 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2299                                                                                  jobject obj,
2300                                                                                  jobject device,
2301                                                                                  jint status)
2302 {
2303     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Notification Sent Callback");
2304 }
2305
2306 JNIEXPORT void JNICALL
2307 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(
2308         JNIEnv *env, jobject obj, jobject settingsInEffect)
2309 {
2310     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - LE Advertise Start Success Callback");
2311 }
2312
2313 JNIEXPORT void JNICALL
2314 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2315                                                                             jobject obj,
2316                                                                             jint errorCode)
2317 {
2318     OIC_LOG_V(ERROR, TAG, "CaLeServerInterface - LE Advertise Start Failure Callback(%)",
2319               errorCode);
2320 }
2321
2322 /**
2323  * adapter common
2324  */
2325
2326 CAResult_t CAStartLEGattServer()
2327 {
2328     OIC_LOG(DEBUG, TAG, "IN");
2329
2330     CAResult_t ret = CALEServerInitMutexVaraibles();
2331     if (CA_STATUS_OK != ret)
2332     {
2333         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed!");
2334         CALEServerTerminateMutexVaraibles();
2335         return CA_SERVER_NOT_STARTED;
2336     }
2337
2338     ret = CALEServerInitConditionVaraibles();
2339     if (CA_STATUS_OK != ret)
2340     {
2341         OIC_LOG(ERROR, TAG, "CALEServerInitConditionVaraibles has failed!");
2342         CALEServerTerminateConditionVaraibles();
2343         return CA_SERVER_NOT_STARTED;
2344     }
2345
2346     // start gatt service
2347     CALEServerStartMulticastServer();
2348
2349     OIC_LOG(DEBUG, TAG, "OUT");
2350     return CA_STATUS_OK;
2351 }
2352
2353 CAResult_t CAStopLEGattServer()
2354 {
2355     OIC_LOG(DEBUG, TAG, "IN");
2356
2357     OIC_LOG(DEBUG, TAG, "OUT");
2358     return CA_STATUS_OK;
2359 }
2360
2361 void CATerminateLEGattServer()
2362 {
2363     OIC_LOG(DEBUG, TAG, "IN");
2364
2365     OIC_LOG(DEBUG, TAG, "Terminat Gatt Server");
2366     CALEServerTerminate();
2367
2368     OIC_LOG(DEBUG, TAG, "OUT");
2369 }
2370
2371 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2372 {
2373     OIC_LOG(DEBUG, TAG, "IN");
2374
2375     ca_mutex_lock(g_bleReqRespCbMutex);
2376     g_CABLEServerDataReceivedCallback = callback;
2377     ca_mutex_unlock(g_bleReqRespCbMutex);
2378
2379     OIC_LOG(DEBUG, TAG, "OUT");
2380 }
2381
2382 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2383 {
2384     g_serverErrorCallback = callback;
2385 }
2386
2387 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2388                                                const char *charValue,
2389                                                uint32_t charValueLen)
2390 {
2391     CAResult_t result = CA_SEND_FAILED;
2392     OIC_LOG(DEBUG, TAG, "IN");
2393     VERIFY_NON_NULL(address, TAG, "env is null");
2394     VERIFY_NON_NULL(charValue, TAG, "device is null");
2395
2396     if (address)
2397     {
2398         OIC_LOG(DEBUG, TAG, "CALEServerSendUnicastData");
2399         result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2400     }
2401
2402     OIC_LOG(DEBUG, TAG, "OUT");
2403
2404     return result;
2405 }
2406
2407 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
2408                                                    uint32_t charValueLen)
2409 {
2410     OIC_LOG(DEBUG, TAG, "IN");
2411     VERIFY_NON_NULL(charValue, TAG, "device is null");
2412
2413     OIC_LOG(DEBUG, TAG, "CALEServerSendMulticastMessage");
2414     CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2415
2416     OIC_LOG(DEBUG, TAG, "OUT");
2417     return result;
2418 }
2419
2420 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2421 {
2422     OIC_LOG(DEBUG, TAG, "IN");
2423
2424     CALEServerInitialize(handle);
2425
2426     OIC_LOG(DEBUG, TAG, "OUT");
2427 }
2428
2429 CAResult_t CALEServerInitMutexVaraibles()
2430 {
2431     OIC_LOG(DEBUG, TAG, "IN");
2432     if (NULL == g_bleReqRespCbMutex)
2433     {
2434         g_bleReqRespCbMutex = ca_mutex_new();
2435         if (NULL == g_bleReqRespCbMutex)
2436         {
2437             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2438             return CA_STATUS_FAILED;
2439         }
2440     }
2441
2442     if (NULL == g_bleClientBDAddressMutex)
2443     {
2444         g_bleClientBDAddressMutex = ca_mutex_new();
2445         if (NULL == g_bleClientBDAddressMutex)
2446         {
2447             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2448             return CA_STATUS_FAILED;
2449         }
2450     }
2451
2452     if (NULL == g_connectedDeviceListMutex)
2453     {
2454         g_connectedDeviceListMutex = ca_mutex_new();
2455         if (NULL == g_connectedDeviceListMutex)
2456         {
2457             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2458             return CA_STATUS_FAILED;
2459         }
2460     }
2461
2462     OIC_LOG(DEBUG, TAG, "OUT");
2463     return CA_STATUS_OK;
2464 }
2465
2466 CAResult_t CALEServerInitConditionVaraibles()
2467 {
2468     OIC_LOG(DEBUG, TAG, "this method is not supported");
2469     return CA_STATUS_OK;
2470 }
2471
2472 void CALEServerTerminateMutexVaraibles()
2473 {
2474     OIC_LOG(DEBUG, TAG, "IN");
2475
2476     ca_mutex_free(g_bleReqRespCbMutex);
2477     g_bleReqRespCbMutex = NULL;
2478
2479     ca_mutex_free(g_bleClientBDAddressMutex);
2480     g_bleClientBDAddressMutex = NULL;
2481
2482     ca_mutex_free(g_connectedDeviceListMutex);
2483     g_connectedDeviceListMutex = NULL;
2484
2485     OIC_LOG(DEBUG, TAG, "OUT");
2486 }
2487
2488 void CALEServerTerminateConditionVaraibles()
2489 {
2490     OIC_LOG(DEBUG, TAG, "this method is not supported");
2491 }