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