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