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