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