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";
71 static const char CLASSPATH_BT_GATTSERVER[] = "android/bluetooth/BluetoothGattServer";
73 void CALEServerJNISetContext()
75 OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
76 g_context = (jobject) CANativeJNIGetContext();
79 void CALeServerJniInit()
81 OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
82 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
85 CAResult_t CALEServerCreateJniInterfaceObject()
87 OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
91 OIC_LOG(ERROR, TAG, "g_context is null");
92 return CA_STATUS_FAILED;
97 OIC_LOG(ERROR, TAG, "g_jvm is null");
98 return CA_STATUS_FAILED;
101 bool isAttached = false;
103 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
106 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
107 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
111 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
112 return CA_STATUS_FAILED;
117 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
118 if (!jni_LEInterface)
120 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
124 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
126 if (!LeInterfaceConstructorMethod)
128 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
132 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
133 OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
137 (*g_jvm)->DetachCurrentThread(g_jvm);
146 (*g_jvm)->DetachCurrentThread(g_jvm);
149 return CA_STATUS_FAILED;
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.
158 static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
160 OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
162 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
163 VERIFY_NON_NULL_RET(device, TAG, "device", -1);
165 jmethodID jni_mid_getConnectionState = CAGetJNIMethodID(env, "android/bluetooth"
167 "getConnectionState",
168 "(Landroid/bluetooth/BluetoothDevice"
170 if (!jni_mid_getConnectionState)
172 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
176 if (!g_bluetoothManager)
178 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
182 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
183 jni_mid_getConnectionState,
184 device, GATT_PROFILE);
185 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
189 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
191 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
192 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
193 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
195 if (!g_bluetoothGattServer)
197 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
201 if (!CALEIsEnableBTAdapter(env))
203 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
207 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
208 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
210 "(Ljava/util/UUID;)Landroid/bluetooth/"
211 "BluetoothGattService;");
212 if (!jni_mid_getService)
214 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
218 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
219 if (!jni_obj_serviceUUID)
221 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
225 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
227 jni_obj_serviceUUID);
228 if (!jni_obj_bluetoothGattService)
230 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
234 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
235 "BluetoothGattService",
238 "Landroid/bluetooth/"
239 "BluetoothGattCharacteristic;");
240 if (!jni_mid_getCharacteristic)
242 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
246 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
247 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
248 if (!jni_obj_responseUUID)
250 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
254 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
255 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
256 if (!jni_obj_bluetoothGattCharacteristic)
258 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
262 jmethodID jni_mid_setValue = CAGetJNIMethodID(env, "android/bluetooth/"
263 "BluetoothGattCharacteristic",
264 "setValue", "([B)Z");
265 if (!jni_mid_setValue)
267 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
271 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
272 jni_obj_bluetoothGattCharacteristic,
273 jni_mid_setValue, responseData);
274 if (JNI_FALSE == jni_boolean_setValue)
276 OIC_LOG(ERROR, TAG, "Fail to set response data");
279 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
280 return jni_obj_bluetoothGattCharacteristic;
283 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
285 OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
286 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
287 VERIFY_NON_NULL(device, TAG, "device is null");
288 VERIFY_NON_NULL(env, TAG, "env is null");
290 if (!CALEIsEnableBTAdapter(env))
292 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
293 return CA_ADAPTER_NOT_ENABLED;
296 if (STATE_CONNECTED != CALEServerGetConnectionState(env, device))
298 OIC_LOG(ERROR, TAG, "it is not connected state");
299 return CA_STATUS_FAILED;
302 jmethodID jni_mid_notifyCharacteristicChanged = CAGetJNIMethodID(env,
303 CLASSPATH_BT_GATTSERVER,
304 "notifyCharacteristicChanged",
305 "(Landroid/bluetooth/BluetoothDevice;"
306 "Landroid/bluetooth/"
307 "BluetoothGattCharacteristic;Z)Z");
308 if (!jni_mid_notifyCharacteristicChanged)
310 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
311 return CA_STATUS_FAILED;
314 OIC_LOG(DEBUG, TAG, "CALL API - notifyCharacteristicChanged");
316 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
317 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
319 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
321 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
322 return CA_SEND_FAILED;
325 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
326 ca_mutex_lock(g_threadSendNotifyMutex);
327 if (!g_isSignalSetFlag)
329 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
330 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
331 WAIT_TIME_WRITE_CHARACTERISTIC))
333 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
334 ca_mutex_unlock(g_threadSendNotifyMutex);
335 return CA_STATUS_FAILED;
338 // reset flag set by writeCharacteristic Callback
339 g_isSignalSetFlag = false;
340 ca_mutex_unlock(g_threadSendNotifyMutex);
341 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
345 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
346 jint offset, jbyteArray value)
348 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
349 VERIFY_NON_NULL(env, TAG, "env is null");
350 VERIFY_NON_NULL(device, TAG, "device is null");
351 VERIFY_NON_NULL(value, TAG, "value is null");
353 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
355 if (!CALEIsEnableBTAdapter(env))
357 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
358 return CA_ADAPTER_NOT_ENABLED;
361 jmethodID jni_mid_sendResponse = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
363 "(Landroid/bluetooth/BluetoothDevice;"
365 if (!jni_mid_sendResponse)
367 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
368 return CA_STATUS_FAILED;
371 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
372 jni_mid_sendResponse, device,
373 requestId, status, offset,
375 if (JNI_FALSE == jni_boolean_sendResponse)
377 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
378 return CA_SEND_FAILED;
381 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
385 CAResult_t CALEStartAdvertise()
389 OIC_LOG(ERROR, TAG, "g_jvm is null");
390 return CA_STATUS_FAILED;
393 bool isAttached = false;
395 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
398 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
399 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
403 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
404 return CA_STATUS_FAILED;
410 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
411 if (CA_STATUS_OK != ret)
413 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
418 (*g_jvm)->DetachCurrentThread(g_jvm);
423 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
425 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
426 VERIFY_NON_NULL(env, TAG, "env is null");
427 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
429 if (!CALEIsEnableBTAdapter(env))
431 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
432 return CA_ADAPTER_NOT_ENABLED;
435 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
436 "android/bluetooth/le/"
437 "AdvertiseSettings$Builder");
438 if (!jni_cid_AdvertiseSettings)
440 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
441 return CA_STATUS_FAILED;
444 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
446 if (!jni_mid_AdvertiseSettings)
448 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
449 return CA_STATUS_FAILED;
452 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
453 jni_mid_AdvertiseSettings);
454 if (!jni_AdvertiseSettings)
456 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
457 return CA_STATUS_FAILED;
460 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
462 "(I)Landroid/bluetooth/le/"
463 "AdvertiseSettings$Builder;");
464 if (!jni_mid_setAdvertiseMode)
466 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
467 return CA_STATUS_FAILED;
470 // 0: Low power, 1: Balanced
471 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
472 jni_mid_setAdvertiseMode, 0);
473 if (!jni_obj_setAdvertiseMode)
475 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
476 return CA_STATUS_FAILED;
479 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
481 "(Z)Landroid/bluetooth/le/"
482 "AdvertiseSettings$Builder;");
483 if (!jni_mid_setConnectable)
485 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
486 return CA_STATUS_FAILED;
489 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
490 jni_mid_setConnectable, JNI_TRUE);
491 if (!jni_obj_setConnectable)
493 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
494 return CA_STATUS_FAILED;
497 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
498 "(I)Landroid/bluetooth/le/"
499 "AdvertiseSettings$Builder;");
500 if (!jni_mid_setTimeout)
502 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
503 return CA_STATUS_FAILED;
506 //A value of 0 will disable the time limit
507 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
508 jni_mid_setTimeout, 0);
509 if (!jni_obj_setTimeout)
511 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
512 return CA_STATUS_FAILED;
515 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
516 "android/bluetooth/le/"
517 "AdvertiseData$Builder");
518 if (!jni_cid_AdvertiseDataBuilder)
520 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
521 return CA_STATUS_FAILED;
524 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
526 if (!jni_mid_AdvertiseDataBuilder)
528 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
529 return CA_STATUS_FAILED;
532 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
533 jni_mid_AdvertiseDataBuilder);
534 if (!jni_AdvertiseDataBuilder)
536 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
537 return CA_STATUS_FAILED;
540 jobject jni_AdvertiseDataBuilderForScanRsp = (*env)->NewObject(env,
541 jni_cid_AdvertiseDataBuilder,
542 jni_mid_AdvertiseDataBuilder);
543 if (!jni_AdvertiseDataBuilderForScanRsp)
545 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilderForScanRsp is null");
546 return CA_STATUS_FAILED;
549 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
550 if (!jni_obj_serviceUUID)
552 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
553 return CA_STATUS_FAILED;
556 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
559 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
560 return CA_STATUS_FAILED;
563 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
565 "(Landroid/os/ParcelUuid;)Landroid/"
566 "bluetooth/le/AdvertiseData$Builder;");
567 if (!jni_mid_addServiceUuid)
569 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
570 return CA_STATUS_FAILED;
573 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
574 jni_mid_addServiceUuid,
576 if (!jni_obj_addServiceUuid)
578 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
579 return CA_STATUS_FAILED;
582 // Device name has to be included in advertise packet after Android API 23
583 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
584 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
585 "setIncludeDeviceName",
588 "AdvertiseData$Builder;");
589 if (!jni_mid_setIncludeDeviceName)
591 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
592 return CA_STATUS_FAILED;
595 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env,
596 jni_AdvertiseDataBuilderForScanRsp,
597 jni_mid_setIncludeDeviceName,
599 if (!jni_obj_setIncludeDeviceName)
601 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
602 return CA_STATUS_FAILED;
605 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
606 if (!jni_cid_BTAdapter)
608 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
609 return CA_STATUS_FAILED;
612 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
614 "()Landroid/bluetooth/"
615 "BluetoothAdapter;");
616 if (!jni_mid_getDefaultAdapter)
618 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
619 return CA_STATUS_FAILED;
622 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
623 jni_mid_getDefaultAdapter);
624 if (!jni_obj_BTAdapter)
626 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
627 return CA_STATUS_FAILED;
630 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
631 "getBluetoothLeAdvertiser",
632 "()Landroid/bluetooth/le/"
633 "BluetoothLeAdvertiser;");
634 if (!jni_mid_getBluetoothLeAdvertiser)
636 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
637 return CA_STATUS_FAILED;
640 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
641 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
642 if (!jni_obj_getBluetoothLeAdvertiser)
644 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
645 return CA_STATUS_FAILED;
648 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
649 jni_cid_AdvertiseSettings,
651 "()Landroid/bluetooth/le/"
652 "AdvertiseSettings;");
653 if (!jni_mid_build_LeAdvertiseSettings)
655 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
656 return CA_STATUS_FAILED;
659 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
660 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
661 if (!jni_obj_build_LeAdvertiseSettings)
663 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
664 return CA_STATUS_FAILED;
667 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
669 "()Landroid/bluetooth/le/"
671 if (!jni_mid_build_LeAdvertiseData)
673 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
674 return CA_STATUS_FAILED;
677 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
678 jni_mid_build_LeAdvertiseData);
679 if (!jni_obj_build_LeAdvertiseData)
681 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
682 return CA_STATUS_FAILED;
685 jobject jni_obj_build_LeAdvertiseDataForScanRsp = (*env)->CallObjectMethod(env,
686 jni_AdvertiseDataBuilderForScanRsp,
687 jni_mid_build_LeAdvertiseData);
688 if (!jni_obj_build_LeAdvertiseDataForScanRsp)
690 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseDataForScanRsp is null");
691 return CA_STATUS_FAILED;
694 jmethodID jni_mid_startAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
695 "BluetoothLeAdvertiser",
697 "(Landroid/bluetooth/le/"
698 "AdvertiseSettings;Landroid/bluetooth/"
699 "le/AdvertiseData;Landroid/bluetooth/"
700 "le/AdvertiseData;Landroid/bluetooth/"
701 "le/AdvertiseCallback;)V");
702 if (!jni_mid_startAdvertising)
704 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
705 return CA_STATUS_FAILED;
708 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
709 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
710 jni_obj_build_LeAdvertiseDataForScanRsp, advertiseCallback);
712 if ((*env)->ExceptionCheck(env))
714 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
715 (*env)->ExceptionDescribe(env);
716 (*env)->ExceptionClear(env);
717 return CA_STATUS_FAILED;
720 OIC_LOG(DEBUG, TAG, "Advertising started!!");
722 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
726 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
728 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
729 VERIFY_NON_NULL(env, TAG, "env is null");
730 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
732 if (!CALEIsEnableBTAdapter(env))
734 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
735 return CA_ADAPTER_NOT_ENABLED;
738 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
739 if (!jni_cid_BTAdapter)
741 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
742 return CA_STATUS_FAILED;
745 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
747 "()Landroid/bluetooth/"
748 "BluetoothAdapter;");
749 if (!jni_mid_getDefaultAdapter)
751 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
752 return CA_STATUS_FAILED;
755 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
756 "getBluetoothLeAdvertiser",
757 "()Landroid/bluetooth/le/"
758 "BluetoothLeAdvertiser;");
759 if (!jni_mid_getBTLeAdvertiser)
761 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
762 return CA_STATUS_FAILED;
765 jmethodID jni_mid_stopAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
766 "BluetoothLeAdvertiser",
768 "(Landroid/bluetooth/le/"
769 "AdvertiseCallback;)V");
770 if (!jni_mid_stopAdvertising)
772 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
773 return CA_STATUS_FAILED;
776 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
777 jni_mid_getDefaultAdapter);
778 if (!jni_obj_BTAdapter)
780 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
781 return CA_STATUS_FAILED;
784 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
785 jni_mid_getBTLeAdvertiser);
786 if (!jni_obj_getBluetoothLeAdvertiser)
788 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
789 return CA_STATUS_FAILED;
792 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
794 if ((*env)->ExceptionCheck(env))
796 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
797 (*env)->ExceptionDescribe(env);
798 (*env)->ExceptionClear(env);
799 return CA_STATUS_FAILED;
802 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
806 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
808 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
809 VERIFY_NON_NULL(env, TAG, "env is null");
810 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
812 if (!CALEIsEnableBTAdapter(env))
814 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
815 return CA_ADAPTER_NOT_ENABLED;
820 OIC_LOG(DEBUG, TAG, "Gatt server already started");
823 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
826 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
827 if (!bluetoothGattServer)
829 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
830 return CA_STATUS_FAILED;
833 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
834 if (!g_bluetoothGattServer)
836 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
837 return CA_STATUS_FAILED;
840 // create gatt service
841 jobject bluetoothGattService = CALEServerCreateGattService(env);
842 if (!bluetoothGattService)
844 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
845 return CA_STATUS_FAILED;
849 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
850 bluetoothGattService);
851 if (CA_STATUS_OK != res)
853 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
858 jobject CALEServerOpenGattServer(JNIEnv *env)
860 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
861 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
863 if (!CALEIsEnableBTAdapter(env))
865 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
869 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
870 if (!jni_cid_context)
872 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
876 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
878 "Ljava/lang/String;");
879 if (!jni_fid_bluetoothService)
881 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
885 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
887 "(Ljava/lang/String;)"
888 "Ljava/lang/Object;");
889 if (!jni_mid_getSystemService)
891 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
895 jmethodID jni_mid_openGattServer = CAGetJNIMethodID(env, "android/bluetooth/"
898 "(Landroid/content/Context;"
899 "Landroid/bluetooth/"
900 "BluetoothGattServerCallback;)"
901 "Landroid/bluetooth/"
902 "BluetoothGattServer;");
903 if (!jni_mid_openGattServer)
905 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
909 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
910 jni_fid_bluetoothService);
911 if (!jni_obj_bluetoothService)
913 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
917 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
918 jni_mid_getSystemService,
919 jni_obj_bluetoothService);
920 if (!jni_obj_bluetoothManager)
922 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
926 if (g_bluetoothManager)
928 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
930 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
932 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
933 jni_mid_openGattServer,
935 g_bluetoothGattServerCallback);
936 if (!jni_obj_bluetoothGattServer)
938 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
942 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
943 return jni_obj_bluetoothGattServer;
946 jobject CALEServerCreateGattService(JNIEnv *env)
948 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
949 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
951 if (!CALEIsEnableBTAdapter(env))
953 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
957 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
958 "BluetoothGattService");
959 if (!jni_cid_bluetoothGattService)
961 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
965 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
966 "BluetoothGattCharacteristic");
967 if (!jni_cid_bluetoothGattCharacteristic)
969 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
973 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
974 "SERVICE_TYPE_PRIMARY", "I");
975 if (!jni_fid_serviceType)
977 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
981 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
982 jni_cid_bluetoothGattCharacteristic,
983 "PROPERTY_NOTIFY", "I");
984 if (!jni_fid_readProperties)
986 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
990 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
991 jni_cid_bluetoothGattCharacteristic,
992 "PROPERTY_WRITE_NO_RESPONSE", "I");
993 if (!jni_fid_writeProperties)
995 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
999 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1000 jni_cid_bluetoothGattCharacteristic,
1001 "PERMISSION_READ", "I");
1002 if (!jni_fid_readPermissions)
1004 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1008 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1009 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1010 if (!jni_fid_writePermissions)
1012 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1016 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1017 "<init>", "(Ljava/util/UUID;I)V");
1018 if (!jni_mid_bluetoothGattService)
1020 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1024 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1025 "addCharacteristic",
1026 "(Landroid/bluetooth/"
1027 "BluetoothGattCharacteristic;)Z");
1028 if (!jni_mid_addCharacteristic)
1030 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1034 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1035 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1036 if (!jni_mid_bluetoothGattCharacteristic)
1038 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1042 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1043 if (!jni_obj_serviceUUID)
1045 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1049 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1050 jni_fid_serviceType);
1051 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1052 jni_mid_bluetoothGattService,
1053 jni_obj_serviceUUID, jni_int_serviceType);
1054 if (!jni_bluetoothGattService)
1056 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1060 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1061 if (!jni_obj_readUuid)
1063 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1067 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1068 jni_cid_bluetoothGattCharacteristic,
1069 jni_fid_readProperties);
1071 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1072 jni_cid_bluetoothGattCharacteristic,
1073 jni_fid_readPermissions);
1075 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1076 jni_cid_bluetoothGattCharacteristic,
1077 jni_fid_writePermissions);
1079 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1080 jni_mid_bluetoothGattCharacteristic,
1081 jni_obj_readUuid, jni_int_readProperties,
1082 jni_int_readPermissions|
1083 jni_int_writePermissions);
1084 if (!jni_readCharacteristic)
1086 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1090 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1091 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1092 if (!jni_boolean_addReadCharacteristic)
1094 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1098 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1099 if (!jni_obj_writeUuid)
1101 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1105 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1106 jni_cid_bluetoothGattCharacteristic,
1107 jni_fid_writeProperties);
1109 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1110 jni_mid_bluetoothGattCharacteristic,
1111 jni_obj_writeUuid, jni_int_writeProperties,
1112 jni_int_writePermissions);
1113 if (!jni_writeCharacteristic)
1115 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1119 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1120 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1121 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1123 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1127 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1128 return jni_bluetoothGattService;
1131 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1133 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1134 VERIFY_NON_NULL(env, TAG, "env is null");
1135 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1137 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1138 "BluetoothGattDescriptor");
1139 if (!jni_cid_bluetoothGattDescriptor)
1141 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1142 return CA_STATUS_FAILED;
1145 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1146 jni_cid_bluetoothGattDescriptor,
1148 "(Ljava/util/UUID;I)V");
1149 if (!jni_mid_bluetoothGattDescriptor)
1151 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1152 return CA_STATUS_FAILED;
1155 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1156 jni_cid_bluetoothGattDescriptor,
1157 "PERMISSION_READ", "I");
1158 if (!jni_fid_readPermissions)
1160 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1161 return CA_STATUS_FAILED;
1164 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1165 if (!jni_obj_readUuid)
1167 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1168 return CA_STATUS_FAILED;
1171 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1172 jni_fid_readPermissions);
1174 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1176 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1177 jni_mid_bluetoothGattDescriptor,
1178 jni_obj_readUuid, jni_int_readPermissions);
1179 if (!jni_readDescriptor)
1181 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1182 return CA_STATUS_FAILED;
1185 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1186 "BluetoothGattCharacteristic");
1187 if (!jni_cid_GattCharacteristic)
1189 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1190 return CA_STATUS_FAILED;
1193 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1195 "(Landroid/bluetooth/"
1196 "BluetoothGattDescriptor;)Z");
1197 if (!jni_mid_addDescriptor)
1199 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1200 return CA_STATUS_FAILED;
1203 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1204 jni_mid_addDescriptor,
1205 jni_readDescriptor);
1207 if (JNI_FALSE == jni_boolean_addDescriptor)
1209 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1210 return CA_STATUS_FAILED;
1214 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1216 return CA_STATUS_OK;
1219 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1220 jobject bluetoothGattService)
1222 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1223 VERIFY_NON_NULL(env, TAG, "env is null");
1224 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1225 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1227 if (!CALEIsEnableBTAdapter(env))
1229 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1230 return CA_ADAPTER_NOT_ENABLED;
1233 jmethodID jni_mid_addService = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1235 "(Landroid/bluetooth/BluetoothGattService;)"
1237 if (!jni_mid_addService)
1239 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1240 return CA_STATUS_FAILED;
1243 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1245 bluetoothGattService);
1247 if (JNI_FALSE == jni_boolean_addService)
1249 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1250 return CA_STATUS_FAILED;
1253 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1254 return CA_STATUS_OK;
1257 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1259 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1260 VERIFY_NON_NULL(env, TAG, "env is null");
1261 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1263 if (!CALEIsEnableBTAdapter(env))
1265 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1266 return CA_ADAPTER_NOT_ENABLED;
1269 jmethodID jni_mid_connect = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1271 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1272 if (!jni_mid_connect)
1274 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1275 return CA_STATUS_FAILED;
1278 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1279 jni_mid_connect, bluetoothDevice,
1281 if (JNI_FALSE == jni_boolean_connect)
1283 OIC_LOG(ERROR, TAG, "Fail to connect");
1284 return CA_STATUS_FAILED;
1287 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1288 return CA_STATUS_OK;
1291 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1293 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1294 VERIFY_NON_NULL(env, TAG, "env is null");
1296 ca_mutex_lock(g_connectedDeviceListMutex);
1297 if (!g_connectedDeviceList)
1299 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1300 ca_mutex_unlock(g_connectedDeviceListMutex);
1301 return CA_STATUS_FAILED;
1304 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1305 for (uint32_t index = 0; index < length; index++)
1307 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1310 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1314 // disconnect for device obj
1315 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1316 if (CA_STATUS_OK != res)
1318 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1323 ca_mutex_unlock(g_connectedDeviceListMutex);
1324 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1325 return CA_STATUS_OK;
1328 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1330 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1331 VERIFY_NON_NULL(env, TAG, "env is null");
1332 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1334 if (!CALEIsEnableBTAdapter(env))
1336 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1337 return CA_ADAPTER_NOT_ENABLED;
1340 jmethodID jni_mid_cancelConnection = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1342 "(Landroid/bluetooth/BluetoothDevice;)"
1344 if (!jni_mid_cancelConnection)
1346 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1347 return CA_STATUS_FAILED;
1350 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1352 if ((*env)->ExceptionCheck(env))
1354 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1355 (*env)->ExceptionDescribe(env);
1356 (*env)->ExceptionClear(env);
1357 return CA_STATUS_FAILED;
1360 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1361 return CA_STATUS_OK;
1364 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1367 OIC_LOG(DEBUG, TAG, "GattServer Close");
1368 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1369 VERIFY_NON_NULL(env, TAG, "env is null");
1371 // get BluetoothGatt class
1372 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1373 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1375 if (!jni_mid_closeGatt)
1377 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1378 return CA_STATUS_OK;
1381 // call disconnect gatt method
1382 OIC_LOG(DEBUG, TAG, "request to close GATT");
1383 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1385 if ((*env)->ExceptionCheck(env))
1387 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1388 (*env)->ExceptionDescribe(env);
1389 (*env)->ExceptionClear(env);
1390 return CA_STATUS_FAILED;
1393 return CA_STATUS_OK;
1396 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1398 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1399 VERIFY_NON_NULL(env, TAG, "env is null");
1400 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1401 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1403 if (!CALEIsEnableBTAdapter(env))
1405 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1406 return CA_ADAPTER_NOT_ENABLED;
1409 jobject responseChar = CALEServerSetResponseData(env, responseData);
1412 OIC_LOG(ERROR, TAG, "responseChar is null");
1413 return CA_STATUS_FAILED;
1416 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1417 if (CA_STATUS_OK != result)
1419 OIC_LOG(ERROR, TAG, "Fail to send response data");
1423 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1427 CAResult_t CALEServerInitialize()
1429 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1431 CALeServerJniInit();
1435 OIC_LOG(ERROR, TAG, "g_jvm is null");
1436 return CA_STATUS_FAILED;
1439 bool isAttached = false;
1441 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1444 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1445 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1449 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1450 return CA_STATUS_FAILED;
1455 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1456 if (CA_STATUS_OK != ret)
1458 OIC_LOG(ERROR, TAG, "it is not supported");
1462 (*g_jvm)->DetachCurrentThread(g_jvm);
1467 g_threadSendNotifyCond = ca_cond_new();
1469 ret = CALEServerInitMutexVaraibles();
1470 if (CA_STATUS_OK != ret)
1472 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1476 (*g_jvm)->DetachCurrentThread(g_jvm);
1478 return CA_STATUS_FAILED;
1481 CALEServerJNISetContext();
1482 CALEServerCreateCachedDeviceList();
1484 ret = CALEServerCreateJniInterfaceObject();
1485 if (CA_STATUS_OK != ret)
1487 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1491 (*g_jvm)->DetachCurrentThread(g_jvm);
1493 return CA_STATUS_FAILED;
1498 (*g_jvm)->DetachCurrentThread(g_jvm);
1501 g_isInitializedServer = true;
1502 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1503 return CA_STATUS_OK;
1506 void CALEServerTerminate()
1508 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1512 OIC_LOG(ERROR, TAG, "g_jvm is null");
1516 bool isAttached = false;
1518 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1521 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1522 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1526 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1534 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1535 g_sendBuffer = NULL;
1538 if (g_bluetoothManager)
1540 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1541 g_bluetoothManager = NULL;
1544 ca_cond_free(g_threadSendNotifyCond);
1545 g_threadSendNotifyCond = NULL;
1547 CALEServerTerminateMutexVaraibles();
1548 CALEServerTerminateConditionVaraibles();
1550 g_isInitializedServer = false;
1554 (*g_jvm)->DetachCurrentThread(g_jvm);
1557 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1560 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1562 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1563 VERIFY_NON_NULL(address, TAG, "address is null");
1564 VERIFY_NON_NULL(data, TAG, "data is null");
1568 OIC_LOG(ERROR, TAG, "g_jvm is null");
1569 return CA_STATUS_FAILED;
1572 bool isAttached = false;
1574 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1577 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1578 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1582 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1583 return CA_STATUS_FAILED;
1588 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1589 if (CA_STATUS_OK != ret)
1591 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1596 (*g_jvm)->DetachCurrentThread(g_jvm);
1602 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1604 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1605 VERIFY_NON_NULL(data, TAG, "data is null");
1609 OIC_LOG(ERROR, TAG, "g_jvm is null");
1610 return CA_STATUS_FAILED;
1613 bool isAttached = false;
1615 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1618 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1619 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1623 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1624 return CA_STATUS_FAILED;
1629 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1630 if (CA_STATUS_OK != ret)
1632 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1637 (*g_jvm)->DetachCurrentThread(g_jvm);
1643 CAResult_t CALEServerStartMulticastServer()
1645 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1647 if (!g_isInitializedServer)
1649 OIC_LOG(INFO, TAG, "server is not initialized");
1650 return CA_STATUS_FAILED;
1653 if (g_isStartServer)
1655 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1656 return CA_STATUS_FAILED;
1661 OIC_LOG(ERROR, TAG, "g_jvm is null");
1662 return CA_STATUS_FAILED;
1665 bool isAttached = false;
1667 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1670 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1671 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1675 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1676 return CA_STATUS_FAILED;
1681 g_isStartServer = true;
1683 // start gatt server
1684 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1685 if (CA_STATUS_OK != ret)
1687 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1692 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1693 if (CA_STATUS_OK != ret)
1695 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1700 (*g_jvm)->DetachCurrentThread(g_jvm);
1703 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1707 CAResult_t CALEServerStopMulticastServer()
1709 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1711 if (false == g_isStartServer)
1713 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1714 return CA_STATUS_FAILED;
1719 OIC_LOG(ERROR, TAG, "g_jvm is null");
1720 return CA_STATUS_FAILED;
1723 bool isAttached = false;
1725 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1728 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1729 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1733 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1734 return CA_STATUS_FAILED;
1739 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1740 if (CA_STATUS_OK != ret)
1742 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1745 g_isStartServer = false;
1749 (*g_jvm)->DetachCurrentThread(g_jvm);
1752 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1756 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1758 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1759 g_packetReceiveCallback = callback;
1762 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1765 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1767 VERIFY_NON_NULL(env, TAG, "env is null");
1768 VERIFY_NON_NULL(address, TAG, "address is null");
1769 VERIFY_NON_NULL(data, TAG, "data is null");
1771 if (!g_connectedDeviceList)
1773 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1774 return CA_STATUS_FAILED;
1777 ca_mutex_lock(g_threadSendMutex);
1779 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1780 for (uint32_t index = 0; index < length; index++)
1782 OIC_LOG(DEBUG, TAG, "check device address");
1783 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1786 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1790 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1791 if (!jni_setAddress)
1793 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1796 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1799 OIC_LOG(ERROR, TAG, "setAddress is null");
1803 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1804 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1806 if (!strcmp(setAddress, address))
1808 OIC_LOG(DEBUG, TAG, "found the device");
1810 if (g_obj_bluetoothDevice)
1812 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1813 g_obj_bluetoothDevice = NULL;
1818 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1820 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1823 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1826 if (g_obj_bluetoothDevice)
1828 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1829 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1830 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1832 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1833 if (CA_STATUS_OK != res)
1835 OIC_LOG(ERROR, TAG, "send has failed");
1841 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1847 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1848 g_sendBuffer = NULL;
1851 ca_mutex_unlock(g_threadSendMutex);
1852 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1853 return CA_STATUS_OK;
1858 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1859 g_sendBuffer = NULL;
1862 if (g_obj_bluetoothDevice)
1864 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1865 g_obj_bluetoothDevice = NULL;
1868 ca_mutex_unlock(g_threadSendMutex);
1869 return CA_SEND_FAILED;
1872 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1874 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1875 VERIFY_NON_NULL(env, TAG, "env is null");
1876 VERIFY_NON_NULL(data, TAG, "data is null");
1878 if (!g_connectedDeviceList)
1880 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1881 return CA_STATUS_FAILED;
1884 ca_mutex_lock(g_threadSendMutex);
1886 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1889 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1890 g_sendBuffer = NULL;
1892 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1893 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1894 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1896 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1897 for (uint32_t index = 0; index < length; index++)
1899 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1902 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1906 // send data for all device
1907 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1908 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1910 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1913 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1917 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1920 OIC_LOG(ERROR, TAG, "address is not available");
1924 if (g_obj_bluetoothDevice)
1926 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1927 g_obj_bluetoothDevice = NULL;
1932 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1935 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
1936 if (CA_STATUS_OK != res)
1938 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
1939 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1940 if (g_obj_bluetoothDevice)
1942 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1943 g_obj_bluetoothDevice = NULL;
1948 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
1949 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1954 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1955 g_sendBuffer = NULL;
1958 ca_mutex_unlock(g_threadSendMutex);
1959 return CA_STATUS_OK;
1962 void CALEServerCreateCachedDeviceList()
1964 ca_mutex_lock(g_connectedDeviceListMutex);
1965 // create new object array
1966 if (!g_connectedDeviceList)
1968 OIC_LOG(DEBUG, TAG, "Create device list");
1969 g_connectedDeviceList = u_arraylist_create();
1971 ca_mutex_unlock(g_connectedDeviceListMutex);
1974 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1976 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1977 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1979 if (!g_connectedDeviceList)
1981 OIC_LOG(ERROR, TAG, "list is null");
1985 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1986 for (uint32_t index = 0; index < length; index++)
1988 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1992 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1996 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1997 if (!jni_setAddress)
1999 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2003 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2006 OIC_LOG(ERROR, TAG, "setAddress is null");
2010 if (!strcmp(remoteAddress, setAddress))
2012 OIC_LOG(ERROR, TAG, "the device is already set");
2013 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2018 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2023 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2027 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2029 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2030 VERIFY_NON_NULL(device, TAG, "device is null");
2031 VERIFY_NON_NULL(env, TAG, "env is null");
2033 ca_mutex_lock(g_connectedDeviceListMutex);
2035 if (!g_connectedDeviceList)
2037 OIC_LOG(ERROR, TAG, "list is null");
2038 ca_mutex_unlock(g_connectedDeviceListMutex);
2039 return CA_STATUS_FAILED;
2042 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2043 if (!jni_remoteAddress)
2045 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2046 ca_mutex_unlock(g_connectedDeviceListMutex);
2047 return CA_STATUS_FAILED;
2050 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2053 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2054 ca_mutex_unlock(g_connectedDeviceListMutex);
2055 return CA_STATUS_FAILED;
2058 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2060 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2061 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2062 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2065 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2066 ca_mutex_unlock(g_connectedDeviceListMutex);
2067 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2068 return CA_STATUS_OK;
2071 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2073 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2074 VERIFY_NON_NULL(env, TAG, "env is null");
2076 ca_mutex_lock(g_connectedDeviceListMutex);
2077 if (!g_connectedDeviceList)
2079 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2080 ca_mutex_unlock(g_connectedDeviceListMutex);
2081 return CA_STATUS_FAILED;
2084 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2085 for (uint32_t index = 0; index < length; index++)
2087 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2090 (*env)->DeleteGlobalRef(env, jarrayObj);
2094 OICFree(g_connectedDeviceList);
2095 g_connectedDeviceList = NULL;
2096 ca_mutex_unlock(g_connectedDeviceListMutex);
2098 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2099 return CA_STATUS_OK;
2102 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2104 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2105 VERIFY_NON_NULL(env, TAG, "env is null");
2106 VERIFY_NON_NULL(address, TAG, "address is null");
2108 ca_mutex_lock(g_connectedDeviceListMutex);
2109 if (!g_connectedDeviceList)
2111 OIC_LOG(ERROR, TAG, "no deviceList");
2112 ca_mutex_unlock(g_connectedDeviceListMutex);
2113 return CA_STATUS_FAILED;
2116 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2117 for (uint32_t index = 0; index < length; index++)
2119 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2123 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2124 if (!jni_setAddress)
2126 OIC_LOG(ERROR, TAG, "wrong device address");
2129 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2132 OIC_LOG(ERROR, TAG, "setAddress is null");
2136 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2139 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2140 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2144 if (!strcmp(setAddress, remoteAddress))
2146 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2148 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2149 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2150 (*env)->DeleteGlobalRef(env, jarrayObj);
2153 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2155 OIC_LOG(ERROR, TAG, "List removal failed.");
2156 ca_mutex_unlock(g_connectedDeviceListMutex);
2157 return CA_STATUS_FAILED;
2159 ca_mutex_unlock(g_connectedDeviceListMutex);
2160 return CA_STATUS_OK;
2162 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2163 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2167 ca_mutex_unlock(g_connectedDeviceListMutex);
2169 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2171 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2172 return CA_STATUS_FAILED;
2175 JNIEXPORT void JNICALL
2176 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2179 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2180 VERIFY_NON_NULL_VOID(env, TAG, "env");
2181 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2182 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2184 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2187 JNIEXPORT void JNICALL
2188 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2192 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2193 VERIFY_NON_NULL_VOID(env, TAG, "env");
2194 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2195 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2197 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2200 JNIEXPORT void JNICALL
2201 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2202 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2204 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2205 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2207 VERIFY_NON_NULL_VOID(env, TAG, "env");
2208 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2209 VERIFY_NON_NULL_VOID(device, TAG, "device");
2212 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
2214 // STATE_DISCONNECTED
2215 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
2217 if (newState == state_connected)
2220 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2222 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2223 if (!jni_remoteAddress)
2225 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2229 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2232 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2236 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2238 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2239 CALEServerAddDeviceToList(env, device);
2241 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2243 else if (newState == state_disconnected)
2245 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2247 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2248 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2249 if (CA_STATUS_OK != ret)
2251 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2255 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2256 if (CA_STATUS_OK != ret)
2258 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2263 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2268 JNIEXPORT void JNICALL
2269 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2272 jobject gattService)
2274 VERIFY_NON_NULL_VOID(env, TAG, "env");
2275 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2276 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2278 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2281 JNIEXPORT void JNICALL
2282 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2283 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2285 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2286 VERIFY_NON_NULL_VOID(env, TAG, "env");
2287 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2288 VERIFY_NON_NULL_VOID(device, TAG, "device");
2289 VERIFY_NON_NULL_VOID(data, TAG, "data");
2292 JNIEXPORT void JNICALL
2293 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2294 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2296 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2297 VERIFY_NON_NULL_VOID(env, TAG, "env");
2298 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2299 VERIFY_NON_NULL_VOID(device, TAG, "device");
2300 VERIFY_NON_NULL_VOID(data, TAG, "data");
2302 // get Byte Array and covert to uint8_t*
2303 jint length = (*env)->GetArrayLength(env, data);
2306 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2308 uint8_t* requestData = NULL;
2309 requestData = OICMalloc(length);
2312 OIC_LOG(ERROR, TAG, "requestData is null");
2316 memcpy(requestData, jni_byte_requestData, length);
2317 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2319 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2322 OIC_LOG(ERROR, TAG, "jni_address is null");
2323 OICFree(requestData);
2327 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2330 OIC_LOG(ERROR, TAG, "address is null");
2331 OICFree(requestData);
2335 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2337 ca_mutex_lock(g_bleClientBDAddressMutex);
2338 uint32_t sentLength = 0;
2339 g_CABLEServerDataReceivedCallback(address, requestData, length,
2341 ca_mutex_unlock(g_bleClientBDAddressMutex);
2343 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2346 JNIEXPORT void JNICALL
2347 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2352 VERIFY_NON_NULL_VOID(env, TAG, "env");
2353 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2354 VERIFY_NON_NULL_VOID(device, TAG, "device");
2356 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2359 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2360 if (gatt_success != status) // error case
2362 OIC_LOG(ERROR, TAG, "it will be sent again.");
2364 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2365 if (CA_STATUS_OK != res)
2367 OIC_LOG(ERROR, TAG, "send has failed");
2369 if (g_obj_bluetoothDevice)
2371 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2372 g_obj_bluetoothDevice = NULL;
2375 ca_mutex_lock(g_threadSendNotifyMutex);
2376 g_isSignalSetFlag = true;
2377 ca_cond_signal(g_threadSendNotifyCond);
2378 ca_mutex_unlock(g_threadSendNotifyMutex);
2384 OIC_LOG(DEBUG, TAG, "notify success");
2386 if (g_obj_bluetoothDevice)
2388 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2389 g_obj_bluetoothDevice = NULL;
2392 // next data can be sent
2393 ca_mutex_lock(g_threadSendNotifyMutex);
2394 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2395 g_isSignalSetFlag = true;
2396 ca_cond_signal(g_threadSendNotifyCond);
2397 ca_mutex_unlock(g_threadSendNotifyMutex);
2402 JNIEXPORT void JNICALL
2403 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2405 jobject settingsInEffect)
2407 VERIFY_NON_NULL_VOID(env, TAG, "env");
2408 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2409 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2411 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2414 JNIEXPORT void JNICALL
2415 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2419 VERIFY_NON_NULL_VOID(env, TAG, "env");
2420 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2422 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2424 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2425 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2426 jint already_started = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2427 "ADVERTISE_FAILED_ALREADY_STARTED");
2429 if (data_too_large == errorCode)
2431 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2433 else if (already_started == errorCode)
2435 OIC_LOG_V(INFO, TAG, "advertising is already started");
2443 CAResult_t CAStartLEGattServer()
2445 // start gatt service
2446 CALEServerStartMulticastServer();
2448 return CA_STATUS_OK;
2451 CAResult_t CAStopLEGattServer()
2453 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2457 OIC_LOG(ERROR, TAG, "g_jvm is null");
2458 return CA_STATUS_FAILED;
2461 bool isAttached = false;
2463 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2466 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2467 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2471 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2472 return CA_STATUS_FAILED;
2477 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2478 if (CA_STATUS_OK != ret)
2480 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2481 return CA_STATUS_FAILED;
2484 ret = CALEServerStopMulticastServer();
2485 if (CA_STATUS_OK != ret)
2487 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2488 return CA_STATUS_FAILED;
2491 ret = CALEServerDisconnectAllDevices(env);
2492 if (CA_STATUS_OK != ret)
2494 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2495 return CA_STATUS_FAILED;
2498 ret = CALEServerRemoveAllDevices(env);
2499 if (CA_STATUS_OK != ret)
2501 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2502 return CA_STATUS_FAILED;
2505 if (g_leAdvertiseCallback)
2507 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2510 if (g_bluetoothGattServer)
2512 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2515 if (g_bluetoothGattServerCallback)
2517 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2520 if (g_obj_bluetoothDevice)
2522 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2523 g_obj_bluetoothDevice = NULL;
2526 ca_mutex_lock(g_threadSendNotifyMutex);
2527 ca_cond_signal(g_threadSendNotifyCond);
2528 ca_mutex_unlock(g_threadSendNotifyMutex);
2530 g_isStartServer = false;
2534 (*g_jvm)->DetachCurrentThread(g_jvm);
2537 return CA_STATUS_OK;
2540 CAResult_t CAInitializeLEGattServer()
2542 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2543 return CALEServerInitialize();
2546 void CATerminateLEGattServer()
2548 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2549 CALEServerTerminate();
2552 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2554 ca_mutex_lock(g_bleReqRespCbMutex);
2555 g_CABLEServerDataReceivedCallback = callback;
2556 ca_mutex_unlock(g_bleReqRespCbMutex);
2559 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2561 g_serverErrorCallback = callback;
2564 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2565 const uint8_t *charValue,
2566 uint32_t charValueLen)
2568 CAResult_t result = CA_SEND_FAILED;
2569 VERIFY_NON_NULL(address, TAG, "env is null");
2570 VERIFY_NON_NULL(charValue, TAG, "device is null");
2574 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2580 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2581 uint32_t charValueLen)
2583 VERIFY_NON_NULL(charValue, TAG, "device is null");
2585 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2590 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2592 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2596 CAResult_t CALEServerInitMutexVaraibles()
2598 if (NULL == g_bleReqRespCbMutex)
2600 g_bleReqRespCbMutex = ca_mutex_new();
2601 if (NULL == g_bleReqRespCbMutex)
2603 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2604 return CA_STATUS_FAILED;
2608 if (NULL == g_bleClientBDAddressMutex)
2610 g_bleClientBDAddressMutex = ca_mutex_new();
2611 if (NULL == g_bleClientBDAddressMutex)
2613 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2614 return CA_STATUS_FAILED;
2618 if (NULL == g_connectedDeviceListMutex)
2620 g_connectedDeviceListMutex = ca_mutex_new();
2621 if (NULL == g_connectedDeviceListMutex)
2623 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2624 return CA_STATUS_FAILED;
2628 if (NULL == g_threadSendMutex)
2630 g_threadSendMutex = ca_mutex_new();
2631 if (NULL == g_threadSendMutex)
2633 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2634 return CA_STATUS_FAILED;
2638 if (NULL == g_threadSendNotifyMutex)
2640 g_threadSendNotifyMutex = ca_mutex_new();
2641 if (NULL == g_threadSendNotifyMutex)
2643 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2644 return CA_STATUS_FAILED;
2648 return CA_STATUS_OK;
2651 void CALEServerTerminateMutexVaraibles()
2653 ca_mutex_free(g_bleReqRespCbMutex);
2654 g_bleReqRespCbMutex = NULL;
2656 ca_mutex_free(g_bleClientBDAddressMutex);
2657 g_bleClientBDAddressMutex = NULL;
2659 ca_mutex_free(g_connectedDeviceListMutex);
2660 g_connectedDeviceListMutex = NULL;
2662 ca_mutex_free(g_threadSendMutex);
2663 g_threadSendMutex = NULL;
2665 ca_mutex_free(g_threadSendNotifyMutex);
2666 g_threadSendNotifyMutex = NULL;
2669 void CALEServerTerminateConditionVaraibles()
2671 OIC_LOG(DEBUG, TAG, "this method is not supported");