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"
30 #include "calestate.h"
33 #include "oic_malloc.h"
34 #include "cathreadpool.h"
36 #include "uarraylist.h"
37 #include "org_iotivity_ca_CaLeServerInterface.h"
39 #define TAG PCF("OIC_CA_LE_SERVER")
41 #define WAIT_TIME_WRITE_CHARACTERISTIC 10000000
42 #define INVALID_STATE -1
44 static JavaVM *g_jvm = NULL;
45 static jobject g_context = NULL;
46 static jobject g_bluetoothGattServer = NULL;
47 static jobject g_bluetoothGattServerCallback = NULL;
48 static jobject g_leAdvertiseCallback = NULL;
49 static jobject g_bluetoothManager = NULL;
51 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
52 static CABLEErrorHandleCallback g_serverErrorCallback;
54 static u_arraylist_t *g_connectedDeviceList = NULL;
55 static u_arraylist_t *g_deviceStateList = NULL;
57 static bool g_isStartServer = false;
58 static bool g_isInitializedServer = false;
60 static jbyteArray g_sendBuffer = NULL;
61 static jobject g_obj_bluetoothDevice = NULL;
63 static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
64 static oc_mutex g_bleReqRespCbMutex = NULL;
65 static oc_mutex g_bleClientBDAddressMutex = NULL;
66 static oc_mutex g_connectedDeviceListMutex = NULL;
68 static oc_mutex g_threadSendMutex = NULL;
69 static oc_mutex g_threadSendNotifyMutex = NULL;
70 static oc_cond g_threadSendNotifyCond = NULL;
71 static bool g_isSignalSetFlag = false;
73 static oc_mutex g_deviceStateListMutex = NULL;
75 static jint g_state_connected = INVALID_STATE;
76 static jint g_state_disconnected = INVALID_STATE;
78 static const char CLASSPATH_BT_ADVERTISE_CB[] = "android/bluetooth/le/AdvertiseCallback";
79 static const char CLASSPATH_BT_GATTSERVER[] = "android/bluetooth/BluetoothGattServer";
81 static bool g_setHighQoS = true;
83 void CALEServerJNISetContext()
85 OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
86 g_context = (jobject) CANativeJNIGetContext();
89 void CALeServerJniInit()
91 OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
92 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
95 CAResult_t CALEServerCreateJniInterfaceObject()
97 OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
99 VERIFY_NON_NULL_RET(g_context, TAG, "g_context is null",CA_STATUS_FAILED);
100 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
103 bool isAttached = false;
104 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
105 return CA_STATUS_FAILED;
108 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
109 if (!jni_LEInterface)
111 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
115 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
117 if (!LeInterfaceConstructorMethod)
119 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
123 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
124 OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
128 (*g_jvm)->DetachCurrentThread(g_jvm);
137 (*g_jvm)->DetachCurrentThread(g_jvm);
140 return CA_STATUS_FAILED;
144 * get the current connection state of the gatt profile to the remote device.
145 * @param[in] env JNI interface pointer.
146 * @param[in] device bluetooth device object
147 * @return state of the profile connection.
149 static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
151 OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
153 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
154 VERIFY_NON_NULL_RET(device, TAG, "device", -1);
156 jmethodID jni_mid_getConnectionState = CAGetJNIMethodID(env, "android/bluetooth"
158 "getConnectionState",
159 "(Landroid/bluetooth/BluetoothDevice"
161 if (!jni_mid_getConnectionState)
163 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
167 if (!g_bluetoothManager)
169 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
173 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
174 jni_mid_getConnectionState,
175 device, GATT_PROFILE);
176 if (CACheckJNIException(env))
178 OIC_LOG(ERROR, TAG, "getConnectionState has failed");
182 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
186 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
188 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
189 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
190 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
192 if (!g_bluetoothGattServer)
194 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
198 if (!CALEIsEnableBTAdapter(env))
200 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
204 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
205 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
207 "(Ljava/util/UUID;)Landroid/bluetooth/"
208 "BluetoothGattService;");
209 if (!jni_mid_getService)
211 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
215 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
216 if (!jni_obj_serviceUUID)
218 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
222 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
224 jni_obj_serviceUUID);
225 if (!jni_obj_bluetoothGattService)
227 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
228 CACheckJNIException(env);
232 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
233 "BluetoothGattService",
236 "Landroid/bluetooth/"
237 "BluetoothGattCharacteristic;");
238 if (!jni_mid_getCharacteristic)
240 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
244 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
245 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
246 if (!jni_obj_responseUUID)
248 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
252 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
253 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
254 if (!jni_obj_bluetoothGattCharacteristic)
256 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
257 CACheckJNIException(env);
261 jmethodID jni_mid_setValue = CAGetJNIMethodID(env, "android/bluetooth/"
262 "BluetoothGattCharacteristic",
263 "setValue", "([B)Z");
264 if (!jni_mid_setValue)
266 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
270 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
271 jni_obj_bluetoothGattCharacteristic,
272 jni_mid_setValue, responseData);
273 if (JNI_FALSE == jni_boolean_setValue)
275 OIC_LOG(ERROR, TAG, "Fail to set response data");
276 CACheckJNIException(env);
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 (!g_bluetoothGattServer)
298 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is not available");
299 return CA_STATUS_FAILED;
302 if (g_state_connected != CALEServerGetConnectionState(env, device))
304 OIC_LOG(ERROR, TAG, "it is not connected state");
305 return CA_STATUS_FAILED;
308 jmethodID jni_mid_notifyCharacteristicChanged = CAGetJNIMethodID(env,
309 CLASSPATH_BT_GATTSERVER,
310 "notifyCharacteristicChanged",
311 "(Landroid/bluetooth/BluetoothDevice;"
312 "Landroid/bluetooth/"
313 "BluetoothGattCharacteristic;Z)Z");
314 if (!jni_mid_notifyCharacteristicChanged)
316 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
317 return CA_STATUS_FAILED;
320 OIC_LOG(DEBUG, TAG, "CALL API - notifyCharacteristicChanged");
322 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
323 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
325 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
327 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
328 CACheckJNIException(env);
329 return CA_SEND_FAILED;
332 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
333 oc_mutex_lock(g_threadSendNotifyMutex);
334 if (!g_isSignalSetFlag)
336 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
337 if (0 != oc_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
338 WAIT_TIME_WRITE_CHARACTERISTIC))
340 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
341 oc_mutex_unlock(g_threadSendNotifyMutex);
342 return CA_STATUS_FAILED;
345 // reset flag set by writeCharacteristic Callback
346 g_isSignalSetFlag = false;
347 oc_mutex_unlock(g_threadSendNotifyMutex);
348 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
352 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
353 jint offset, jbyteArray value)
355 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
356 VERIFY_NON_NULL(env, TAG, "env is null");
357 VERIFY_NON_NULL(device, TAG, "device is null");
358 VERIFY_NON_NULL(value, TAG, "value is null");
360 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
362 if (!CALEIsEnableBTAdapter(env))
364 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
365 return CA_ADAPTER_NOT_ENABLED;
368 if (!g_bluetoothGattServer)
370 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is not available");
371 return CA_STATUS_FAILED;
374 jmethodID jni_mid_sendResponse = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
376 "(Landroid/bluetooth/BluetoothDevice;"
378 if (!jni_mid_sendResponse)
380 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
381 return CA_STATUS_FAILED;
384 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
385 jni_mid_sendResponse, device,
386 requestId, status, offset,
388 if (JNI_FALSE == jni_boolean_sendResponse)
390 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
391 CACheckJNIException(env);
392 return CA_SEND_FAILED;
395 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
399 CAResult_t CALEServerStartAdvertise()
401 if ((caglobals.bleFlags & CA_LE_ADV_DISABLE) || CA_DEFAULT_BT_FLAGS == caglobals.bleFlags)
403 OIC_LOG_V(INFO, TAG, "the advertisement of the bleFlags is disable[%d]",
408 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
411 bool isAttached = false;
412 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
413 return CA_STATUS_FAILED;
417 CAResult_t ret = CALEServerStartAdvertiseImpl(env, g_leAdvertiseCallback);
418 if (CA_STATUS_OK != ret)
420 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertiseImpl has failed");
425 (*g_jvm)->DetachCurrentThread(g_jvm);
430 CAResult_t CALEServerStartAdvertiseImpl(JNIEnv *env, jobject advertiseCallback)
432 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertiseImpl");
433 VERIFY_NON_NULL(env, TAG, "env is null");
434 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
436 if (!CALEIsEnableBTAdapter(env))
438 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
439 return CA_ADAPTER_NOT_ENABLED;
442 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
443 "android/bluetooth/le/"
444 "AdvertiseSettings$Builder");
445 if (!jni_cid_AdvertiseSettings)
447 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
451 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
453 if (!jni_mid_AdvertiseSettings)
455 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
459 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
460 jni_mid_AdvertiseSettings);
461 if (!jni_AdvertiseSettings)
463 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
467 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
469 "(I)Landroid/bluetooth/le/"
470 "AdvertiseSettings$Builder;");
471 if (!jni_mid_setAdvertiseMode)
473 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
477 // 0: Low power, 1: Balanced
478 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
479 jni_mid_setAdvertiseMode, 0);
480 if (!jni_obj_setAdvertiseMode)
482 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
486 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
488 "(Z)Landroid/bluetooth/le/"
489 "AdvertiseSettings$Builder;");
490 if (!jni_mid_setConnectable)
492 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
496 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
497 jni_mid_setConnectable, JNI_TRUE);
498 if (!jni_obj_setConnectable)
500 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
504 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
505 "(I)Landroid/bluetooth/le/"
506 "AdvertiseSettings$Builder;");
507 if (!jni_mid_setTimeout)
509 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
513 //A value of 0 will disable the time limit
514 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
515 jni_mid_setTimeout, 0);
516 if (!jni_obj_setTimeout)
518 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
522 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
523 "android/bluetooth/le/"
524 "AdvertiseData$Builder");
525 if (!jni_cid_AdvertiseDataBuilder)
527 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
531 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
533 if (!jni_mid_AdvertiseDataBuilder)
535 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
539 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
540 jni_mid_AdvertiseDataBuilder);
541 if (!jni_AdvertiseDataBuilder)
543 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
547 jobject jni_AdvertiseDataBuilderForScanRsp = (*env)->NewObject(env,
548 jni_cid_AdvertiseDataBuilder,
549 jni_mid_AdvertiseDataBuilder);
550 if (!jni_AdvertiseDataBuilderForScanRsp)
552 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilderForScanRsp is null");
556 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
557 if (!jni_obj_serviceUUID)
559 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
560 return CA_STATUS_FAILED;
563 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
566 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
567 return CA_STATUS_FAILED;
570 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
572 "(Landroid/os/ParcelUuid;)Landroid/"
573 "bluetooth/le/AdvertiseData$Builder;");
574 if (!jni_mid_addServiceUuid)
576 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
580 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
581 jni_mid_addServiceUuid,
583 if (!jni_obj_addServiceUuid)
585 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
589 // Device name has to be included in advertise packet after Android API 23
590 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
591 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
592 "setIncludeDeviceName",
595 "AdvertiseData$Builder;");
596 if (!jni_mid_setIncludeDeviceName)
598 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
602 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env,
603 jni_AdvertiseDataBuilderForScanRsp,
604 jni_mid_setIncludeDeviceName,
606 if (!jni_obj_setIncludeDeviceName)
608 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
612 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
613 if (!jni_cid_BTAdapter)
615 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
616 return CA_STATUS_FAILED;
619 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
621 "()Landroid/bluetooth/"
622 "BluetoothAdapter;");
623 if (!jni_mid_getDefaultAdapter)
625 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
629 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
630 jni_mid_getDefaultAdapter);
631 if (!jni_obj_BTAdapter)
633 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
637 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
638 "getBluetoothLeAdvertiser",
639 "()Landroid/bluetooth/le/"
640 "BluetoothLeAdvertiser;");
641 if (!jni_mid_getBluetoothLeAdvertiser)
643 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
647 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
648 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
649 if (!jni_obj_getBluetoothLeAdvertiser)
651 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
655 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
656 jni_cid_AdvertiseSettings,
658 "()Landroid/bluetooth/le/"
659 "AdvertiseSettings;");
660 if (!jni_mid_build_LeAdvertiseSettings)
662 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
666 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
667 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
668 if (!jni_obj_build_LeAdvertiseSettings)
670 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
674 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
676 "()Landroid/bluetooth/le/"
678 if (!jni_mid_build_LeAdvertiseData)
680 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
684 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
685 jni_mid_build_LeAdvertiseData);
686 if (!jni_obj_build_LeAdvertiseData)
688 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
692 jobject jni_obj_build_LeAdvertiseDataForScanRsp = (*env)->CallObjectMethod(env,
693 jni_AdvertiseDataBuilderForScanRsp,
694 jni_mid_build_LeAdvertiseData);
695 if (!jni_obj_build_LeAdvertiseDataForScanRsp)
697 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseDataForScanRsp is null");
701 jmethodID jni_mid_startAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
702 "BluetoothLeAdvertiser",
704 "(Landroid/bluetooth/le/"
705 "AdvertiseSettings;Landroid/bluetooth/"
706 "le/AdvertiseData;Landroid/bluetooth/"
707 "le/AdvertiseData;Landroid/bluetooth/"
708 "le/AdvertiseCallback;)V");
709 if (!jni_mid_startAdvertising)
711 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
712 return CA_STATUS_FAILED;
715 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
716 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
717 jni_obj_build_LeAdvertiseDataForScanRsp, advertiseCallback);
718 if (CACheckJNIException(env))
720 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
721 return CA_STATUS_FAILED;
724 OIC_LOG(DEBUG, TAG, "Advertising started!!");
725 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
729 CACheckJNIException(env);
730 return CA_STATUS_FAILED;
733 CAResult_t CALEServerStopAdvertise()
735 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
738 bool isAttached = false;
739 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
740 return CA_STATUS_FAILED;
743 CAResult_t ret = CALEServerStopAdvertiseImpl(env, g_leAdvertiseCallback);
744 if (CA_STATUS_OK != ret)
746 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
751 (*g_jvm)->DetachCurrentThread(g_jvm);
757 CAResult_t CALEServerStopAdvertiseImpl(JNIEnv *env, jobject advertiseCallback)
759 OIC_LOG(DEBUG, TAG, "CALEServerStopAdvertiseImpl");
760 VERIFY_NON_NULL(env, TAG, "env is null");
761 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
763 if (!CALEIsEnableBTAdapter(env))
765 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
766 return CA_ADAPTER_NOT_ENABLED;
769 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
770 if (!jni_cid_BTAdapter)
772 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
776 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
778 "()Landroid/bluetooth/"
779 "BluetoothAdapter;");
780 if (!jni_mid_getDefaultAdapter)
782 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
786 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
787 "getBluetoothLeAdvertiser",
788 "()Landroid/bluetooth/le/"
789 "BluetoothLeAdvertiser;");
790 if (!jni_mid_getBTLeAdvertiser)
792 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
796 jmethodID jni_mid_stopAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
797 "BluetoothLeAdvertiser",
799 "(Landroid/bluetooth/le/"
800 "AdvertiseCallback;)V");
801 if (!jni_mid_stopAdvertising)
803 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
807 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
808 jni_mid_getDefaultAdapter);
809 if (!jni_obj_BTAdapter)
811 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
815 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
816 jni_mid_getBTLeAdvertiser);
817 if (!jni_obj_getBluetoothLeAdvertiser)
819 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
823 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
825 if (CACheckJNIException(env))
827 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
828 return CA_STATUS_FAILED;
831 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
835 CACheckJNIException(env);
836 return CA_STATUS_FAILED;
839 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
841 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
842 VERIFY_NON_NULL(env, TAG, "env is null");
843 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
845 if (!CALEIsEnableBTAdapter(env))
847 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
848 return CA_ADAPTER_NOT_ENABLED;
853 OIC_LOG(DEBUG, TAG, "Gatt server already started");
856 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
859 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
860 if (!bluetoothGattServer)
862 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
863 return CA_STATUS_FAILED;
866 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
867 if (!g_bluetoothGattServer)
869 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
870 return CA_STATUS_FAILED;
873 // create gatt service
874 jobject bluetoothGattService = CALEServerCreateGattService(env);
875 if (!bluetoothGattService)
877 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
878 return CA_STATUS_FAILED;
882 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
883 bluetoothGattService);
884 if (CA_STATUS_OK != res)
886 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
891 jobject CALEServerOpenGattServer(JNIEnv *env)
893 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
894 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
896 if (!CALEIsEnableBTAdapter(env))
898 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
902 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
903 if (!jni_cid_context)
905 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
909 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
911 "Ljava/lang/String;");
912 if (!jni_fid_bluetoothService)
914 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
918 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
920 "(Ljava/lang/String;)"
921 "Ljava/lang/Object;");
922 if (!jni_mid_getSystemService)
924 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
928 jmethodID jni_mid_openGattServer = CAGetJNIMethodID(env, "android/bluetooth/"
931 "(Landroid/content/Context;"
932 "Landroid/bluetooth/"
933 "BluetoothGattServerCallback;)"
934 "Landroid/bluetooth/"
935 "BluetoothGattServer;");
936 if (!jni_mid_openGattServer)
938 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
942 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
943 jni_fid_bluetoothService);
944 if (!jni_obj_bluetoothService)
946 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
950 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
951 jni_mid_getSystemService,
952 jni_obj_bluetoothService);
953 if (!jni_obj_bluetoothManager)
955 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
959 if (g_bluetoothManager)
961 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
963 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
965 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
966 jni_mid_openGattServer,
968 g_bluetoothGattServerCallback);
969 if (!jni_obj_bluetoothGattServer)
971 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
975 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
976 return jni_obj_bluetoothGattServer;
979 CACheckJNIException(env);
983 jobject CALEServerCreateGattService(JNIEnv *env)
985 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
986 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
988 if (!CALEIsEnableBTAdapter(env))
990 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
994 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
995 "BluetoothGattService");
996 if (!jni_cid_bluetoothGattService)
998 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
1002 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1003 "BluetoothGattCharacteristic");
1004 if (!jni_cid_bluetoothGattCharacteristic)
1006 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
1010 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
1011 "SERVICE_TYPE_PRIMARY", "I");
1012 if (!jni_fid_serviceType)
1014 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
1018 jfieldID jni_fid_readProperties = NULL;
1019 jfieldID jni_fid_writeProperties = NULL;
1022 jni_fid_readProperties = (*env)->GetStaticFieldID(env,
1023 jni_cid_bluetoothGattCharacteristic,
1024 "PROPERTY_INDICATE", "I");
1025 if (!jni_fid_readProperties)
1027 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1031 jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1032 jni_cid_bluetoothGattCharacteristic,
1033 "PROPERTY_WRITE", "I");
1034 if (!jni_fid_writeProperties)
1036 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1042 jni_fid_readProperties = (*env)->GetStaticFieldID(env,
1043 jni_cid_bluetoothGattCharacteristic,
1044 "PROPERTY_NOTIFY", "I");
1045 if (!jni_fid_readProperties)
1047 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1051 jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1052 jni_cid_bluetoothGattCharacteristic,
1053 "PROPERTY_WRITE_NO_RESPONSE", "I");
1054 if (!jni_fid_writeProperties)
1056 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1061 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1062 jni_cid_bluetoothGattCharacteristic,
1063 "PERMISSION_READ", "I");
1064 if (!jni_fid_readPermissions)
1066 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1070 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1071 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1072 if (!jni_fid_writePermissions)
1074 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1078 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1079 "<init>", "(Ljava/util/UUID;I)V");
1080 if (!jni_mid_bluetoothGattService)
1082 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1086 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1087 "addCharacteristic",
1088 "(Landroid/bluetooth/"
1089 "BluetoothGattCharacteristic;)Z");
1090 if (!jni_mid_addCharacteristic)
1092 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1096 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1097 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1098 if (!jni_mid_bluetoothGattCharacteristic)
1100 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1104 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1105 if (!jni_obj_serviceUUID)
1107 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1111 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1112 jni_fid_serviceType);
1113 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1114 jni_mid_bluetoothGattService,
1115 jni_obj_serviceUUID, jni_int_serviceType);
1116 if (!jni_bluetoothGattService)
1118 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1122 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1123 if (!jni_obj_readUuid)
1125 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1129 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1130 jni_cid_bluetoothGattCharacteristic,
1131 jni_fid_readProperties);
1132 CACheckJNIException(env);
1134 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1135 jni_cid_bluetoothGattCharacteristic,
1136 jni_fid_readPermissions);
1137 CACheckJNIException(env);
1139 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1140 jni_cid_bluetoothGattCharacteristic,
1141 jni_fid_writePermissions);
1142 CACheckJNIException(env);
1144 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1145 jni_mid_bluetoothGattCharacteristic,
1146 jni_obj_readUuid, jni_int_readProperties,
1147 jni_int_readPermissions|
1148 jni_int_writePermissions);
1149 if (!jni_readCharacteristic)
1151 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1155 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1156 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1157 if (!jni_boolean_addReadCharacteristic)
1159 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1163 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1164 if (!jni_obj_writeUuid)
1166 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1170 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1171 jni_cid_bluetoothGattCharacteristic,
1172 jni_fid_writeProperties);
1173 CACheckJNIException(env);
1175 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1176 jni_mid_bluetoothGattCharacteristic,
1177 jni_obj_writeUuid, jni_int_writeProperties,
1178 jni_int_writePermissions);
1179 if (!jni_writeCharacteristic)
1181 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1185 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1186 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1187 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1189 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1193 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1194 return jni_bluetoothGattService;
1197 CACheckJNIException(env);
1201 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1203 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1204 VERIFY_NON_NULL(env, TAG, "env is null");
1205 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1207 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1208 "BluetoothGattDescriptor");
1209 if (!jni_cid_bluetoothGattDescriptor)
1211 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1215 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1216 jni_cid_bluetoothGattDescriptor,
1218 "(Ljava/util/UUID;I)V");
1219 if (!jni_mid_bluetoothGattDescriptor)
1221 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1225 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1226 jni_cid_bluetoothGattDescriptor,
1227 "PERMISSION_READ", "I");
1228 if (!jni_fid_readPermissions)
1230 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1234 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1235 if (!jni_obj_readUuid)
1237 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1238 return CA_STATUS_FAILED;
1241 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1242 jni_fid_readPermissions);
1243 CACheckJNIException(env);
1245 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1247 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1248 jni_mid_bluetoothGattDescriptor,
1249 jni_obj_readUuid, jni_int_readPermissions);
1250 if (!jni_readDescriptor)
1252 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1256 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1257 "BluetoothGattCharacteristic");
1258 if (!jni_cid_GattCharacteristic)
1260 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1264 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1266 "(Landroid/bluetooth/"
1267 "BluetoothGattDescriptor;)Z");
1268 if (!jni_mid_addDescriptor)
1270 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1274 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1275 jni_mid_addDescriptor,
1276 jni_readDescriptor);
1278 if (JNI_FALSE == jni_boolean_addDescriptor)
1280 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1285 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1287 return CA_STATUS_OK;
1290 CACheckJNIException(env);
1291 return CA_STATUS_FAILED;
1294 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1295 jobject bluetoothGattService)
1297 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1298 VERIFY_NON_NULL(env, TAG, "env is null");
1299 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1300 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1302 if (!CALEIsEnableBTAdapter(env))
1304 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1305 return CA_ADAPTER_NOT_ENABLED;
1308 jmethodID jni_mid_addService = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1310 "(Landroid/bluetooth/BluetoothGattService;)"
1312 if (!jni_mid_addService)
1314 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1315 return CA_STATUS_FAILED;
1318 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1320 bluetoothGattService);
1322 if (JNI_FALSE == jni_boolean_addService)
1324 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1325 CACheckJNIException(env);
1326 return CA_STATUS_FAILED;
1329 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1330 return CA_STATUS_OK;
1333 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1335 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1336 VERIFY_NON_NULL(env, TAG, "env is null");
1337 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1339 if (!CALEIsEnableBTAdapter(env))
1341 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1342 return CA_ADAPTER_NOT_ENABLED;
1345 jmethodID jni_mid_connect = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1347 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1348 if (!jni_mid_connect)
1350 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1351 return CA_STATUS_FAILED;
1354 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1355 jni_mid_connect, bluetoothDevice,
1357 if (JNI_FALSE == jni_boolean_connect)
1359 OIC_LOG(ERROR, TAG, "Fail to connect");
1360 CACheckJNIException(env);
1361 return CA_STATUS_FAILED;
1364 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1365 return CA_STATUS_OK;
1368 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1370 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1371 VERIFY_NON_NULL(env, TAG, "env is null");
1373 oc_mutex_lock(g_connectedDeviceListMutex);
1374 if (!g_connectedDeviceList)
1376 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1377 oc_mutex_unlock(g_connectedDeviceListMutex);
1378 return CA_STATUS_FAILED;
1381 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1382 for (uint32_t index = 0; index < length; index++)
1384 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1387 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1391 // disconnect for device obj
1392 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1393 if (CA_STATUS_OK != res)
1395 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1400 oc_mutex_unlock(g_connectedDeviceListMutex);
1401 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1402 return CA_STATUS_OK;
1405 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1407 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1408 VERIFY_NON_NULL(env, TAG, "env is null");
1409 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1411 if (!CALEIsEnableBTAdapter(env))
1413 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1414 return CA_ADAPTER_NOT_ENABLED;
1417 jmethodID jni_mid_cancelConnection = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1419 "(Landroid/bluetooth/BluetoothDevice;)"
1421 if (!jni_mid_cancelConnection)
1423 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1424 return CA_STATUS_FAILED;
1427 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1429 if (CACheckJNIException(env))
1431 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1432 return CA_STATUS_FAILED;
1435 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1436 return CA_STATUS_OK;
1439 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1442 OIC_LOG(DEBUG, TAG, "GattServer Close");
1443 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1444 VERIFY_NON_NULL(env, TAG, "env is null");
1446 // get BluetoothGatt class
1447 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1448 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1450 if (!jni_mid_closeGatt)
1452 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1453 return CA_STATUS_OK;
1456 // call disconnect gatt method
1457 OIC_LOG(DEBUG, TAG, "request to close GATT");
1458 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1460 if (CACheckJNIException(env))
1462 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1463 return CA_STATUS_FAILED;
1466 return CA_STATUS_OK;
1469 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1471 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1472 VERIFY_NON_NULL(env, TAG, "env is null");
1473 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1474 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1476 if (!CALEIsEnableBTAdapter(env))
1478 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1479 return CA_ADAPTER_NOT_ENABLED;
1482 jobject responseChar = CALEServerSetResponseData(env, responseData);
1485 OIC_LOG(ERROR, TAG, "responseChar is null");
1486 return CA_STATUS_FAILED;
1489 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1490 if (CA_STATUS_OK != result)
1492 OIC_LOG(ERROR, TAG, "Fail to send response data");
1496 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1500 CAResult_t CALEServerInitialize()
1502 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1504 CALeServerJniInit();
1506 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
1509 bool isAttached = false;
1510 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1511 return CA_STATUS_FAILED;
1514 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1515 if (CA_STATUS_OK != ret)
1517 OIC_LOG(ERROR, TAG, "it is not supported");
1521 (*g_jvm)->DetachCurrentThread(g_jvm);
1526 g_threadSendNotifyCond = oc_cond_new();
1528 ret = CALEServerInitMutexVaraibles();
1529 if (CA_STATUS_OK != ret)
1531 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1535 (*g_jvm)->DetachCurrentThread(g_jvm);
1537 return CA_STATUS_FAILED;
1540 CALEServerJNISetContext();
1541 CALEServerCreateCachedDeviceList();
1543 ret = CALEServerCreateJniInterfaceObject();
1544 if (CA_STATUS_OK != ret)
1546 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1550 (*g_jvm)->DetachCurrentThread(g_jvm);
1552 return CA_STATUS_FAILED;
1557 (*g_jvm)->DetachCurrentThread(g_jvm);
1560 g_isInitializedServer = true;
1561 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1562 return CA_STATUS_OK;
1565 void CALEServerTerminate()
1567 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1569 VERIFY_NON_NULL_VOID(g_jvm, TAG, "g_jvm is null");
1572 bool isAttached = false;
1573 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1579 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1580 g_sendBuffer = NULL;
1583 if (g_bluetoothManager)
1585 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1586 g_bluetoothManager = NULL;
1589 oc_cond_free(g_threadSendNotifyCond);
1590 g_threadSendNotifyCond = NULL;
1592 CALEServerTerminateMutexVaraibles();
1593 CALEServerTerminateConditionVaraibles();
1595 g_isInitializedServer = false;
1599 (*g_jvm)->DetachCurrentThread(g_jvm);
1602 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1605 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1607 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1608 VERIFY_NON_NULL(address, TAG, "address is null");
1609 VERIFY_NON_NULL(data, TAG, "data is null");
1611 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
1614 bool isAttached = false;
1615 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1616 return CA_STATUS_FAILED;
1619 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1620 if (CA_STATUS_OK != ret)
1622 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1627 (*g_jvm)->DetachCurrentThread(g_jvm);
1633 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1635 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1636 VERIFY_NON_NULL(data, TAG, "data is null");
1638 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
1641 bool isAttached = false;
1642 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1643 return CA_STATUS_FAILED;
1646 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1647 if (CA_STATUS_OK != ret)
1649 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1654 (*g_jvm)->DetachCurrentThread(g_jvm);
1660 CAResult_t CALEServerStartMulticastServer()
1662 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1664 if (!g_isInitializedServer)
1666 OIC_LOG(INFO, TAG, "server is not initialized");
1667 return CA_STATUS_FAILED;
1670 if (g_isStartServer)
1672 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1673 return CA_STATUS_FAILED;
1676 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
1679 bool isAttached = false;
1680 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
1681 return CA_STATUS_FAILED;
1684 g_isStartServer = true;
1686 // start gatt server
1687 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1688 if (CA_STATUS_OK != ret)
1690 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1695 ret = CALEServerStartAdvertise();
1696 if (CA_STATUS_OK != ret)
1698 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1701 // get Constants Value from Android Platform
1702 g_state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
1703 g_state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
1707 (*g_jvm)->DetachCurrentThread(g_jvm);
1710 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1714 CAResult_t CALEServerStopMulticastServer()
1716 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1718 if (false == g_isStartServer)
1720 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1721 return CA_STATUS_FAILED;
1724 CAResult_t ret = CALEServerStopAdvertise();
1725 if (CA_STATUS_OK != ret)
1727 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1730 g_isStartServer = false;
1732 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1736 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1738 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1739 g_packetReceiveCallback = callback;
1742 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1745 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1747 VERIFY_NON_NULL(env, TAG, "env is null");
1748 VERIFY_NON_NULL(address, TAG, "address is null");
1749 VERIFY_NON_NULL(data, TAG, "data is null");
1751 if (!g_connectedDeviceList)
1753 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1754 return CA_STATUS_FAILED;
1757 oc_mutex_lock(g_threadSendMutex);
1759 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1760 for (uint32_t index = 0; index < length; index++)
1762 OIC_LOG(DEBUG, TAG, "check device address");
1763 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1766 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1770 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1771 if (!jni_setAddress)
1773 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1776 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1779 OIC_LOG(ERROR, TAG, "setAddress is null");
1783 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1784 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1786 if (!strcasecmp(setAddress, address))
1788 OIC_LOG(DEBUG, TAG, "found the device");
1790 if (g_obj_bluetoothDevice)
1792 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1793 g_obj_bluetoothDevice = NULL;
1798 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1799 CACheckJNIException(env);
1801 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1804 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1807 if (g_obj_bluetoothDevice)
1809 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1810 CACheckJNIException(env);
1811 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1812 CACheckJNIException(env);
1813 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1814 CACheckJNIException(env);
1816 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1817 if (CA_STATUS_OK != res)
1819 OIC_LOG(ERROR, TAG, "send has failed");
1825 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1831 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1832 g_sendBuffer = NULL;
1835 oc_mutex_unlock(g_threadSendMutex);
1836 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1837 return CA_STATUS_OK;
1842 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1843 g_sendBuffer = NULL;
1846 if (g_obj_bluetoothDevice)
1848 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1849 g_obj_bluetoothDevice = NULL;
1852 oc_mutex_unlock(g_threadSendMutex);
1853 return CA_SEND_FAILED;
1856 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1858 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1859 VERIFY_NON_NULL(env, TAG, "env is null");
1860 VERIFY_NON_NULL(data, TAG, "data is null");
1862 if (!g_connectedDeviceList)
1864 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1865 return CA_STATUS_FAILED;
1868 oc_mutex_lock(g_threadSendMutex);
1870 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1873 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1874 g_sendBuffer = NULL;
1876 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1877 CACheckJNIException(env);
1878 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1879 CACheckJNIException(env);
1880 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1881 CACheckJNIException(env);
1883 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1884 for (uint32_t index = 0; index < length; index++)
1886 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1889 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1893 // send data for all device
1894 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1895 CACheckJNIException(env);
1896 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1897 CACheckJNIException(env);
1899 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1902 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1906 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1909 OIC_LOG(ERROR, TAG, "address is not available");
1913 if (g_obj_bluetoothDevice)
1915 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1916 g_obj_bluetoothDevice = NULL;
1921 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1922 CACheckJNIException(env);
1925 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
1926 if (CA_STATUS_OK != res)
1928 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
1929 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1930 if (g_obj_bluetoothDevice)
1932 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1933 g_obj_bluetoothDevice = NULL;
1938 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
1939 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1944 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1945 g_sendBuffer = NULL;
1948 oc_mutex_unlock(g_threadSendMutex);
1949 return CA_STATUS_OK;
1952 void CALEServerCreateCachedDeviceList()
1954 oc_mutex_lock(g_connectedDeviceListMutex);
1955 // create new object array
1956 if (!g_connectedDeviceList)
1958 OIC_LOG(DEBUG, TAG, "Create device list");
1959 g_connectedDeviceList = u_arraylist_create();
1961 oc_mutex_unlock(g_connectedDeviceListMutex);
1963 oc_mutex_lock(g_deviceStateListMutex);
1964 // create new object array
1965 if (!g_deviceStateList)
1967 OIC_LOG(DEBUG, TAG, "Create device list");
1968 g_deviceStateList = u_arraylist_create();
1970 oc_mutex_unlock(g_deviceStateListMutex);
1973 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1975 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1976 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1978 if (!g_connectedDeviceList)
1980 OIC_LOG(ERROR, TAG, "list is null");
1984 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1985 for (uint32_t index = 0; index < length; index++)
1987 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1991 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1995 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1996 if (!jni_setAddress)
1998 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2002 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2005 OIC_LOG(ERROR, TAG, "setAddress is null");
2009 if (!strcasecmp(remoteAddress, setAddress))
2011 OIC_LOG(ERROR, TAG, "the device is already set");
2012 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2017 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2022 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2026 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2028 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2029 VERIFY_NON_NULL(device, TAG, "device is null");
2030 VERIFY_NON_NULL(env, TAG, "env is null");
2032 oc_mutex_lock(g_connectedDeviceListMutex);
2034 if (!g_connectedDeviceList)
2036 OIC_LOG(ERROR, TAG, "list is null");
2037 oc_mutex_unlock(g_connectedDeviceListMutex);
2038 return CA_STATUS_FAILED;
2041 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2042 if (!jni_remoteAddress)
2044 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2045 oc_mutex_unlock(g_connectedDeviceListMutex);
2046 return CA_STATUS_FAILED;
2049 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2052 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2053 oc_mutex_unlock(g_connectedDeviceListMutex);
2054 return CA_STATUS_FAILED;
2057 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2059 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2060 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2061 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2064 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2065 oc_mutex_unlock(g_connectedDeviceListMutex);
2066 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2067 return CA_STATUS_OK;
2070 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2072 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2073 VERIFY_NON_NULL(env, TAG, "env is null");
2075 oc_mutex_lock(g_connectedDeviceListMutex);
2076 if (!g_connectedDeviceList)
2078 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2079 oc_mutex_unlock(g_connectedDeviceListMutex);
2080 return CA_STATUS_FAILED;
2083 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2084 for (uint32_t index = 0; index < length; index++)
2086 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2089 (*env)->DeleteGlobalRef(env, jarrayObj);
2093 OICFree(g_connectedDeviceList);
2094 g_connectedDeviceList = NULL;
2095 oc_mutex_unlock(g_connectedDeviceListMutex);
2097 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2098 return CA_STATUS_OK;
2101 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2103 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2104 VERIFY_NON_NULL(env, TAG, "env is null");
2105 VERIFY_NON_NULL(address, TAG, "address is null");
2107 oc_mutex_lock(g_connectedDeviceListMutex);
2108 if (!g_connectedDeviceList)
2110 OIC_LOG(ERROR, TAG, "no deviceList");
2111 oc_mutex_unlock(g_connectedDeviceListMutex);
2112 return CA_STATUS_FAILED;
2115 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2116 for (uint32_t index = 0; index < length; index++)
2118 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2122 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2123 if (!jni_setAddress)
2125 OIC_LOG(ERROR, TAG, "wrong device address");
2128 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2131 OIC_LOG(ERROR, TAG, "setAddress is null");
2135 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2138 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2139 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2143 if (!strcasecmp(setAddress, remoteAddress))
2145 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2147 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2148 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2149 (*env)->DeleteGlobalRef(env, jarrayObj);
2152 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2154 OIC_LOG(ERROR, TAG, "List removal failed.");
2155 oc_mutex_unlock(g_connectedDeviceListMutex);
2156 return CA_STATUS_FAILED;
2158 oc_mutex_unlock(g_connectedDeviceListMutex);
2159 return CA_STATUS_OK;
2161 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2162 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2166 oc_mutex_unlock(g_connectedDeviceListMutex);
2168 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2170 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2171 return CA_STATUS_FAILED;
2174 JNIEXPORT void JNICALL
2175 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2178 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2179 VERIFY_NON_NULL_VOID(env, TAG, "env");
2180 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2181 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2183 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2184 CACheckJNIException(env);
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);
2198 CACheckJNIException(env);
2201 JNIEXPORT void JNICALL
2202 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2203 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2205 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2206 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2208 VERIFY_NON_NULL_VOID(env, TAG, "env");
2209 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2210 VERIFY_NON_NULL_VOID(device, TAG, "device");
2212 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2213 if (!jni_remoteAddress)
2215 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2219 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2222 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2223 CACheckJNIException(env);
2227 if (newState == g_state_connected)
2229 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2231 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2233 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2234 CALEServerAddDeviceToList(env, device);
2237 CAResult_t res = CALEUpdateDeviceState(remoteAddress,
2238 CA_LE_CONNECTION_STATE,
2241 g_deviceStateListMutex);
2242 if (CA_STATUS_OK != res)
2244 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2247 res = CALEServerStopAdvertise();
2248 if (CA_STATUS_OK != res)
2250 OIC_LOG(DEBUG, TAG, "CALEServerStopAdvertise has failed");
2253 else if (newState == g_state_disconnected)
2255 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2257 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2258 CAResult_t res = CALEServerRemoveDevice(env, jni_remoteAddress);
2259 if (CA_STATUS_OK != res)
2261 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2264 res = CALEUpdateDeviceState(remoteAddress,
2265 CA_LE_CONNECTION_STATE,
2268 g_deviceStateListMutex);
2269 if (CA_STATUS_OK != res)
2271 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2275 res = CALEServerStartAdvertise();
2276 if (CA_STATUS_OK != res)
2278 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2286 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2289 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2290 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2293 JNIEXPORT void JNICALL
2294 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2297 jobject gattService)
2299 VERIFY_NON_NULL_VOID(env, TAG, "env");
2300 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2301 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2305 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2308 JNIEXPORT void JNICALL
2309 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2310 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2312 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2313 VERIFY_NON_NULL_VOID(env, TAG, "env");
2314 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2315 VERIFY_NON_NULL_VOID(device, TAG, "device");
2316 VERIFY_NON_NULL_VOID(data, TAG, "data");
2319 JNIEXPORT void JNICALL
2320 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2321 JNIEnv *env, jobject obj, jobject device, jbyteArray data,
2322 jint requestId, jint offset, jbyteArray value)
2324 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2325 VERIFY_NON_NULL_VOID(env, TAG, "env");
2326 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2327 VERIFY_NON_NULL_VOID(device, TAG, "device");
2328 VERIFY_NON_NULL_VOID(data, TAG, "data");
2332 CALEServerSendResponse(env, device, requestId, 0, offset, value);
2341 // get Byte Array and covert to uint8_t*
2342 jint length = (*env)->GetArrayLength(env, data);
2343 CACheckJNIException(env);
2346 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2347 CACheckJNIException(env);
2349 uint8_t* requestData = NULL;
2350 requestData = OICMalloc(length);
2353 OIC_LOG(ERROR, TAG, "requestData is null");
2357 memcpy(requestData, jni_byte_requestData, length);
2358 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2360 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2363 OIC_LOG(ERROR, TAG, "jni_address is null");
2364 OICFree(requestData);
2368 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2371 OIC_LOG(ERROR, TAG, "address is null");
2372 CACheckJNIException(env);
2373 OICFree(requestData);
2377 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2379 oc_mutex_lock(g_bleClientBDAddressMutex);
2380 uint32_t sentLength = 0;
2381 g_CABLEServerDataReceivedCallback(address, requestData, length,
2383 oc_mutex_unlock(g_bleClientBDAddressMutex);
2385 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2388 JNIEXPORT void JNICALL
2389 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2394 VERIFY_NON_NULL_VOID(env, TAG, "env");
2395 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2396 VERIFY_NON_NULL_VOID(device, TAG, "device");
2398 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2401 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2404 OIC_LOG(ERROR, TAG, "jni_address is null");
2408 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2411 OIC_LOG(ERROR, TAG, "address is not available");
2412 (*env)->DeleteLocalRef(env, jni_address);
2416 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2417 if (gatt_success != status) // error case
2419 OIC_LOG(ERROR, TAG, "it will be sent again.");
2421 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2422 if (CA_STATUS_OK != res)
2424 OIC_LOG(ERROR, TAG, "send has failed");
2426 if (g_obj_bluetoothDevice)
2428 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2429 g_obj_bluetoothDevice = NULL;
2432 oc_mutex_lock(g_threadSendNotifyMutex);
2433 g_isSignalSetFlag = true;
2434 oc_cond_signal(g_threadSendNotifyCond);
2435 oc_mutex_unlock(g_threadSendNotifyMutex);
2437 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2438 (*env)->DeleteLocalRef(env, jni_address);
2442 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, -1,
2443 false, "notifyChar failure");
2447 OIC_LOG(DEBUG, TAG, "notify success");
2449 if (g_obj_bluetoothDevice)
2451 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2452 g_obj_bluetoothDevice = NULL;
2455 // next data can be sent
2456 oc_mutex_lock(g_threadSendNotifyMutex);
2457 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2458 g_isSignalSetFlag = true;
2459 oc_cond_signal(g_threadSendNotifyCond);
2460 oc_mutex_unlock(g_threadSendNotifyMutex);
2462 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, -1,
2463 true, "notifyChar success");
2465 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2466 (*env)->DeleteLocalRef(env, jni_address);
2470 JNIEXPORT void JNICALL
2471 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2473 jobject settingsInEffect)
2475 VERIFY_NON_NULL_VOID(env, TAG, "env");
2476 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2477 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2479 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2482 JNIEXPORT void JNICALL
2483 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2487 VERIFY_NON_NULL_VOID(env, TAG, "env");
2488 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2490 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2492 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2493 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2494 jint already_started = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2495 "ADVERTISE_FAILED_ALREADY_STARTED");
2497 if (data_too_large == errorCode)
2499 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2501 else if (already_started == errorCode)
2503 OIC_LOG_V(INFO, TAG, "advertising is already started");
2507 JNIEXPORT void JNICALL
2508 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerMtuChangedCallback(JNIEnv * env,
2513 VERIFY_NON_NULL_VOID(env, TAG, "env");
2514 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2515 VERIFY_NON_NULL_VOID(device, TAG, "device");
2517 OIC_LOG_V(INFO, TAG, "gatt MTU size is changed (%d byte)", mtu);
2519 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2522 OIC_LOG(ERROR, TAG, "jni_address is null");
2526 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2529 OIC_LOG(ERROR, TAG, "address is not available");
2530 (*env)->DeleteLocalRef(env, jni_address);
2535 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
2536 g_deviceStateList, g_deviceStateListMutex);
2537 if (CA_STATUS_OK != res)
2539 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
2542 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
2543 STATE_SEND_MTU_NEGO_SUCCESS,
2545 g_deviceStateListMutex);
2546 if (CA_STATUS_OK != res)
2548 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2551 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2552 (*env)->DeleteLocalRef(env, jni_address);
2559 CAResult_t CAStartLEGattServer()
2561 // start gatt service
2562 CALEServerStartMulticastServer();
2564 return CA_STATUS_OK;
2567 CAResult_t CAStopLEGattServer()
2569 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2571 VERIFY_NON_NULL_RET(g_jvm, TAG, "g_jvm is null", CA_STATUS_FAILED);
2574 bool isAttached = false;
2575 if (!CALEAttachCurrentThread(&env, g_jvm, &isAttached)){
2576 return CA_STATUS_FAILED;
2579 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2580 if (CA_STATUS_OK != ret)
2582 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2583 return CA_STATUS_FAILED;
2586 ret = CALEServerStopMulticastServer();
2587 if (CA_STATUS_OK != ret)
2589 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2590 return CA_STATUS_FAILED;
2593 ret = CALEServerDisconnectAllDevices(env);
2594 if (CA_STATUS_OK != ret)
2596 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2597 return CA_STATUS_FAILED;
2600 ret = CALEServerRemoveAllDevices(env);
2601 if (CA_STATUS_OK != ret)
2603 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2604 return CA_STATUS_FAILED;
2607 if (g_leAdvertiseCallback)
2609 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2612 if (g_bluetoothGattServer)
2614 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2617 if (g_bluetoothGattServerCallback)
2619 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2622 if (g_obj_bluetoothDevice)
2624 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2625 g_obj_bluetoothDevice = NULL;
2628 oc_mutex_lock(g_threadSendNotifyMutex);
2629 oc_cond_signal(g_threadSendNotifyCond);
2630 oc_mutex_unlock(g_threadSendNotifyMutex);
2632 g_isStartServer = false;
2636 (*g_jvm)->DetachCurrentThread(g_jvm);
2639 return CA_STATUS_OK;
2642 CAResult_t CAInitializeLEGattServer()
2644 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2645 return CALEServerInitialize();
2648 void CATerminateLEGattServer()
2650 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2651 CALEServerTerminate();
2654 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2656 oc_mutex_lock(g_bleReqRespCbMutex);
2657 g_CABLEServerDataReceivedCallback = callback;
2658 oc_mutex_unlock(g_bleReqRespCbMutex);
2661 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2663 g_serverErrorCallback = callback;
2666 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2667 const uint8_t *charValue,
2668 uint32_t charValueLen)
2670 CAResult_t result = CA_SEND_FAILED;
2671 VERIFY_NON_NULL(address, TAG, "env is null");
2672 VERIFY_NON_NULL(charValue, TAG, "device is null");
2676 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2682 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2683 uint32_t charValueLen)
2685 VERIFY_NON_NULL(charValue, TAG, "device is null");
2687 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2692 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2694 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2698 CAResult_t CALEServerInitMutexVaraibles()
2700 if (NULL == g_bleReqRespCbMutex)
2702 g_bleReqRespCbMutex = oc_mutex_new();
2703 if (NULL == g_bleReqRespCbMutex)
2705 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2706 return CA_STATUS_FAILED;
2710 if (NULL == g_bleClientBDAddressMutex)
2712 g_bleClientBDAddressMutex = oc_mutex_new();
2713 if (NULL == g_bleClientBDAddressMutex)
2715 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2716 return CA_STATUS_FAILED;
2720 if (NULL == g_connectedDeviceListMutex)
2722 g_connectedDeviceListMutex = oc_mutex_new();
2723 if (NULL == g_connectedDeviceListMutex)
2725 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2726 return CA_STATUS_FAILED;
2730 if (NULL == g_threadSendMutex)
2732 g_threadSendMutex = oc_mutex_new();
2733 if (NULL == g_threadSendMutex)
2735 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2736 return CA_STATUS_FAILED;
2740 if (NULL == g_threadSendNotifyMutex)
2742 g_threadSendNotifyMutex = oc_mutex_new();
2743 if (NULL == g_threadSendNotifyMutex)
2745 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2746 return CA_STATUS_FAILED;
2750 if (NULL == g_deviceStateListMutex)
2752 g_deviceStateListMutex = oc_mutex_new();
2753 if (NULL == g_deviceStateListMutex)
2755 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2756 return CA_STATUS_FAILED;
2760 return CA_STATUS_OK;
2763 void CALEServerTerminateMutexVaraibles()
2765 oc_mutex_free(g_bleReqRespCbMutex);
2766 g_bleReqRespCbMutex = NULL;
2768 oc_mutex_free(g_bleClientBDAddressMutex);
2769 g_bleClientBDAddressMutex = NULL;
2771 oc_mutex_free(g_connectedDeviceListMutex);
2772 g_connectedDeviceListMutex = NULL;
2774 oc_mutex_free(g_threadSendMutex);
2775 g_threadSendMutex = NULL;
2777 oc_mutex_free(g_threadSendNotifyMutex);
2778 g_threadSendNotifyMutex = NULL;
2780 oc_mutex_free(g_deviceStateListMutex);
2781 g_deviceStateListMutex = NULL;
2784 void CALEServerTerminateConditionVaraibles()
2786 OIC_LOG(DEBUG, TAG, "this method is not supported");
2789 bool CALEServerIsConnected(const char* address)
2791 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2792 STATE_SERVICE_CONNECTED,
2794 g_deviceStateListMutex))
2796 OIC_LOG(DEBUG, TAG, "current state is connected");
2799 OIC_LOG(DEBUG, TAG, "current state is not connected");
2803 uint16_t CALEServerGetMtuSize(const char* address)
2805 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);