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