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