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 = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothManager",
166 "getConnectionState",
167 "(Landroid/bluetooth/BluetoothDevice"
169 if (!jni_mid_getConnectionState)
171 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
175 if (!g_bluetoothManager)
177 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
181 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
182 jni_mid_getConnectionState,
183 device, GATT_PROFILE);
184 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
188 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
190 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
191 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
192 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
194 if (!g_bluetoothGattServer)
196 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
200 if (!CALEIsEnableBTAdapter(env))
202 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
206 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
207 jmethodID jni_mid_getService = CALEGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
209 "(Ljava/util/UUID;)Landroid/bluetooth/"
210 "BluetoothGattService;");
211 if (!jni_mid_getService)
213 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
217 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
218 if (!jni_obj_serviceUUID)
220 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
224 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
226 jni_obj_serviceUUID);
227 if (!jni_obj_bluetoothGattService)
229 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
233 jmethodID jni_mid_getCharacteristic = CALEGetJNIMethodID(env, "android/bluetooth/"
234 "BluetoothGattService",
237 "Landroid/bluetooth/"
238 "BluetoothGattCharacteristic;");
239 if (!jni_mid_getCharacteristic)
241 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
245 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
246 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
247 if (!jni_obj_responseUUID)
249 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
253 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
254 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
255 if (!jni_obj_bluetoothGattCharacteristic)
257 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
261 jmethodID jni_mid_setValue = CALEGetJNIMethodID(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");
278 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
279 return jni_obj_bluetoothGattCharacteristic;
282 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
284 OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
285 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
286 VERIFY_NON_NULL(device, TAG, "device is null");
287 VERIFY_NON_NULL(env, TAG, "env is null");
289 if (!CALEIsEnableBTAdapter(env))
291 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
292 return CA_ADAPTER_NOT_ENABLED;
295 if (STATE_CONNECTED != CALEServerGetConnectionState(env, device))
297 OIC_LOG(ERROR, TAG, "it is not connected state");
298 return CA_STATUS_FAILED;
301 jmethodID jni_mid_notifyCharacteristicChanged = CALEGetJNIMethodID(env,
302 CLASSPATH_BT_GATTSERVER,
303 "notifyCharacteristicChanged",
304 "(Landroid/bluetooth/BluetoothDevice;"
305 "Landroid/bluetooth/"
306 "BluetoothGattCharacteristic;Z)Z");
307 if (!jni_mid_notifyCharacteristicChanged)
309 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
310 return CA_STATUS_FAILED;
313 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
314 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
316 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
318 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
319 return CA_SEND_FAILED;
322 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
323 ca_mutex_lock(g_threadSendNotifyMutex);
324 if (!g_isSignalSetFlag)
326 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
327 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
328 WAIT_TIME_WRITE_CHARACTERISTIC))
330 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
331 ca_mutex_unlock(g_threadSendNotifyMutex);
332 return CA_STATUS_FAILED;
335 // reset flag set by writeCharacteristic Callback
336 g_isSignalSetFlag = false;
337 ca_mutex_unlock(g_threadSendNotifyMutex);
338 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
342 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
343 jint offset, jbyteArray value)
345 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
346 VERIFY_NON_NULL(env, TAG, "env is null");
347 VERIFY_NON_NULL(device, TAG, "device is null");
348 VERIFY_NON_NULL(value, TAG, "value is null");
350 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
352 if (!CALEIsEnableBTAdapter(env))
354 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
355 return CA_ADAPTER_NOT_ENABLED;
358 jmethodID jni_mid_sendResponse = CALEGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
360 "(Landroid/bluetooth/BluetoothDevice;"
362 if (!jni_mid_sendResponse)
364 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
365 return CA_STATUS_FAILED;
368 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
369 jni_mid_sendResponse, device,
370 requestId, status, offset,
372 if (JNI_FALSE == jni_boolean_sendResponse)
374 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
375 return CA_SEND_FAILED;
378 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
382 CAResult_t CALEStartAdvertise()
386 OIC_LOG(ERROR, TAG, "g_jvm is null");
387 return CA_STATUS_FAILED;
390 bool isAttached = false;
392 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
395 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
396 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
400 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
401 return CA_STATUS_FAILED;
407 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
408 if (CA_STATUS_OK != ret)
410 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
415 (*g_jvm)->DetachCurrentThread(g_jvm);
420 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
422 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
423 VERIFY_NON_NULL(env, TAG, "env is null");
424 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
426 if (!CALEIsEnableBTAdapter(env))
428 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
429 return CA_ADAPTER_NOT_ENABLED;
432 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
433 "android/bluetooth/le/"
434 "AdvertiseSettings$Builder");
435 if (!jni_cid_AdvertiseSettings)
437 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
438 return CA_STATUS_FAILED;
441 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
443 if (!jni_mid_AdvertiseSettings)
445 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
446 return CA_STATUS_FAILED;
449 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
450 jni_mid_AdvertiseSettings);
451 if (!jni_AdvertiseSettings)
453 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
454 return CA_STATUS_FAILED;
457 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
459 "(I)Landroid/bluetooth/le/"
460 "AdvertiseSettings$Builder;");
461 if (!jni_mid_setAdvertiseMode)
463 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
464 return CA_STATUS_FAILED;
467 // 0: Low power, 1: Balanced
468 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
469 jni_mid_setAdvertiseMode, 0);
470 if (!jni_obj_setAdvertiseMode)
472 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
473 return CA_STATUS_FAILED;
476 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
478 "(Z)Landroid/bluetooth/le/"
479 "AdvertiseSettings$Builder;");
480 if (!jni_mid_setConnectable)
482 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
483 return CA_STATUS_FAILED;
486 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
487 jni_mid_setConnectable, JNI_TRUE);
488 if (!jni_obj_setConnectable)
490 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
491 return CA_STATUS_FAILED;
494 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
495 "(I)Landroid/bluetooth/le/"
496 "AdvertiseSettings$Builder;");
497 if (!jni_mid_setTimeout)
499 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
500 return CA_STATUS_FAILED;
503 //A value of 0 will disable the time limit
504 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
505 jni_mid_setTimeout, 0);
506 if (!jni_obj_setTimeout)
508 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
509 return CA_STATUS_FAILED;
512 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
513 "android/bluetooth/le/"
514 "AdvertiseData$Builder");
515 if (!jni_cid_AdvertiseDataBuilder)
517 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
518 return CA_STATUS_FAILED;
521 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
523 if (!jni_mid_AdvertiseDataBuilder)
525 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
526 return CA_STATUS_FAILED;
529 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
530 jni_mid_AdvertiseDataBuilder);
531 if (!jni_AdvertiseDataBuilder)
533 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
534 return CA_STATUS_FAILED;
537 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
538 if (!jni_obj_serviceUUID)
540 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
541 return CA_STATUS_FAILED;
544 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
547 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
548 return CA_STATUS_FAILED;
551 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
553 "(Landroid/os/ParcelUuid;)Landroid/"
554 "bluetooth/le/AdvertiseData$Builder;");
555 if (!jni_mid_addServiceUuid)
557 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
558 return CA_STATUS_FAILED;
561 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
562 jni_mid_addServiceUuid,
564 if (!jni_obj_addServiceUuid)
566 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
567 return CA_STATUS_FAILED;
570 // Device name has to be included in advertise packet after Android API 23
571 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
572 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
573 "setIncludeDeviceName",
576 "AdvertiseData$Builder;");
577 if (!jni_mid_setIncludeDeviceName)
579 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
580 return CA_STATUS_FAILED;
583 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
584 jni_mid_setIncludeDeviceName,
586 if (!jni_obj_setIncludeDeviceName)
588 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
589 return CA_STATUS_FAILED;
592 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
593 if (!jni_cid_BTAdapter)
595 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
596 return CA_STATUS_FAILED;
599 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
601 "()Landroid/bluetooth/"
602 "BluetoothAdapter;");
603 if (!jni_mid_getDefaultAdapter)
605 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
606 return CA_STATUS_FAILED;
609 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
610 jni_mid_getDefaultAdapter);
611 if (!jni_obj_BTAdapter)
613 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
614 return CA_STATUS_FAILED;
617 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
618 "getBluetoothLeAdvertiser",
619 "()Landroid/bluetooth/le/"
620 "BluetoothLeAdvertiser;");
621 if (!jni_mid_getBluetoothLeAdvertiser)
623 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
624 return CA_STATUS_FAILED;
627 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
628 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
629 if (!jni_obj_getBluetoothLeAdvertiser)
631 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
632 return CA_STATUS_FAILED;
635 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
636 jni_cid_AdvertiseSettings,
638 "()Landroid/bluetooth/le/"
639 "AdvertiseSettings;");
640 if (!jni_mid_build_LeAdvertiseSettings)
642 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
643 return CA_STATUS_FAILED;
646 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
647 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
648 if (!jni_obj_build_LeAdvertiseSettings)
650 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
651 return CA_STATUS_FAILED;
654 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
656 "()Landroid/bluetooth/le/"
658 if (!jni_mid_build_LeAdvertiseData)
660 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
661 return CA_STATUS_FAILED;
664 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
665 jni_mid_build_LeAdvertiseData);
666 if (!jni_obj_build_LeAdvertiseData)
668 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
669 return CA_STATUS_FAILED;
672 jmethodID jni_mid_startAdvertising = CALEGetJNIMethodID(env, "android/bluetooth/le/"
673 "BluetoothLeAdvertiser",
675 "(Landroid/bluetooth/le/"
676 "AdvertiseSettings;Landroid/bluetooth/"
677 "le/AdvertiseData;Landroid/bluetooth/"
678 "le/AdvertiseCallback;)V");
679 if (!jni_mid_startAdvertising)
681 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
682 return CA_STATUS_FAILED;
685 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
686 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
689 if ((*env)->ExceptionCheck(env))
691 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
692 (*env)->ExceptionDescribe(env);
693 (*env)->ExceptionClear(env);
694 return CA_STATUS_FAILED;
697 OIC_LOG(DEBUG, TAG, "Advertising started!!");
699 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
703 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
705 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
706 VERIFY_NON_NULL(env, TAG, "env is null");
707 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
709 if (!CALEIsEnableBTAdapter(env))
711 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
712 return CA_ADAPTER_NOT_ENABLED;
715 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
716 if (!jni_cid_BTAdapter)
718 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
719 return CA_STATUS_FAILED;
722 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
724 "()Landroid/bluetooth/"
725 "BluetoothAdapter;");
726 if (!jni_mid_getDefaultAdapter)
728 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
729 return CA_STATUS_FAILED;
732 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
733 "getBluetoothLeAdvertiser",
734 "()Landroid/bluetooth/le/"
735 "BluetoothLeAdvertiser;");
736 if (!jni_mid_getBTLeAdvertiser)
738 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
739 return CA_STATUS_FAILED;
742 jmethodID jni_mid_stopAdvertising = CALEGetJNIMethodID(env, "android/bluetooth/le/"
743 "BluetoothLeAdvertiser",
745 "(Landroid/bluetooth/le/"
746 "AdvertiseCallback;)V");
747 if (!jni_mid_stopAdvertising)
749 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
750 return CA_STATUS_FAILED;
753 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
754 jni_mid_getDefaultAdapter);
755 if (!jni_obj_BTAdapter)
757 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
758 return CA_STATUS_FAILED;
761 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
762 jni_mid_getBTLeAdvertiser);
763 if (!jni_obj_getBluetoothLeAdvertiser)
765 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
766 return CA_STATUS_FAILED;
769 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
771 if ((*env)->ExceptionCheck(env))
773 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
774 (*env)->ExceptionDescribe(env);
775 (*env)->ExceptionClear(env);
776 return CA_STATUS_FAILED;
779 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
783 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
785 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
786 VERIFY_NON_NULL(env, TAG, "env is null");
787 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
789 if (!CALEIsEnableBTAdapter(env))
791 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
792 return CA_ADAPTER_NOT_ENABLED;
797 OIC_LOG(DEBUG, TAG, "Gatt server already started");
800 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
803 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
804 if (!bluetoothGattServer)
806 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
807 return CA_STATUS_FAILED;
810 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
811 if (!g_bluetoothGattServer)
813 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
814 return CA_STATUS_FAILED;
817 // create gatt service
818 jobject bluetoothGattService = CALEServerCreateGattService(env);
819 if (!bluetoothGattService)
821 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
822 return CA_STATUS_FAILED;
826 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
827 bluetoothGattService);
828 if (CA_STATUS_OK != res)
830 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
835 jobject CALEServerOpenGattServer(JNIEnv *env)
837 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
838 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
840 if (!CALEIsEnableBTAdapter(env))
842 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
846 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
847 if (!jni_cid_context)
849 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
853 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
855 "Ljava/lang/String;");
856 if (!jni_fid_bluetoothService)
858 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
862 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
864 "(Ljava/lang/String;)"
865 "Ljava/lang/Object;");
866 if (!jni_mid_getSystemService)
868 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
872 jmethodID jni_mid_openGattServer = CALEGetJNIMethodID(env, "android/bluetooth/"
875 "(Landroid/content/Context;"
876 "Landroid/bluetooth/"
877 "BluetoothGattServerCallback;)"
878 "Landroid/bluetooth/"
879 "BluetoothGattServer;");
880 if (!jni_mid_openGattServer)
882 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
886 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
887 jni_fid_bluetoothService);
888 if (!jni_obj_bluetoothService)
890 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
894 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
895 jni_mid_getSystemService,
896 jni_obj_bluetoothService);
897 if (!jni_obj_bluetoothManager)
899 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
903 if (g_bluetoothManager)
905 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
907 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
909 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
910 jni_mid_openGattServer,
912 g_bluetoothGattServerCallback);
913 if (!jni_obj_bluetoothGattServer)
915 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
919 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
920 return jni_obj_bluetoothGattServer;
923 jobject CALEServerCreateGattService(JNIEnv *env)
925 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
926 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
928 if (!CALEIsEnableBTAdapter(env))
930 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
934 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
935 "BluetoothGattService");
936 if (!jni_cid_bluetoothGattService)
938 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
942 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
943 "BluetoothGattCharacteristic");
944 if (!jni_cid_bluetoothGattCharacteristic)
946 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
950 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
951 "SERVICE_TYPE_PRIMARY", "I");
952 if (!jni_fid_serviceType)
954 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
958 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
959 jni_cid_bluetoothGattCharacteristic,
960 "PROPERTY_NOTIFY", "I");
961 if (!jni_fid_readProperties)
963 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
967 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
968 jni_cid_bluetoothGattCharacteristic,
969 "PROPERTY_WRITE_NO_RESPONSE", "I");
970 if (!jni_fid_writeProperties)
972 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
976 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
977 jni_cid_bluetoothGattCharacteristic,
978 "PERMISSION_READ", "I");
979 if (!jni_fid_readPermissions)
981 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
985 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
986 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
987 if (!jni_fid_writePermissions)
989 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
993 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
994 "<init>", "(Ljava/util/UUID;I)V");
995 if (!jni_mid_bluetoothGattService)
997 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1001 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1002 "addCharacteristic",
1003 "(Landroid/bluetooth/"
1004 "BluetoothGattCharacteristic;)Z");
1005 if (!jni_mid_addCharacteristic)
1007 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1011 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1012 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1013 if (!jni_mid_bluetoothGattCharacteristic)
1015 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1019 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1020 if (!jni_obj_serviceUUID)
1022 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1026 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1027 jni_fid_serviceType);
1028 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1029 jni_mid_bluetoothGattService,
1030 jni_obj_serviceUUID, jni_int_serviceType);
1031 if (!jni_bluetoothGattService)
1033 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1037 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1038 if (!jni_obj_readUuid)
1040 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1044 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1045 jni_cid_bluetoothGattCharacteristic,
1046 jni_fid_readProperties);
1048 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1049 jni_cid_bluetoothGattCharacteristic,
1050 jni_fid_readPermissions);
1052 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1053 jni_cid_bluetoothGattCharacteristic,
1054 jni_fid_writePermissions);
1056 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1057 jni_mid_bluetoothGattCharacteristic,
1058 jni_obj_readUuid, jni_int_readProperties,
1059 jni_int_readPermissions|
1060 jni_int_writePermissions);
1061 if (!jni_readCharacteristic)
1063 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1067 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1068 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1069 if (!jni_boolean_addReadCharacteristic)
1071 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1075 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1076 if (!jni_obj_writeUuid)
1078 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1082 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1083 jni_cid_bluetoothGattCharacteristic,
1084 jni_fid_writeProperties);
1086 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1087 jni_mid_bluetoothGattCharacteristic,
1088 jni_obj_writeUuid, jni_int_writeProperties,
1089 jni_int_writePermissions);
1090 if (!jni_writeCharacteristic)
1092 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1096 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1097 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1098 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1100 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1104 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1105 return jni_bluetoothGattService;
1108 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1110 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1111 VERIFY_NON_NULL(env, TAG, "env is null");
1112 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1114 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1115 "BluetoothGattDescriptor");
1116 if (!jni_cid_bluetoothGattDescriptor)
1118 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1119 return CA_STATUS_FAILED;
1122 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1123 jni_cid_bluetoothGattDescriptor,
1125 "(Ljava/util/UUID;I)V");
1126 if (!jni_mid_bluetoothGattDescriptor)
1128 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1129 return CA_STATUS_FAILED;
1132 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1133 jni_cid_bluetoothGattDescriptor,
1134 "PERMISSION_READ", "I");
1135 if (!jni_fid_readPermissions)
1137 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1138 return CA_STATUS_FAILED;
1141 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1142 if (!jni_obj_readUuid)
1144 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1145 return CA_STATUS_FAILED;
1148 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1149 jni_fid_readPermissions);
1151 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1153 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1154 jni_mid_bluetoothGattDescriptor,
1155 jni_obj_readUuid, jni_int_readPermissions);
1156 if (!jni_readDescriptor)
1158 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1159 return CA_STATUS_FAILED;
1162 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1163 "BluetoothGattCharacteristic");
1164 if (!jni_cid_GattCharacteristic)
1166 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1167 return CA_STATUS_FAILED;
1170 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1172 "(Landroid/bluetooth/"
1173 "BluetoothGattDescriptor;)Z");
1174 if (!jni_mid_addDescriptor)
1176 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1177 return CA_STATUS_FAILED;
1180 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1181 jni_mid_addDescriptor,
1182 jni_readDescriptor);
1184 if (JNI_FALSE == jni_boolean_addDescriptor)
1186 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1187 return CA_STATUS_FAILED;
1191 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1193 return CA_STATUS_OK;
1196 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1197 jobject bluetoothGattService)
1199 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1200 VERIFY_NON_NULL(env, TAG, "env is null");
1201 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1202 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1204 if (!CALEIsEnableBTAdapter(env))
1206 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1207 return CA_ADAPTER_NOT_ENABLED;
1210 jmethodID jni_mid_addService = CALEGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1212 "(Landroid/bluetooth/BluetoothGattService;)"
1214 if (!jni_mid_addService)
1216 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1217 return CA_STATUS_FAILED;
1220 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1222 bluetoothGattService);
1224 if (JNI_FALSE == jni_boolean_addService)
1226 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1227 return CA_STATUS_FAILED;
1230 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1231 return CA_STATUS_OK;
1234 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1236 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1237 VERIFY_NON_NULL(env, TAG, "env is null");
1238 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1240 if (!CALEIsEnableBTAdapter(env))
1242 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1243 return CA_ADAPTER_NOT_ENABLED;
1246 jmethodID jni_mid_connect = CALEGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1248 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1249 if (!jni_mid_connect)
1251 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1252 return CA_STATUS_FAILED;
1255 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1256 jni_mid_connect, bluetoothDevice,
1258 if (JNI_FALSE == jni_boolean_connect)
1260 OIC_LOG(ERROR, TAG, "Fail to connect");
1261 return CA_STATUS_FAILED;
1264 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1265 return CA_STATUS_OK;
1268 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1270 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1271 VERIFY_NON_NULL(env, TAG, "env is null");
1273 ca_mutex_lock(g_connectedDeviceListMutex);
1274 if (!g_connectedDeviceList)
1276 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1277 ca_mutex_unlock(g_connectedDeviceListMutex);
1278 return CA_STATUS_FAILED;
1281 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1282 for (uint32_t index = 0; index < length; index++)
1284 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1287 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1291 // disconnect for device obj
1292 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1293 if (CA_STATUS_OK != res)
1295 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1300 ca_mutex_unlock(g_connectedDeviceListMutex);
1301 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1302 return CA_STATUS_OK;
1305 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1307 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1308 VERIFY_NON_NULL(env, TAG, "env is null");
1309 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1311 if (!CALEIsEnableBTAdapter(env))
1313 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1314 return CA_ADAPTER_NOT_ENABLED;
1317 jmethodID jni_mid_cancelConnection = CALEGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1319 "(Landroid/bluetooth/BluetoothDevice;)"
1321 if (!jni_mid_cancelConnection)
1323 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1324 return CA_STATUS_FAILED;
1327 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1329 if ((*env)->ExceptionCheck(env))
1331 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1332 (*env)->ExceptionDescribe(env);
1333 (*env)->ExceptionClear(env);
1334 return CA_STATUS_FAILED;
1337 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1338 return CA_STATUS_OK;
1341 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1344 OIC_LOG(DEBUG, TAG, "GattServer Close");
1345 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1346 VERIFY_NON_NULL(env, TAG, "env is null");
1348 // get BluetoothGatt class
1349 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1350 jmethodID jni_mid_closeGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1352 if (!jni_mid_closeGatt)
1354 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1355 return CA_STATUS_OK;
1358 // call disconnect gatt method
1359 OIC_LOG(DEBUG, TAG, "request to close GATT");
1360 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1362 if ((*env)->ExceptionCheck(env))
1364 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1365 (*env)->ExceptionDescribe(env);
1366 (*env)->ExceptionClear(env);
1367 return CA_STATUS_FAILED;
1370 return CA_STATUS_OK;
1373 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1375 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1376 VERIFY_NON_NULL(env, TAG, "env is null");
1377 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1378 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1380 if (!CALEIsEnableBTAdapter(env))
1382 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1383 return CA_ADAPTER_NOT_ENABLED;
1386 jobject responseChar = CALEServerSetResponseData(env, responseData);
1389 OIC_LOG(ERROR, TAG, "responseChar is null");
1390 return CA_STATUS_FAILED;
1393 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1394 if (CA_STATUS_OK != result)
1396 OIC_LOG(ERROR, TAG, "Fail to send response data");
1400 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1404 CAResult_t CALEServerInitialize()
1406 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1408 CALeServerJniInit();
1412 OIC_LOG(ERROR, TAG, "g_jvm is null");
1413 return CA_STATUS_FAILED;
1416 bool isAttached = false;
1418 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1421 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1422 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1426 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1427 return CA_STATUS_FAILED;
1432 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1433 if (CA_STATUS_OK != ret)
1435 OIC_LOG(ERROR, TAG, "it is not supported");
1439 (*g_jvm)->DetachCurrentThread(g_jvm);
1444 g_threadSendNotifyCond = ca_cond_new();
1446 ret = CALEServerInitMutexVaraibles();
1447 if (CA_STATUS_OK != ret)
1449 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1453 (*g_jvm)->DetachCurrentThread(g_jvm);
1455 return CA_STATUS_FAILED;
1458 CALEServerJNISetContext();
1459 CALEServerCreateCachedDeviceList();
1461 ret = CALEServerCreateJniInterfaceObject();
1462 if (CA_STATUS_OK != ret)
1464 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1468 (*g_jvm)->DetachCurrentThread(g_jvm);
1470 return CA_STATUS_FAILED;
1475 (*g_jvm)->DetachCurrentThread(g_jvm);
1478 g_isInitializedServer = true;
1479 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1480 return CA_STATUS_OK;
1483 void CALEServerTerminate()
1485 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1489 OIC_LOG(ERROR, TAG, "g_jvm is null");
1493 bool isAttached = false;
1495 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1498 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1499 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1503 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1511 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1512 g_sendBuffer = NULL;
1515 if (g_bluetoothManager)
1517 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1518 g_bluetoothManager = NULL;
1521 ca_cond_free(g_threadSendNotifyCond);
1522 g_threadSendNotifyCond = NULL;
1524 CALEServerTerminateMutexVaraibles();
1525 CALEServerTerminateConditionVaraibles();
1527 g_isInitializedServer = false;
1531 (*g_jvm)->DetachCurrentThread(g_jvm);
1534 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1537 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1539 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1540 VERIFY_NON_NULL(address, TAG, "address is null");
1541 VERIFY_NON_NULL(data, TAG, "data is null");
1545 OIC_LOG(ERROR, TAG, "g_jvm is null");
1546 return CA_STATUS_FAILED;
1549 bool isAttached = false;
1551 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1554 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1555 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1559 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1560 return CA_STATUS_FAILED;
1565 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1566 if (CA_STATUS_OK != ret)
1568 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1573 (*g_jvm)->DetachCurrentThread(g_jvm);
1579 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1581 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1582 VERIFY_NON_NULL(data, TAG, "data is null");
1586 OIC_LOG(ERROR, TAG, "g_jvm is null");
1587 return CA_STATUS_FAILED;
1590 bool isAttached = false;
1592 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1595 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1596 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1600 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1601 return CA_STATUS_FAILED;
1606 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1607 if (CA_STATUS_OK != ret)
1609 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1614 (*g_jvm)->DetachCurrentThread(g_jvm);
1620 CAResult_t CALEServerStartMulticastServer()
1622 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1624 if (!g_isInitializedServer)
1626 OIC_LOG(INFO, TAG, "server is not initialized");
1627 return CA_STATUS_FAILED;
1630 if (g_isStartServer)
1632 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1633 return CA_STATUS_FAILED;
1638 OIC_LOG(ERROR, TAG, "g_jvm is null");
1639 return CA_STATUS_FAILED;
1642 bool isAttached = false;
1644 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1647 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1648 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1652 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1653 return CA_STATUS_FAILED;
1658 g_isStartServer = true;
1660 // start gatt server
1661 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1662 if (CA_STATUS_OK != ret)
1664 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1669 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1670 if (CA_STATUS_OK != ret)
1672 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1677 (*g_jvm)->DetachCurrentThread(g_jvm);
1680 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1684 CAResult_t CALEServerStopMulticastServer()
1686 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1688 if (false == g_isStartServer)
1690 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1691 return CA_STATUS_FAILED;
1696 OIC_LOG(ERROR, TAG, "g_jvm is null");
1697 return CA_STATUS_FAILED;
1700 bool isAttached = false;
1702 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1705 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1706 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1710 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1711 return CA_STATUS_FAILED;
1716 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1717 if (CA_STATUS_OK != ret)
1719 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1722 g_isStartServer = false;
1726 (*g_jvm)->DetachCurrentThread(g_jvm);
1729 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1733 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1735 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1736 g_packetReceiveCallback = callback;
1739 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1742 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1744 VERIFY_NON_NULL(env, TAG, "env is null");
1745 VERIFY_NON_NULL(address, TAG, "address is null");
1746 VERIFY_NON_NULL(data, TAG, "data is null");
1748 if (!g_connectedDeviceList)
1750 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1751 return CA_STATUS_FAILED;
1754 ca_mutex_lock(g_threadSendMutex);
1756 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1757 for (uint32_t index = 0; index < length; index++)
1759 OIC_LOG(DEBUG, TAG, "check device address");
1760 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1763 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1767 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1768 if (!jni_setAddress)
1770 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1773 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1776 OIC_LOG(ERROR, TAG, "setAddress is null");
1780 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1781 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1783 if (!strcmp(setAddress, address))
1785 OIC_LOG(DEBUG, TAG, "found the device");
1787 if (g_obj_bluetoothDevice)
1789 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1791 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1792 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1795 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1798 if (g_obj_bluetoothDevice)
1800 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1801 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1802 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1804 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1805 if (CA_STATUS_OK != res)
1807 OIC_LOG(ERROR, TAG, "send has failed");
1808 if (g_obj_bluetoothDevice)
1810 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1811 g_obj_bluetoothDevice = NULL;
1818 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1824 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1825 g_sendBuffer = NULL;
1828 ca_mutex_unlock(g_threadSendMutex);
1829 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1830 return CA_STATUS_OK;
1835 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1836 g_sendBuffer = NULL;
1839 ca_mutex_unlock(g_threadSendMutex);
1840 return CA_SEND_FAILED;
1843 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1845 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1846 VERIFY_NON_NULL(env, TAG, "env is null");
1847 VERIFY_NON_NULL(data, TAG, "data is null");
1849 if (!g_connectedDeviceList)
1851 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1852 return CA_STATUS_FAILED;
1855 ca_mutex_lock(g_threadSendMutex);
1857 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1860 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1861 g_sendBuffer = NULL;
1863 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1864 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1865 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1867 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1868 for (uint32_t index = 0; index < length; index++)
1870 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1873 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1877 // send data for all device
1878 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1879 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1881 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1884 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1888 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1891 OIC_LOG(ERROR, TAG, "address is not available");
1895 if (g_obj_bluetoothDevice)
1897 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1899 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1901 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
1902 if (CA_STATUS_OK != res)
1904 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
1905 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1906 if (g_obj_bluetoothDevice)
1908 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1909 g_obj_bluetoothDevice = NULL;
1914 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
1915 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1920 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1921 g_sendBuffer = NULL;
1924 ca_mutex_unlock(g_threadSendMutex);
1925 return CA_STATUS_OK;
1928 void CALEServerCreateCachedDeviceList()
1930 ca_mutex_lock(g_connectedDeviceListMutex);
1931 // create new object array
1932 if (!g_connectedDeviceList)
1934 OIC_LOG(DEBUG, TAG, "Create device list");
1935 g_connectedDeviceList = u_arraylist_create();
1937 ca_mutex_unlock(g_connectedDeviceListMutex);
1940 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1942 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1943 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1945 if (!g_connectedDeviceList)
1947 OIC_LOG(ERROR, TAG, "list is null");
1951 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1952 for (uint32_t index = 0; index < length; index++)
1954 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1958 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1962 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1963 if (!jni_setAddress)
1965 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1969 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1972 OIC_LOG(ERROR, TAG, "setAddress is null");
1976 if (!strcmp(remoteAddress, setAddress))
1978 OIC_LOG(ERROR, TAG, "the device is already set");
1979 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1984 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1989 OIC_LOG(DEBUG, TAG, "there are no device in the list");
1993 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1995 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
1996 VERIFY_NON_NULL(device, TAG, "device is null");
1997 VERIFY_NON_NULL(env, TAG, "env is null");
1999 ca_mutex_lock(g_connectedDeviceListMutex);
2001 if (!g_connectedDeviceList)
2003 OIC_LOG(ERROR, TAG, "list is null");
2004 ca_mutex_unlock(g_connectedDeviceListMutex);
2005 return CA_STATUS_FAILED;
2008 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2009 if (!jni_remoteAddress)
2011 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2012 ca_mutex_unlock(g_connectedDeviceListMutex);
2013 return CA_STATUS_FAILED;
2016 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2019 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2020 ca_mutex_unlock(g_connectedDeviceListMutex);
2021 return CA_STATUS_FAILED;
2024 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2026 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2027 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2028 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2031 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2032 ca_mutex_unlock(g_connectedDeviceListMutex);
2033 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2034 return CA_STATUS_OK;
2037 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2039 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2040 VERIFY_NON_NULL(env, TAG, "env is null");
2042 ca_mutex_lock(g_connectedDeviceListMutex);
2043 if (!g_connectedDeviceList)
2045 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2046 ca_mutex_unlock(g_connectedDeviceListMutex);
2047 return CA_STATUS_FAILED;
2050 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2051 for (uint32_t index = 0; index < length; index++)
2053 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2056 (*env)->DeleteGlobalRef(env, jarrayObj);
2060 OICFree(g_connectedDeviceList);
2061 g_connectedDeviceList = NULL;
2062 ca_mutex_unlock(g_connectedDeviceListMutex);
2064 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2065 return CA_STATUS_OK;
2068 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2070 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2071 VERIFY_NON_NULL(env, TAG, "env is null");
2072 VERIFY_NON_NULL(address, TAG, "address is null");
2074 ca_mutex_lock(g_connectedDeviceListMutex);
2075 if (!g_connectedDeviceList)
2077 OIC_LOG(ERROR, TAG, "no deviceList");
2078 ca_mutex_unlock(g_connectedDeviceListMutex);
2079 return CA_STATUS_FAILED;
2082 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2083 for (uint32_t index = 0; index < length; index++)
2085 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2089 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2090 if (!jni_setAddress)
2092 OIC_LOG(ERROR, TAG, "wrong device address");
2095 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2098 OIC_LOG(ERROR, TAG, "setAddress is null");
2102 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2105 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2106 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2110 if (!strcmp(setAddress, remoteAddress))
2112 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2114 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2115 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2116 (*env)->DeleteGlobalRef(env, jarrayObj);
2118 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2120 OIC_LOG(ERROR, TAG, "List removal failed.");
2121 ca_mutex_unlock(g_connectedDeviceListMutex);
2122 return CA_STATUS_FAILED;
2124 ca_mutex_unlock(g_connectedDeviceListMutex);
2125 return CA_STATUS_OK;
2127 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2128 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2132 ca_mutex_unlock(g_connectedDeviceListMutex);
2134 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2136 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2137 return CA_STATUS_FAILED;
2140 JNIEXPORT void JNICALL
2141 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2144 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2145 VERIFY_NON_NULL_VOID(env, TAG, "env");
2146 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2147 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2149 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2152 JNIEXPORT void JNICALL
2153 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2157 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2158 VERIFY_NON_NULL_VOID(env, TAG, "env");
2159 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2160 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2162 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2165 JNIEXPORT void JNICALL
2166 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2167 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2169 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2170 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2172 VERIFY_NON_NULL_VOID(env, TAG, "env");
2173 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2174 VERIFY_NON_NULL_VOID(device, TAG, "device");
2177 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
2179 // STATE_DISCONNECTED
2180 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
2182 if (newState == state_connected)
2185 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2187 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2188 if (!jni_remoteAddress)
2190 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2194 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2197 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2201 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2203 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2204 CALEServerAddDeviceToList(env, device);
2206 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2208 else if (newState == state_disconnected)
2210 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2212 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2213 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2214 if (CA_STATUS_OK != ret)
2216 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2220 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2221 if (CA_STATUS_OK != ret)
2223 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2228 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2233 JNIEXPORT void JNICALL
2234 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2237 jobject gattService)
2239 VERIFY_NON_NULL_VOID(env, TAG, "env");
2240 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2241 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2243 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2246 JNIEXPORT void JNICALL
2247 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2248 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2250 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2251 VERIFY_NON_NULL_VOID(env, TAG, "env");
2252 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2253 VERIFY_NON_NULL_VOID(device, TAG, "device");
2254 VERIFY_NON_NULL_VOID(data, TAG, "data");
2257 JNIEXPORT void JNICALL
2258 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2259 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2261 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2262 VERIFY_NON_NULL_VOID(env, TAG, "env");
2263 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2264 VERIFY_NON_NULL_VOID(device, TAG, "device");
2265 VERIFY_NON_NULL_VOID(data, TAG, "data");
2267 // get Byte Array and covert to uint8_t*
2268 jint length = (*env)->GetArrayLength(env, data);
2271 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2273 uint8_t* requestData = NULL;
2274 requestData = OICMalloc(length);
2277 OIC_LOG(ERROR, TAG, "requestData is null");
2281 memcpy(requestData, jni_byte_requestData, length);
2282 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2284 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2287 OIC_LOG(ERROR, TAG, "jni_address is null");
2288 OICFree(requestData);
2292 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2295 OIC_LOG(ERROR, TAG, "address is null");
2296 OICFree(requestData);
2300 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2302 ca_mutex_lock(g_bleClientBDAddressMutex);
2303 uint32_t sentLength = 0;
2304 g_CABLEServerDataReceivedCallback(address, requestData, length,
2306 ca_mutex_unlock(g_bleClientBDAddressMutex);
2308 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2311 JNIEXPORT void JNICALL
2312 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2317 VERIFY_NON_NULL_VOID(env, TAG, "env");
2318 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2319 VERIFY_NON_NULL_VOID(device, TAG, "device");
2321 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2324 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2325 if (gatt_success != status) // error case
2327 OIC_LOG(ERROR, TAG, "it will be sent again.");
2329 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2330 if (CA_STATUS_OK != res)
2332 OIC_LOG(ERROR, TAG, "send has failed");
2334 if (g_obj_bluetoothDevice)
2336 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2337 g_obj_bluetoothDevice = NULL;
2340 ca_mutex_lock(g_threadSendNotifyMutex);
2341 g_isSignalSetFlag = true;
2342 ca_cond_signal(g_threadSendNotifyCond);
2343 ca_mutex_unlock(g_threadSendNotifyMutex);
2349 OIC_LOG(DEBUG, TAG, "notify success");
2351 if (g_obj_bluetoothDevice)
2353 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2354 g_obj_bluetoothDevice = NULL;
2357 // next data can be sent
2358 ca_mutex_lock(g_threadSendNotifyMutex);
2359 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2360 g_isSignalSetFlag = true;
2361 ca_cond_signal(g_threadSendNotifyCond);
2362 ca_mutex_unlock(g_threadSendNotifyMutex);
2367 JNIEXPORT void JNICALL
2368 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2370 jobject settingsInEffect)
2372 VERIFY_NON_NULL_VOID(env, TAG, "env");
2373 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2374 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2376 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2379 JNIEXPORT void JNICALL
2380 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2384 VERIFY_NON_NULL_VOID(env, TAG, "env");
2385 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2387 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2389 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2390 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2391 if (data_too_large == errorCode)
2393 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2401 CAResult_t CAStartLEGattServer()
2403 // start gatt service
2404 CALEServerStartMulticastServer();
2406 return CA_STATUS_OK;
2409 CAResult_t CAStopLEGattServer()
2411 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2415 OIC_LOG(ERROR, TAG, "g_jvm is null");
2416 return CA_STATUS_FAILED;
2419 bool isAttached = false;
2421 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2424 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2425 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2429 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2430 return CA_STATUS_FAILED;
2435 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2436 if (CA_STATUS_OK != ret)
2438 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2439 return CA_STATUS_FAILED;
2442 ret = CALEServerStopMulticastServer();
2443 if (CA_STATUS_OK != ret)
2445 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2446 return CA_STATUS_FAILED;
2449 ret = CALEServerDisconnectAllDevices(env);
2450 if (CA_STATUS_OK != ret)
2452 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2453 return CA_STATUS_FAILED;
2456 ret = CALEServerRemoveAllDevices(env);
2457 if (CA_STATUS_OK != ret)
2459 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2460 return CA_STATUS_FAILED;
2463 if (g_leAdvertiseCallback)
2465 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2468 if (g_bluetoothGattServer)
2470 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2473 if (g_bluetoothGattServerCallback)
2475 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2478 if (g_obj_bluetoothDevice)
2480 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2481 g_obj_bluetoothDevice = NULL;
2484 ca_mutex_lock(g_threadSendNotifyMutex);
2485 ca_cond_signal(g_threadSendNotifyCond);
2486 ca_mutex_unlock(g_threadSendNotifyMutex);
2488 g_isStartServer = false;
2492 (*g_jvm)->DetachCurrentThread(g_jvm);
2495 return CA_STATUS_OK;
2498 CAResult_t CAInitializeLEGattServer()
2500 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2501 return CALEServerInitialize();
2504 void CATerminateLEGattServer()
2506 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2507 CALEServerTerminate();
2510 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2512 ca_mutex_lock(g_bleReqRespCbMutex);
2513 g_CABLEServerDataReceivedCallback = callback;
2514 ca_mutex_unlock(g_bleReqRespCbMutex);
2517 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2519 g_serverErrorCallback = callback;
2522 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2523 const uint8_t *charValue,
2524 uint32_t charValueLen)
2526 CAResult_t result = CA_SEND_FAILED;
2527 VERIFY_NON_NULL(address, TAG, "env is null");
2528 VERIFY_NON_NULL(charValue, TAG, "device is null");
2532 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2538 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2539 uint32_t charValueLen)
2541 VERIFY_NON_NULL(charValue, TAG, "device is null");
2543 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2548 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2550 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2554 CAResult_t CALEServerInitMutexVaraibles()
2556 if (NULL == g_bleReqRespCbMutex)
2558 g_bleReqRespCbMutex = ca_mutex_new();
2559 if (NULL == g_bleReqRespCbMutex)
2561 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2562 return CA_STATUS_FAILED;
2566 if (NULL == g_bleClientBDAddressMutex)
2568 g_bleClientBDAddressMutex = ca_mutex_new();
2569 if (NULL == g_bleClientBDAddressMutex)
2571 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2572 return CA_STATUS_FAILED;
2576 if (NULL == g_connectedDeviceListMutex)
2578 g_connectedDeviceListMutex = ca_mutex_new();
2579 if (NULL == g_connectedDeviceListMutex)
2581 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2582 return CA_STATUS_FAILED;
2586 if (NULL == g_threadSendMutex)
2588 g_threadSendMutex = ca_mutex_new();
2589 if (NULL == g_threadSendMutex)
2591 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2592 return CA_STATUS_FAILED;
2596 if (NULL == g_threadSendNotifyMutex)
2598 g_threadSendNotifyMutex = ca_mutex_new();
2599 if (NULL == g_threadSendNotifyMutex)
2601 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2602 return CA_STATUS_FAILED;
2606 return CA_STATUS_OK;
2609 void CALEServerTerminateMutexVaraibles()
2611 ca_mutex_free(g_bleReqRespCbMutex);
2612 g_bleReqRespCbMutex = NULL;
2614 ca_mutex_free(g_bleClientBDAddressMutex);
2615 g_bleClientBDAddressMutex = NULL;
2617 ca_mutex_free(g_connectedDeviceListMutex);
2618 g_connectedDeviceListMutex = NULL;
2620 ca_mutex_free(g_threadSendMutex);
2621 g_threadSendMutex = NULL;
2623 ca_mutex_free(g_threadSendNotifyMutex);
2624 g_threadSendNotifyMutex = NULL;
2627 void CALEServerTerminateConditionVaraibles()
2629 OIC_LOG(DEBUG, TAG, "this method is not supported");