1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
24 #include <android/log.h>
26 #include "caleserver.h"
27 #include "caleutils.h"
28 #include "caleinterface.h"
29 #include "caadapterutils.h"
32 #include "oic_malloc.h"
33 #include "cathreadpool.h"
35 #include "uarraylist.h"
36 #include "org_iotivity_ca_CaLeServerInterface.h"
38 #define TAG PCF("OIC_CA_LE_SERVER")
40 #define WAIT_TIME_WRITE_CHARACTERISTIC 10000000
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;
49 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
50 static CABLEErrorHandleCallback g_serverErrorCallback;
52 static u_arraylist_t *g_connectedDeviceList = NULL;
54 static bool g_isStartServer = false;
55 static bool g_isInitializedServer = false;
57 static jbyteArray g_sendBuffer = NULL;
58 static jobject g_obj_bluetoothDevice = NULL;
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;
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;
70 static const char CLASSPATH_BT_ADVERTISE_CB[] = "android/bluetooth/le/AdvertiseCallback";
72 void CALEServerJNISetContext()
74 OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
75 g_context = (jobject) CANativeJNIGetContext();
78 void CALeServerJniInit()
80 OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
81 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
84 CAResult_t CALEServerCreateJniInterfaceObject()
86 OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
90 OIC_LOG(ERROR, TAG, "g_context is null");
91 return CA_STATUS_FAILED;
96 OIC_LOG(ERROR, TAG, "g_jvm is null");
97 return CA_STATUS_FAILED;
100 bool isAttached = false;
102 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
105 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
106 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
110 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
111 return CA_STATUS_FAILED;
116 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
117 if (!jni_LEInterface)
119 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
123 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
125 if (!LeInterfaceConstructorMethod)
127 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
131 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
132 OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
136 (*g_jvm)->DetachCurrentThread(g_jvm);
145 (*g_jvm)->DetachCurrentThread(g_jvm);
148 return CA_STATUS_FAILED;
152 * get the current connection state of the gatt profile to the remote device.
153 * @param[in] env JNI interface pointer.
154 * @param[in] device bluetooth device object
155 * @return state of the profile connection.
157 static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
159 OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
161 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
162 VERIFY_NON_NULL_RET(device, TAG, "device", -1);
164 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
165 if (!jni_cid_bluetoothManager)
167 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
171 jmethodID jni_mid_getConnectionState = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
172 "getConnectionState",
173 "(Landroid/bluetooth/BluetoothDevice"
175 if (!jni_mid_getConnectionState)
177 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
181 if (!g_bluetoothManager)
183 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
187 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
188 jni_mid_getConnectionState,
189 device, GATT_PROFILE);
190 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
194 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
196 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
197 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
198 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
200 if (!g_bluetoothGattServer)
202 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
206 if (!CALEIsEnableBTAdapter(env))
208 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
212 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
214 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
215 "android/bluetooth/BluetoothGattServer");
216 if (!jni_cid_bluetoothGattServer)
218 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
222 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
223 "BluetoothGattService");
224 if (!jni_cid_bluetoothGattService)
226 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
230 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
231 "BluetoothGattCharacteristic");
232 if (!jni_cid_bluetoothGattCharacteristic)
234 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
238 jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
240 "(Ljava/util/UUID;)Landroid/bluetooth/"
241 "BluetoothGattService;");
242 if (!jni_mid_getService)
244 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
248 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
249 if (!jni_obj_serviceUUID)
251 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
255 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
257 jni_obj_serviceUUID);
258 if (!jni_obj_bluetoothGattService)
260 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
264 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
267 "Landroid/bluetooth/"
268 "BluetoothGattCharacteristic;");
269 if (!jni_mid_getCharacteristic)
271 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
275 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
276 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
277 if (!jni_obj_responseUUID)
279 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
283 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
284 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
285 if (!jni_obj_bluetoothGattCharacteristic)
287 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
291 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
292 "setValue", "([B)Z");
293 if (!jni_mid_setValue)
295 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
299 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
300 jni_obj_bluetoothGattCharacteristic,
301 jni_mid_setValue, responseData);
302 if (JNI_FALSE == jni_boolean_setValue)
304 OIC_LOG(ERROR, TAG, "Fail to set response data");
307 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
308 return jni_obj_bluetoothGattCharacteristic;
311 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
313 OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
314 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
315 VERIFY_NON_NULL(device, TAG, "device is null");
316 VERIFY_NON_NULL(env, TAG, "env is null");
318 if (!CALEIsEnableBTAdapter(env))
320 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
321 return CA_ADAPTER_NOT_ENABLED;
324 if (STATE_CONNECTED != CALEServerGetConnectionState(env, device))
326 OIC_LOG(ERROR, TAG, "it is not connected state");
327 return CA_STATUS_FAILED;
330 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
331 "android/bluetooth/BluetoothGattServer");
332 if (!jni_cid_bluetoothGattServer)
334 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
335 return CA_STATUS_FAILED;
338 jmethodID jni_mid_notifyCharacteristicChanged = (*env)->GetMethodID(
339 env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
340 "(Landroid/bluetooth/BluetoothDevice;"
341 "Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
342 if (!jni_mid_notifyCharacteristicChanged)
344 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
345 return CA_STATUS_FAILED;
348 OIC_LOG(DEBUG, TAG, "CALL API - notifyCharacteristicChanged");
350 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
351 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
353 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
355 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
356 return CA_SEND_FAILED;
359 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
360 ca_mutex_lock(g_threadSendNotifyMutex);
361 if (!g_isSignalSetFlag)
363 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
364 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
365 WAIT_TIME_WRITE_CHARACTERISTIC))
367 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
368 ca_mutex_unlock(g_threadSendNotifyMutex);
369 return CA_STATUS_FAILED;
372 // reset flag set by writeCharacteristic Callback
373 g_isSignalSetFlag = false;
374 ca_mutex_unlock(g_threadSendNotifyMutex);
375 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
379 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
380 jint offset, jbyteArray value)
382 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
383 VERIFY_NON_NULL(env, TAG, "env is null");
384 VERIFY_NON_NULL(device, TAG, "device is null");
385 VERIFY_NON_NULL(value, TAG, "value is null");
387 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
389 if (!CALEIsEnableBTAdapter(env))
391 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
392 return CA_ADAPTER_NOT_ENABLED;
395 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
396 "android/bluetooth/BluetoothGattServer");
397 if (!jni_cid_bluetoothGattServer)
399 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
400 return CA_STATUS_FAILED;
403 jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
405 "(Landroid/bluetooth/BluetoothDevice;"
407 if (!jni_mid_sendResponse)
409 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
410 return CA_STATUS_FAILED;
413 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
414 jni_mid_sendResponse, device,
415 requestId, status, offset,
417 if (JNI_FALSE == jni_boolean_sendResponse)
419 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
420 return CA_SEND_FAILED;
423 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
427 CAResult_t CALEStartAdvertise()
431 OIC_LOG(ERROR, TAG, "g_jvm is null");
432 return CA_STATUS_FAILED;
435 bool isAttached = false;
437 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
440 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
441 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
445 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
446 return CA_STATUS_FAILED;
452 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
453 if (CA_STATUS_OK != ret)
455 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
460 (*g_jvm)->DetachCurrentThread(g_jvm);
465 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
467 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
468 VERIFY_NON_NULL(env, TAG, "env is null");
469 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
471 if (!CALEIsEnableBTAdapter(env))
473 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
474 return CA_ADAPTER_NOT_ENABLED;
477 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
478 "android/bluetooth/le/"
479 "AdvertiseSettings$Builder");
480 if (!jni_cid_AdvertiseSettings)
482 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
483 return CA_STATUS_FAILED;
486 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
488 if (!jni_mid_AdvertiseSettings)
490 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
491 return CA_STATUS_FAILED;
494 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
495 jni_mid_AdvertiseSettings);
496 if (!jni_AdvertiseSettings)
498 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
499 return CA_STATUS_FAILED;
502 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
504 "(I)Landroid/bluetooth/le/"
505 "AdvertiseSettings$Builder;");
506 if (!jni_mid_setAdvertiseMode)
508 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
509 return CA_STATUS_FAILED;
512 // 0: Low power, 1: Balanced
513 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
514 jni_mid_setAdvertiseMode, 0);
515 if (!jni_obj_setAdvertiseMode)
517 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
518 return CA_STATUS_FAILED;
521 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
523 "(Z)Landroid/bluetooth/le/"
524 "AdvertiseSettings$Builder;");
525 if (!jni_mid_setConnectable)
527 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
528 return CA_STATUS_FAILED;
531 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
532 jni_mid_setConnectable, JNI_TRUE);
533 if (!jni_obj_setConnectable)
535 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
536 return CA_STATUS_FAILED;
539 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
540 "(I)Landroid/bluetooth/le/"
541 "AdvertiseSettings$Builder;");
542 if (!jni_mid_setTimeout)
544 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
545 return CA_STATUS_FAILED;
548 //A value of 0 will disable the time limit
549 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
550 jni_mid_setTimeout, 0);
551 if (!jni_obj_setTimeout)
553 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
554 return CA_STATUS_FAILED;
557 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
558 "android/bluetooth/le/"
559 "AdvertiseData$Builder");
560 if (!jni_cid_AdvertiseDataBuilder)
562 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
563 return CA_STATUS_FAILED;
566 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
568 if (!jni_mid_AdvertiseDataBuilder)
570 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
571 return CA_STATUS_FAILED;
574 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
575 jni_mid_AdvertiseDataBuilder);
576 if (!jni_AdvertiseDataBuilder)
578 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
579 return CA_STATUS_FAILED;
582 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
583 if (!jni_obj_serviceUUID)
585 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
586 return CA_STATUS_FAILED;
589 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
592 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
593 return CA_STATUS_FAILED;
596 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
598 "(Landroid/os/ParcelUuid;)Landroid/"
599 "bluetooth/le/AdvertiseData$Builder;");
600 if (!jni_mid_addServiceUuid)
602 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
603 return CA_STATUS_FAILED;
606 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
607 jni_mid_addServiceUuid,
609 if (!jni_obj_addServiceUuid)
611 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
612 return CA_STATUS_FAILED;
615 // Device name has to be included in advertise packet after Android API 23
616 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
617 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
618 "setIncludeDeviceName",
621 "AdvertiseData$Builder;");
622 if (!jni_mid_setIncludeDeviceName)
624 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
625 return CA_STATUS_FAILED;
628 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
629 jni_mid_setIncludeDeviceName,
631 if (!jni_obj_setIncludeDeviceName)
633 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
634 return CA_STATUS_FAILED;
637 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
638 if (!jni_cid_BTAdapter)
640 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
641 return CA_STATUS_FAILED;
644 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
646 "()Landroid/bluetooth/"
647 "BluetoothAdapter;");
648 if (!jni_mid_getDefaultAdapter)
650 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
651 return CA_STATUS_FAILED;
654 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
655 jni_mid_getDefaultAdapter);
656 if (!jni_obj_BTAdapter)
658 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
659 return CA_STATUS_FAILED;
662 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
663 "getBluetoothLeAdvertiser",
664 "()Landroid/bluetooth/le/"
665 "BluetoothLeAdvertiser;");
666 if (!jni_mid_getBluetoothLeAdvertiser)
668 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
669 return CA_STATUS_FAILED;
672 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
673 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
674 if (!jni_obj_getBluetoothLeAdvertiser)
676 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
677 return CA_STATUS_FAILED;
680 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
681 jni_cid_AdvertiseSettings,
683 "()Landroid/bluetooth/le/"
684 "AdvertiseSettings;");
685 if (!jni_mid_build_LeAdvertiseSettings)
687 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
688 return CA_STATUS_FAILED;
691 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
692 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
693 if (!jni_obj_build_LeAdvertiseSettings)
695 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
696 return CA_STATUS_FAILED;
699 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
701 "()Landroid/bluetooth/le/"
703 if (!jni_mid_build_LeAdvertiseData)
705 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
706 return CA_STATUS_FAILED;
709 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
710 jni_mid_build_LeAdvertiseData);
711 if (!jni_obj_build_LeAdvertiseData)
713 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
714 return CA_STATUS_FAILED;
717 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
718 "android/bluetooth/le/BluetoothLeAdvertiser");
719 if (!jni_cid_leAdvertiser)
721 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
722 return CA_STATUS_FAILED;
725 jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
727 "(Landroid/bluetooth/le/"
728 "AdvertiseSettings;Landroid/bluetooth/"
729 "le/AdvertiseData;Landroid/bluetooth/"
730 "le/AdvertiseCallback;)V");
731 if (!jni_mid_startAdvertising)
733 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
734 return CA_STATUS_FAILED;
737 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
738 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
741 if ((*env)->ExceptionCheck(env))
743 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
744 (*env)->ExceptionDescribe(env);
745 (*env)->ExceptionClear(env);
746 return CA_STATUS_FAILED;
749 OIC_LOG(DEBUG, TAG, "Advertising started!!");
751 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
755 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
757 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
758 VERIFY_NON_NULL(env, TAG, "env is null");
759 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
761 if (!CALEIsEnableBTAdapter(env))
763 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
764 return CA_ADAPTER_NOT_ENABLED;
767 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
768 if (!jni_cid_BTAdapter)
770 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
771 return CA_STATUS_FAILED;
774 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
775 "android/bluetooth/le/BluetoothLeAdvertiser");
776 if (!jni_cid_leAdvertiser)
778 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
779 return CA_STATUS_FAILED;
782 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
784 "()Landroid/bluetooth/"
785 "BluetoothAdapter;");
786 if (!jni_mid_getDefaultAdapter)
788 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
789 return CA_STATUS_FAILED;
792 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
793 "getBluetoothLeAdvertiser",
794 "()Landroid/bluetooth/le/"
795 "BluetoothLeAdvertiser;");
796 if (!jni_mid_getBTLeAdvertiser)
798 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
799 return CA_STATUS_FAILED;
802 jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
804 "(Landroid/bluetooth/le/"
805 "AdvertiseCallback;)V");
806 if (!jni_mid_stopAdvertising)
808 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
809 return CA_STATUS_FAILED;
812 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
813 jni_mid_getDefaultAdapter);
814 if (!jni_obj_BTAdapter)
816 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
817 return CA_STATUS_FAILED;
820 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
821 jni_mid_getBTLeAdvertiser);
822 if (!jni_obj_getBluetoothLeAdvertiser)
824 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
825 return CA_STATUS_FAILED;
828 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
830 if ((*env)->ExceptionCheck(env))
832 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
833 (*env)->ExceptionDescribe(env);
834 (*env)->ExceptionClear(env);
835 return CA_STATUS_FAILED;
838 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
842 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
844 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
845 VERIFY_NON_NULL(env, TAG, "env is null");
846 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
848 if (!CALEIsEnableBTAdapter(env))
850 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
851 return CA_ADAPTER_NOT_ENABLED;
856 OIC_LOG(DEBUG, TAG, "Gatt server already started");
859 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
862 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
863 if (!bluetoothGattServer)
865 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
866 return CA_STATUS_FAILED;
869 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
870 if (!g_bluetoothGattServer)
872 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
873 return CA_STATUS_FAILED;
876 // create gatt service
877 jobject bluetoothGattService = CALEServerCreateGattService(env);
878 if (!bluetoothGattService)
880 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
881 return CA_STATUS_FAILED;
885 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
886 bluetoothGattService);
887 if (CA_STATUS_OK != res)
889 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
894 jobject CALEServerOpenGattServer(JNIEnv *env)
896 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
897 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
899 if (!CALEIsEnableBTAdapter(env))
901 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
905 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
906 if (!jni_cid_context)
908 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
912 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
913 if (!jni_cid_bluetoothManager)
915 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
919 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
921 "Ljava/lang/String;");
922 if (!jni_fid_bluetoothService)
924 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
928 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
930 "(Ljava/lang/String;)"
931 "Ljava/lang/Object;");
932 if (!jni_mid_getSystemService)
934 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
938 jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
940 "(Landroid/content/Context;"
941 "Landroid/bluetooth/"
942 "BluetoothGattServerCallback;)"
943 "Landroid/bluetooth/"
944 "BluetoothGattServer;");
945 if (!jni_mid_openGattServer)
947 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
951 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
952 jni_fid_bluetoothService);
953 if (!jni_obj_bluetoothService)
955 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
959 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
960 jni_mid_getSystemService,
961 jni_obj_bluetoothService);
962 if (!jni_obj_bluetoothManager)
964 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
968 if (g_bluetoothManager)
970 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
972 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
974 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
975 jni_mid_openGattServer,
977 g_bluetoothGattServerCallback);
978 if (!jni_obj_bluetoothGattServer)
980 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
984 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
985 return jni_obj_bluetoothGattServer;
988 jobject CALEServerCreateGattService(JNIEnv *env)
990 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
991 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
993 if (!CALEIsEnableBTAdapter(env))
995 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
999 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
1000 "BluetoothGattService");
1001 if (!jni_cid_bluetoothGattService)
1003 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
1007 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1008 "BluetoothGattCharacteristic");
1009 if (!jni_cid_bluetoothGattCharacteristic)
1011 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
1015 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
1016 "SERVICE_TYPE_PRIMARY", "I");
1017 if (!jni_fid_serviceType)
1019 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
1023 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
1024 jni_cid_bluetoothGattCharacteristic,
1025 "PROPERTY_NOTIFY", "I");
1026 if (!jni_fid_readProperties)
1028 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1032 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1033 jni_cid_bluetoothGattCharacteristic,
1034 "PROPERTY_WRITE_NO_RESPONSE", "I");
1035 if (!jni_fid_writeProperties)
1037 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1041 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1042 jni_cid_bluetoothGattCharacteristic,
1043 "PERMISSION_READ", "I");
1044 if (!jni_fid_readPermissions)
1046 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1050 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1051 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1052 if (!jni_fid_writePermissions)
1054 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1058 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1059 "<init>", "(Ljava/util/UUID;I)V");
1060 if (!jni_mid_bluetoothGattService)
1062 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1066 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1067 "addCharacteristic",
1068 "(Landroid/bluetooth/"
1069 "BluetoothGattCharacteristic;)Z");
1070 if (!jni_mid_addCharacteristic)
1072 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1076 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1077 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1078 if (!jni_mid_bluetoothGattCharacteristic)
1080 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1084 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1085 if (!jni_obj_serviceUUID)
1087 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1091 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1092 jni_fid_serviceType);
1093 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1094 jni_mid_bluetoothGattService,
1095 jni_obj_serviceUUID, jni_int_serviceType);
1096 if (!jni_bluetoothGattService)
1098 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1102 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1103 if (!jni_obj_readUuid)
1105 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1109 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1110 jni_cid_bluetoothGattCharacteristic,
1111 jni_fid_readProperties);
1113 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1114 jni_cid_bluetoothGattCharacteristic,
1115 jni_fid_readPermissions);
1117 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1118 jni_cid_bluetoothGattCharacteristic,
1119 jni_fid_writePermissions);
1121 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1122 jni_mid_bluetoothGattCharacteristic,
1123 jni_obj_readUuid, jni_int_readProperties,
1124 jni_int_readPermissions|
1125 jni_int_writePermissions);
1126 if (!jni_readCharacteristic)
1128 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1132 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1133 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1134 if (!jni_boolean_addReadCharacteristic)
1136 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1140 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1141 if (!jni_obj_writeUuid)
1143 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1147 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1148 jni_cid_bluetoothGattCharacteristic,
1149 jni_fid_writeProperties);
1151 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1152 jni_mid_bluetoothGattCharacteristic,
1153 jni_obj_writeUuid, jni_int_writeProperties,
1154 jni_int_writePermissions);
1155 if (!jni_writeCharacteristic)
1157 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1161 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1162 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1163 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1165 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1169 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1170 return jni_bluetoothGattService;
1173 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1175 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1176 VERIFY_NON_NULL(env, TAG, "env is null");
1177 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1179 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1180 "BluetoothGattDescriptor");
1181 if (!jni_cid_bluetoothGattDescriptor)
1183 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1184 return CA_STATUS_FAILED;
1187 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1188 jni_cid_bluetoothGattDescriptor,
1190 "(Ljava/util/UUID;I)V");
1191 if (!jni_mid_bluetoothGattDescriptor)
1193 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1194 return CA_STATUS_FAILED;
1197 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1198 jni_cid_bluetoothGattDescriptor,
1199 "PERMISSION_READ", "I");
1200 if (!jni_fid_readPermissions)
1202 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1203 return CA_STATUS_FAILED;
1206 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1207 if (!jni_obj_readUuid)
1209 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1210 return CA_STATUS_FAILED;
1213 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1214 jni_fid_readPermissions);
1216 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1218 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1219 jni_mid_bluetoothGattDescriptor,
1220 jni_obj_readUuid, jni_int_readPermissions);
1221 if (!jni_readDescriptor)
1223 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1224 return CA_STATUS_FAILED;
1227 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1228 "BluetoothGattCharacteristic");
1229 if (!jni_cid_GattCharacteristic)
1231 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1232 return CA_STATUS_FAILED;
1235 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1237 "(Landroid/bluetooth/"
1238 "BluetoothGattDescriptor;)Z");
1239 if (!jni_mid_addDescriptor)
1241 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1242 return CA_STATUS_FAILED;
1245 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1246 jni_mid_addDescriptor,
1247 jni_readDescriptor);
1249 if (JNI_FALSE == jni_boolean_addDescriptor)
1251 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1252 return CA_STATUS_FAILED;
1256 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1258 return CA_STATUS_OK;
1261 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1262 jobject bluetoothGattService)
1264 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1265 VERIFY_NON_NULL(env, TAG, "env is null");
1266 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1267 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1269 if (!CALEIsEnableBTAdapter(env))
1271 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1272 return CA_ADAPTER_NOT_ENABLED;
1275 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1276 "android/bluetooth/BluetoothGattServer");
1277 if (!jni_cid_bluetoothGattServer)
1279 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1280 return CA_STATUS_FAILED;
1283 jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1285 "(Landroid/bluetooth/BluetoothGattService;)"
1287 if (!jni_mid_addService)
1289 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1290 return CA_STATUS_FAILED;
1293 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1295 bluetoothGattService);
1297 if (JNI_FALSE == jni_boolean_addService)
1299 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1300 return CA_STATUS_FAILED;
1303 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1304 return CA_STATUS_OK;
1307 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1309 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1310 VERIFY_NON_NULL(env, TAG, "env is null");
1311 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1313 if (!CALEIsEnableBTAdapter(env))
1315 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1316 return CA_ADAPTER_NOT_ENABLED;
1319 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1320 "android/bluetooth/BluetoothGattServer");
1321 if (!jni_cid_bluetoothGattServer)
1323 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1324 return CA_STATUS_FAILED;
1327 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1328 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1329 if (!jni_mid_connect)
1331 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1332 return CA_STATUS_FAILED;
1335 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1336 jni_mid_connect, bluetoothDevice,
1338 if (JNI_FALSE == jni_boolean_connect)
1340 OIC_LOG(ERROR, TAG, "Fail to connect");
1341 return CA_STATUS_FAILED;
1344 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1345 return CA_STATUS_OK;
1348 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1350 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1351 VERIFY_NON_NULL(env, TAG, "env is null");
1353 ca_mutex_lock(g_connectedDeviceListMutex);
1354 if (!g_connectedDeviceList)
1356 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1357 ca_mutex_unlock(g_connectedDeviceListMutex);
1358 return CA_STATUS_FAILED;
1361 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1362 for (uint32_t index = 0; index < length; index++)
1364 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1367 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1371 // disconnect for device obj
1372 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1373 if (CA_STATUS_OK != res)
1375 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1380 ca_mutex_unlock(g_connectedDeviceListMutex);
1381 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1382 return CA_STATUS_OK;
1385 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1387 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1388 VERIFY_NON_NULL(env, TAG, "env is null");
1389 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1391 if (!CALEIsEnableBTAdapter(env))
1393 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1394 return CA_ADAPTER_NOT_ENABLED;
1397 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1398 "android/bluetooth/BluetoothGattServer");
1399 if (!jni_cid_bluetoothGattServer)
1401 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1402 return CA_STATUS_FAILED;
1405 jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1407 "(Landroid/bluetooth/BluetoothDevice;)"
1409 if (!jni_mid_cancelConnection)
1411 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1412 return CA_STATUS_FAILED;
1415 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1417 if ((*env)->ExceptionCheck(env))
1419 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1420 (*env)->ExceptionDescribe(env);
1421 (*env)->ExceptionClear(env);
1422 return CA_STATUS_FAILED;
1425 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1426 return CA_STATUS_OK;
1429 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1432 OIC_LOG(DEBUG, TAG, "GattServer Close");
1433 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1434 VERIFY_NON_NULL(env, TAG, "env is null");
1436 // get BluetoothGatt class
1437 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1438 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
1439 if (!jni_cid_BluetoothGatt)
1441 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1442 return CA_STATUS_FAILED;
1445 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1446 if (!jni_mid_closeGatt)
1448 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1449 return CA_STATUS_OK;
1452 // call disconnect gatt method
1453 OIC_LOG(DEBUG, TAG, "request to close GATT");
1454 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1456 if ((*env)->ExceptionCheck(env))
1458 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1459 (*env)->ExceptionDescribe(env);
1460 (*env)->ExceptionClear(env);
1461 return CA_STATUS_FAILED;
1464 return CA_STATUS_OK;
1467 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1469 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1470 VERIFY_NON_NULL(env, TAG, "env is null");
1471 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1472 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1474 if (!CALEIsEnableBTAdapter(env))
1476 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1477 return CA_ADAPTER_NOT_ENABLED;
1480 jobject responseChar = CALEServerSetResponseData(env, responseData);
1483 OIC_LOG(ERROR, TAG, "responseChar is null");
1484 return CA_STATUS_FAILED;
1487 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1488 if (CA_STATUS_OK != result)
1490 OIC_LOG(ERROR, TAG, "Fail to send response data");
1494 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1498 CAResult_t CALEServerInitialize()
1500 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1502 CALeServerJniInit();
1506 OIC_LOG(ERROR, TAG, "g_jvm is null");
1507 return CA_STATUS_FAILED;
1510 bool isAttached = false;
1512 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1515 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1516 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1520 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1521 return CA_STATUS_FAILED;
1526 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1527 if (CA_STATUS_OK != ret)
1529 OIC_LOG(ERROR, TAG, "it is not supported");
1533 (*g_jvm)->DetachCurrentThread(g_jvm);
1538 g_threadSendNotifyCond = ca_cond_new();
1540 ret = CALEServerInitMutexVaraibles();
1541 if (CA_STATUS_OK != ret)
1543 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1547 (*g_jvm)->DetachCurrentThread(g_jvm);
1549 return CA_STATUS_FAILED;
1552 CALEServerJNISetContext();
1553 CALEServerCreateCachedDeviceList();
1555 ret = CALEServerCreateJniInterfaceObject();
1556 if (CA_STATUS_OK != ret)
1558 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1562 (*g_jvm)->DetachCurrentThread(g_jvm);
1564 return CA_STATUS_FAILED;
1569 (*g_jvm)->DetachCurrentThread(g_jvm);
1572 g_isInitializedServer = true;
1573 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1574 return CA_STATUS_OK;
1577 void CALEServerTerminate()
1579 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1583 OIC_LOG(ERROR, TAG, "g_jvm is null");
1587 bool isAttached = false;
1589 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1592 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1593 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1597 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1605 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1606 g_sendBuffer = NULL;
1609 if (g_bluetoothManager)
1611 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1612 g_bluetoothManager = NULL;
1615 ca_cond_free(g_threadSendNotifyCond);
1616 g_threadSendNotifyCond = NULL;
1618 CALEServerTerminateMutexVaraibles();
1619 CALEServerTerminateConditionVaraibles();
1621 g_isInitializedServer = false;
1625 (*g_jvm)->DetachCurrentThread(g_jvm);
1628 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1631 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1633 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1634 VERIFY_NON_NULL(address, TAG, "address is null");
1635 VERIFY_NON_NULL(data, TAG, "data is null");
1639 OIC_LOG(ERROR, TAG, "g_jvm is null");
1640 return CA_STATUS_FAILED;
1643 bool isAttached = false;
1645 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1648 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1649 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1653 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1654 return CA_STATUS_FAILED;
1659 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1660 if (CA_STATUS_OK != ret)
1662 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1667 (*g_jvm)->DetachCurrentThread(g_jvm);
1673 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1675 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1676 VERIFY_NON_NULL(data, TAG, "data is null");
1680 OIC_LOG(ERROR, TAG, "g_jvm is null");
1681 return CA_STATUS_FAILED;
1684 bool isAttached = false;
1686 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1689 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1690 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1694 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1695 return CA_STATUS_FAILED;
1700 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1701 if (CA_STATUS_OK != ret)
1703 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1708 (*g_jvm)->DetachCurrentThread(g_jvm);
1714 CAResult_t CALEServerStartMulticastServer()
1716 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1718 if (!g_isInitializedServer)
1720 OIC_LOG(INFO, TAG, "server is not initialized");
1721 return CA_STATUS_FAILED;
1724 if (g_isStartServer)
1726 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1727 return CA_STATUS_FAILED;
1732 OIC_LOG(ERROR, TAG, "g_jvm is null");
1733 return CA_STATUS_FAILED;
1736 bool isAttached = false;
1738 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1741 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1742 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1746 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1747 return CA_STATUS_FAILED;
1752 g_isStartServer = true;
1754 // start gatt server
1755 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1756 if (CA_STATUS_OK != ret)
1758 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1763 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1764 if (CA_STATUS_OK != ret)
1766 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1771 (*g_jvm)->DetachCurrentThread(g_jvm);
1774 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1778 CAResult_t CALEServerStopMulticastServer()
1780 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1782 if (false == g_isStartServer)
1784 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1785 return CA_STATUS_FAILED;
1790 OIC_LOG(ERROR, TAG, "g_jvm is null");
1791 return CA_STATUS_FAILED;
1794 bool isAttached = false;
1796 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1799 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1800 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1804 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1805 return CA_STATUS_FAILED;
1810 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1811 if (CA_STATUS_OK != ret)
1813 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1816 g_isStartServer = false;
1820 (*g_jvm)->DetachCurrentThread(g_jvm);
1823 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1827 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1829 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1830 g_packetReceiveCallback = callback;
1833 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1836 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1838 VERIFY_NON_NULL(env, TAG, "env is null");
1839 VERIFY_NON_NULL(address, TAG, "address is null");
1840 VERIFY_NON_NULL(data, TAG, "data is null");
1842 if (!g_connectedDeviceList)
1844 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1845 return CA_STATUS_FAILED;
1848 ca_mutex_lock(g_threadSendMutex);
1850 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1851 for (uint32_t index = 0; index < length; index++)
1853 OIC_LOG(DEBUG, TAG, "check device address");
1854 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1857 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1861 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1862 if (!jni_setAddress)
1864 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1867 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1870 OIC_LOG(ERROR, TAG, "setAddress is null");
1874 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1875 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1877 if (!strcmp(setAddress, address))
1879 OIC_LOG(DEBUG, TAG, "found the device");
1881 if (g_obj_bluetoothDevice)
1883 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1884 g_obj_bluetoothDevice = NULL;
1889 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1891 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1894 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1897 if (g_obj_bluetoothDevice)
1899 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1900 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1901 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1903 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1904 if (CA_STATUS_OK != res)
1906 OIC_LOG(ERROR, TAG, "send has failed");
1912 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1918 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1919 g_sendBuffer = NULL;
1922 ca_mutex_unlock(g_threadSendMutex);
1923 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1924 return CA_STATUS_OK;
1929 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1930 g_sendBuffer = NULL;
1933 if (g_obj_bluetoothDevice)
1935 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1936 g_obj_bluetoothDevice = NULL;
1939 ca_mutex_unlock(g_threadSendMutex);
1940 return CA_SEND_FAILED;
1943 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1945 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1946 VERIFY_NON_NULL(env, TAG, "env is null");
1947 VERIFY_NON_NULL(data, TAG, "data is null");
1949 if (!g_connectedDeviceList)
1951 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1952 return CA_STATUS_FAILED;
1955 ca_mutex_lock(g_threadSendMutex);
1957 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1960 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1961 g_sendBuffer = NULL;
1963 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1964 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1965 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1967 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1968 for (uint32_t index = 0; index < length; index++)
1970 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1973 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1977 // send data for all device
1978 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1979 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1981 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1984 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1988 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1991 OIC_LOG(ERROR, TAG, "address is not available");
1995 if (g_obj_bluetoothDevice)
1997 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1998 g_obj_bluetoothDevice = NULL;
2003 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
2006 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
2007 if (CA_STATUS_OK != res)
2009 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
2010 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2011 if (g_obj_bluetoothDevice)
2013 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2014 g_obj_bluetoothDevice = NULL;
2019 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
2020 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2025 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2026 g_sendBuffer = NULL;
2029 ca_mutex_unlock(g_threadSendMutex);
2030 return CA_STATUS_OK;
2033 void CALEServerCreateCachedDeviceList()
2035 ca_mutex_lock(g_connectedDeviceListMutex);
2036 // create new object array
2037 if (!g_connectedDeviceList)
2039 OIC_LOG(DEBUG, TAG, "Create device list");
2040 g_connectedDeviceList = u_arraylist_create();
2042 ca_mutex_unlock(g_connectedDeviceListMutex);
2045 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
2047 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
2048 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2050 if (!g_connectedDeviceList)
2052 OIC_LOG(ERROR, TAG, "list is null");
2056 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2057 for (uint32_t index = 0; index < length; index++)
2059 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2063 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2067 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2068 if (!jni_setAddress)
2070 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2074 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2077 OIC_LOG(ERROR, TAG, "setAddress is null");
2081 if (!strcmp(remoteAddress, setAddress))
2083 OIC_LOG(ERROR, TAG, "the device is already set");
2084 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2089 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2094 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2098 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2100 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2101 VERIFY_NON_NULL(device, TAG, "device is null");
2102 VERIFY_NON_NULL(env, TAG, "env is null");
2104 ca_mutex_lock(g_connectedDeviceListMutex);
2106 if (!g_connectedDeviceList)
2108 OIC_LOG(ERROR, TAG, "list is null");
2109 ca_mutex_unlock(g_connectedDeviceListMutex);
2110 return CA_STATUS_FAILED;
2113 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2114 if (!jni_remoteAddress)
2116 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2117 ca_mutex_unlock(g_connectedDeviceListMutex);
2118 return CA_STATUS_FAILED;
2121 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2124 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2125 ca_mutex_unlock(g_connectedDeviceListMutex);
2126 return CA_STATUS_FAILED;
2129 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2131 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2132 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2133 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2136 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2137 ca_mutex_unlock(g_connectedDeviceListMutex);
2138 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2139 return CA_STATUS_OK;
2142 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2144 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2145 VERIFY_NON_NULL(env, TAG, "env is null");
2147 ca_mutex_lock(g_connectedDeviceListMutex);
2148 if (!g_connectedDeviceList)
2150 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2151 ca_mutex_unlock(g_connectedDeviceListMutex);
2152 return CA_STATUS_FAILED;
2155 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2156 for (uint32_t index = 0; index < length; index++)
2158 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2161 (*env)->DeleteGlobalRef(env, jarrayObj);
2165 OICFree(g_connectedDeviceList);
2166 g_connectedDeviceList = NULL;
2167 ca_mutex_unlock(g_connectedDeviceListMutex);
2169 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2170 return CA_STATUS_OK;
2173 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2175 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2176 VERIFY_NON_NULL(env, TAG, "env is null");
2177 VERIFY_NON_NULL(address, TAG, "address is null");
2179 ca_mutex_lock(g_connectedDeviceListMutex);
2180 if (!g_connectedDeviceList)
2182 OIC_LOG(ERROR, TAG, "no deviceList");
2183 ca_mutex_unlock(g_connectedDeviceListMutex);
2184 return CA_STATUS_FAILED;
2187 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2188 for (uint32_t index = 0; index < length; index++)
2190 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2194 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2195 if (!jni_setAddress)
2197 OIC_LOG(ERROR, TAG, "wrong device address");
2200 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2203 OIC_LOG(ERROR, TAG, "setAddress is null");
2207 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2210 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2211 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2215 if (!strcmp(setAddress, remoteAddress))
2217 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2219 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2220 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2221 (*env)->DeleteGlobalRef(env, jarrayObj);
2224 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2226 OIC_LOG(ERROR, TAG, "List removal failed.");
2227 ca_mutex_unlock(g_connectedDeviceListMutex);
2228 return CA_STATUS_FAILED;
2230 ca_mutex_unlock(g_connectedDeviceListMutex);
2231 return CA_STATUS_OK;
2233 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2234 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2238 ca_mutex_unlock(g_connectedDeviceListMutex);
2240 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2242 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2243 return CA_STATUS_FAILED;
2246 JNIEXPORT void JNICALL
2247 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2250 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2251 VERIFY_NON_NULL_VOID(env, TAG, "env");
2252 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2253 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2255 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2258 JNIEXPORT void JNICALL
2259 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2263 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2264 VERIFY_NON_NULL_VOID(env, TAG, "env");
2265 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2266 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2268 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2271 JNIEXPORT void JNICALL
2272 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2273 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2275 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2276 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2278 VERIFY_NON_NULL_VOID(env, TAG, "env");
2279 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2280 VERIFY_NON_NULL_VOID(device, TAG, "device");
2283 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
2285 // STATE_DISCONNECTED
2286 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
2288 if (newState == state_connected)
2291 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2293 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2294 if (!jni_remoteAddress)
2296 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2300 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2303 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2307 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2309 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2310 CALEServerAddDeviceToList(env, device);
2312 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2314 else if (newState == state_disconnected)
2316 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2318 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2319 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2320 if (CA_STATUS_OK != ret)
2322 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2326 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2327 if (CA_STATUS_OK != ret)
2329 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2334 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2339 JNIEXPORT void JNICALL
2340 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2343 jobject gattService)
2345 VERIFY_NON_NULL_VOID(env, TAG, "env");
2346 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2347 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2349 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2352 JNIEXPORT void JNICALL
2353 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2354 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2356 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2357 VERIFY_NON_NULL_VOID(env, TAG, "env");
2358 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2359 VERIFY_NON_NULL_VOID(device, TAG, "device");
2360 VERIFY_NON_NULL_VOID(data, TAG, "data");
2363 JNIEXPORT void JNICALL
2364 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2365 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2367 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2368 VERIFY_NON_NULL_VOID(env, TAG, "env");
2369 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2370 VERIFY_NON_NULL_VOID(device, TAG, "device");
2371 VERIFY_NON_NULL_VOID(data, TAG, "data");
2373 // get Byte Array and covert to uint8_t*
2374 jint length = (*env)->GetArrayLength(env, data);
2377 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2379 uint8_t* requestData = NULL;
2380 requestData = OICMalloc(length);
2383 OIC_LOG(ERROR, TAG, "requestData is null");
2387 memcpy(requestData, jni_byte_requestData, length);
2388 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2390 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2393 OIC_LOG(ERROR, TAG, "jni_address is null");
2394 OICFree(requestData);
2398 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2401 OIC_LOG(ERROR, TAG, "address is null");
2402 OICFree(requestData);
2406 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2408 ca_mutex_lock(g_bleClientBDAddressMutex);
2409 uint32_t sentLength = 0;
2410 g_CABLEServerDataReceivedCallback(address, requestData, length,
2412 ca_mutex_unlock(g_bleClientBDAddressMutex);
2414 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2417 JNIEXPORT void JNICALL
2418 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2423 VERIFY_NON_NULL_VOID(env, TAG, "env");
2424 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2425 VERIFY_NON_NULL_VOID(device, TAG, "device");
2427 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2430 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2431 if (gatt_success != status) // error case
2433 OIC_LOG(ERROR, TAG, "it will be sent again.");
2435 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2436 if (CA_STATUS_OK != res)
2438 OIC_LOG(ERROR, TAG, "send has failed");
2440 if (g_obj_bluetoothDevice)
2442 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2443 g_obj_bluetoothDevice = NULL;
2446 ca_mutex_lock(g_threadSendNotifyMutex);
2447 g_isSignalSetFlag = true;
2448 ca_cond_signal(g_threadSendNotifyCond);
2449 ca_mutex_unlock(g_threadSendNotifyMutex);
2455 OIC_LOG(DEBUG, TAG, "notify success");
2457 if (g_obj_bluetoothDevice)
2459 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2460 g_obj_bluetoothDevice = NULL;
2463 // next data can be sent
2464 ca_mutex_lock(g_threadSendNotifyMutex);
2465 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2466 g_isSignalSetFlag = true;
2467 ca_cond_signal(g_threadSendNotifyCond);
2468 ca_mutex_unlock(g_threadSendNotifyMutex);
2473 JNIEXPORT void JNICALL
2474 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2476 jobject settingsInEffect)
2478 VERIFY_NON_NULL_VOID(env, TAG, "env");
2479 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2480 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2482 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2485 JNIEXPORT void JNICALL
2486 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2490 VERIFY_NON_NULL_VOID(env, TAG, "env");
2491 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2493 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2495 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2496 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2497 if (data_too_large == errorCode)
2499 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2507 CAResult_t CAStartLEGattServer()
2509 // start gatt service
2510 CALEServerStartMulticastServer();
2512 return CA_STATUS_OK;
2515 CAResult_t CAStopLEGattServer()
2517 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2521 OIC_LOG(ERROR, TAG, "g_jvm is null");
2522 return CA_STATUS_FAILED;
2525 bool isAttached = false;
2527 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2530 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2531 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2535 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2536 return CA_STATUS_FAILED;
2541 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2542 if (CA_STATUS_OK != ret)
2544 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2545 return CA_STATUS_FAILED;
2548 ret = CALEServerStopMulticastServer();
2549 if (CA_STATUS_OK != ret)
2551 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2552 return CA_STATUS_FAILED;
2555 ret = CALEServerDisconnectAllDevices(env);
2556 if (CA_STATUS_OK != ret)
2558 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2559 return CA_STATUS_FAILED;
2562 ret = CALEServerRemoveAllDevices(env);
2563 if (CA_STATUS_OK != ret)
2565 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2566 return CA_STATUS_FAILED;
2569 if (g_leAdvertiseCallback)
2571 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2574 if (g_bluetoothGattServer)
2576 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2579 if (g_bluetoothGattServerCallback)
2581 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2584 if (g_obj_bluetoothDevice)
2586 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2587 g_obj_bluetoothDevice = NULL;
2590 ca_mutex_lock(g_threadSendNotifyMutex);
2591 ca_cond_signal(g_threadSendNotifyCond);
2592 ca_mutex_unlock(g_threadSendNotifyMutex);
2594 g_isStartServer = false;
2598 (*g_jvm)->DetachCurrentThread(g_jvm);
2601 return CA_STATUS_OK;
2604 CAResult_t CAInitializeLEGattServer()
2606 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2607 return CALEServerInitialize();
2610 void CATerminateLEGattServer()
2612 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2613 CALEServerTerminate();
2616 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2618 ca_mutex_lock(g_bleReqRespCbMutex);
2619 g_CABLEServerDataReceivedCallback = callback;
2620 ca_mutex_unlock(g_bleReqRespCbMutex);
2623 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2625 g_serverErrorCallback = callback;
2628 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2629 const uint8_t *charValue,
2630 uint32_t charValueLen)
2632 CAResult_t result = CA_SEND_FAILED;
2633 VERIFY_NON_NULL(address, TAG, "env is null");
2634 VERIFY_NON_NULL(charValue, TAG, "device is null");
2638 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2644 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2645 uint32_t charValueLen)
2647 VERIFY_NON_NULL(charValue, TAG, "device is null");
2649 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2654 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2656 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2660 CAResult_t CALEServerInitMutexVaraibles()
2662 if (NULL == g_bleReqRespCbMutex)
2664 g_bleReqRespCbMutex = ca_mutex_new();
2665 if (NULL == g_bleReqRespCbMutex)
2667 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2668 return CA_STATUS_FAILED;
2672 if (NULL == g_bleClientBDAddressMutex)
2674 g_bleClientBDAddressMutex = ca_mutex_new();
2675 if (NULL == g_bleClientBDAddressMutex)
2677 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2678 return CA_STATUS_FAILED;
2682 if (NULL == g_connectedDeviceListMutex)
2684 g_connectedDeviceListMutex = ca_mutex_new();
2685 if (NULL == g_connectedDeviceListMutex)
2687 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2688 return CA_STATUS_FAILED;
2692 if (NULL == g_threadSendMutex)
2694 g_threadSendMutex = ca_mutex_new();
2695 if (NULL == g_threadSendMutex)
2697 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2698 return CA_STATUS_FAILED;
2702 if (NULL == g_threadSendNotifyMutex)
2704 g_threadSendNotifyMutex = ca_mutex_new();
2705 if (NULL == g_threadSendNotifyMutex)
2707 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2708 return CA_STATUS_FAILED;
2712 return CA_STATUS_OK;
2715 void CALEServerTerminateMutexVaraibles()
2717 ca_mutex_free(g_bleReqRespCbMutex);
2718 g_bleReqRespCbMutex = NULL;
2720 ca_mutex_free(g_bleClientBDAddressMutex);
2721 g_bleClientBDAddressMutex = NULL;
2723 ca_mutex_free(g_connectedDeviceListMutex);
2724 g_connectedDeviceListMutex = NULL;
2726 ca_mutex_free(g_threadSendMutex);
2727 g_threadSendMutex = NULL;
2729 ca_mutex_free(g_threadSendNotifyMutex);
2730 g_threadSendNotifyMutex = NULL;
2733 void CALEServerTerminateConditionVaraibles()
2735 OIC_LOG(DEBUG, TAG, "this method is not supported");