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 void CALEServerJNISetContext()
72 OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
73 g_context = (jobject) CANativeJNIGetContext();
76 void CALeServerJniInit()
78 OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
79 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
82 CAResult_t CALEServerCreateJniInterfaceObject()
84 OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
88 OIC_LOG(ERROR, TAG, "g_context is null");
89 return CA_STATUS_FAILED;
94 OIC_LOG(ERROR, TAG, "g_jvm is null");
95 return CA_STATUS_FAILED;
98 bool isAttached = false;
100 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
103 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
104 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
108 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
109 return CA_STATUS_FAILED;
114 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
115 if (!jni_LEInterface)
117 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
121 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
123 if (!LeInterfaceConstructorMethod)
125 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
129 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
130 OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
134 (*g_jvm)->DetachCurrentThread(g_jvm);
143 (*g_jvm)->DetachCurrentThread(g_jvm);
146 return CA_STATUS_FAILED;
150 * get the current connection state of the gatt profile to the remote device.
151 * @param[in] env JNI interface pointer.
152 * @param[in] device bluetooth device object
153 * @return state of the profile connection.
155 static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
157 OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
159 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
160 VERIFY_NON_NULL_RET(device, TAG, "device", -1);
162 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
163 if (!jni_cid_bluetoothManager)
165 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
169 jmethodID jni_mid_getConnectionState = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
170 "getConnectionState",
171 "(Landroid/bluetooth/BluetoothDevice"
173 if (!jni_mid_getConnectionState)
175 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
179 if (!g_bluetoothManager)
181 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
185 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
186 jni_mid_getConnectionState,
187 device, GATT_PROFILE);
188 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
192 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
194 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
195 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
196 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
198 if (!g_bluetoothGattServer)
200 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
204 if (!CALEIsEnableBTAdapter(env))
206 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
210 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
212 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
213 "android/bluetooth/BluetoothGattServer");
214 if (!jni_cid_bluetoothGattServer)
216 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
220 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
221 "BluetoothGattService");
222 if (!jni_cid_bluetoothGattService)
224 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
228 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
229 "BluetoothGattCharacteristic");
230 if (!jni_cid_bluetoothGattCharacteristic)
232 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
236 jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
238 "(Ljava/util/UUID;)Landroid/bluetooth/"
239 "BluetoothGattService;");
240 if (!jni_mid_getService)
242 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
246 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
247 if (!jni_obj_serviceUUID)
249 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
253 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
255 jni_obj_serviceUUID);
256 if (!jni_obj_bluetoothGattService)
258 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
262 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
265 "Landroid/bluetooth/"
266 "BluetoothGattCharacteristic;");
267 if (!jni_mid_getCharacteristic)
269 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
273 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
274 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
275 if (!jni_obj_responseUUID)
277 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
281 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
282 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
283 if (!jni_obj_bluetoothGattCharacteristic)
285 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
289 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
290 "setValue", "([B)Z");
291 if (!jni_mid_setValue)
293 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
297 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
298 jni_obj_bluetoothGattCharacteristic,
299 jni_mid_setValue, responseData);
300 if (JNI_FALSE == jni_boolean_setValue)
302 OIC_LOG(ERROR, TAG, "Fail to set response data");
305 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
306 return jni_obj_bluetoothGattCharacteristic;
309 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
311 OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
312 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
313 VERIFY_NON_NULL(device, TAG, "device is null");
314 VERIFY_NON_NULL(env, TAG, "env is null");
316 if (!CALEIsEnableBTAdapter(env))
318 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
319 return CA_ADAPTER_NOT_ENABLED;
322 if (STATE_CONNECTED != CALEServerGetConnectionState(env, device))
324 OIC_LOG(ERROR, TAG, "it is not connected state");
325 return CA_STATUS_FAILED;
328 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
329 "android/bluetooth/BluetoothGattServer");
330 if (!jni_cid_bluetoothGattServer)
332 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
333 return CA_STATUS_FAILED;
336 jmethodID jni_mid_notifyCharacteristicChanged = (*env)->GetMethodID(
337 env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
338 "(Landroid/bluetooth/BluetoothDevice;"
339 "Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
340 if (!jni_mid_notifyCharacteristicChanged)
342 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
343 return CA_STATUS_FAILED;
346 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
347 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
349 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
351 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
352 return CA_SEND_FAILED;
355 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
356 ca_mutex_lock(g_threadSendNotifyMutex);
357 if (!g_isSignalSetFlag)
359 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
360 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
361 WAIT_TIME_WRITE_CHARACTERISTIC))
363 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
364 ca_mutex_unlock(g_threadSendNotifyMutex);
365 return CA_STATUS_FAILED;
368 // reset flag set by writeCharacteristic Callback
369 g_isSignalSetFlag = false;
370 ca_mutex_unlock(g_threadSendNotifyMutex);
371 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
375 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
376 jint offset, jbyteArray value)
378 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
379 VERIFY_NON_NULL(env, TAG, "env is null");
380 VERIFY_NON_NULL(device, TAG, "device is null");
381 VERIFY_NON_NULL(value, TAG, "value is null");
383 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
385 if (!CALEIsEnableBTAdapter(env))
387 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
388 return CA_ADAPTER_NOT_ENABLED;
391 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
392 "android/bluetooth/BluetoothGattServer");
393 if (!jni_cid_bluetoothGattServer)
395 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
396 return CA_STATUS_FAILED;
399 jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
401 "(Landroid/bluetooth/BluetoothDevice;"
403 if (!jni_mid_sendResponse)
405 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
406 return CA_STATUS_FAILED;
409 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
410 jni_mid_sendResponse, device,
411 requestId, status, offset,
413 if (JNI_FALSE == jni_boolean_sendResponse)
415 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
416 return CA_SEND_FAILED;
419 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
423 CAResult_t CALEStartAdvertise()
427 OIC_LOG(ERROR, TAG, "g_jvm is null");
428 return CA_STATUS_FAILED;
431 bool isAttached = false;
433 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
436 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
437 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
441 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
442 return CA_STATUS_FAILED;
448 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
449 if (CA_STATUS_OK != ret)
451 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
456 (*g_jvm)->DetachCurrentThread(g_jvm);
461 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
463 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
464 VERIFY_NON_NULL(env, TAG, "env is null");
465 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
467 if (!CALEIsEnableBTAdapter(env))
469 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
470 return CA_ADAPTER_NOT_ENABLED;
473 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
474 "android/bluetooth/le/"
475 "AdvertiseSettings$Builder");
476 if (!jni_cid_AdvertiseSettings)
478 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
479 return CA_STATUS_FAILED;
482 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
484 if (!jni_mid_AdvertiseSettings)
486 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
487 return CA_STATUS_FAILED;
490 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
491 jni_mid_AdvertiseSettings);
492 if (!jni_AdvertiseSettings)
494 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
495 return CA_STATUS_FAILED;
498 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
500 "(I)Landroid/bluetooth/le/"
501 "AdvertiseSettings$Builder;");
502 if (!jni_mid_setAdvertiseMode)
504 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
505 return CA_STATUS_FAILED;
508 // 0: Low power, 1: Balanced
509 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
510 jni_mid_setAdvertiseMode, 0);
511 if (!jni_obj_setAdvertiseMode)
513 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
514 return CA_STATUS_FAILED;
517 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
519 "(Z)Landroid/bluetooth/le/"
520 "AdvertiseSettings$Builder;");
521 if (!jni_mid_setConnectable)
523 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
524 return CA_STATUS_FAILED;
527 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
528 jni_mid_setConnectable, JNI_TRUE);
529 if (!jni_obj_setConnectable)
531 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
532 return CA_STATUS_FAILED;
535 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
536 "(I)Landroid/bluetooth/le/"
537 "AdvertiseSettings$Builder;");
538 if (!jni_mid_setTimeout)
540 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
541 return CA_STATUS_FAILED;
544 //A value of 0 will disable the time limit
545 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
546 jni_mid_setTimeout, 0);
547 if (!jni_obj_setTimeout)
549 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
550 return CA_STATUS_FAILED;
553 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
554 "android/bluetooth/le/"
555 "AdvertiseData$Builder");
556 if (!jni_cid_AdvertiseDataBuilder)
558 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
559 return CA_STATUS_FAILED;
562 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
564 if (!jni_mid_AdvertiseDataBuilder)
566 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
567 return CA_STATUS_FAILED;
570 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
571 jni_mid_AdvertiseDataBuilder);
572 if (!jni_AdvertiseDataBuilder)
574 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
575 return CA_STATUS_FAILED;
578 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
579 if (!jni_obj_serviceUUID)
581 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
582 return CA_STATUS_FAILED;
585 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
588 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
589 return CA_STATUS_FAILED;
592 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
594 "(Landroid/os/ParcelUuid;)Landroid/"
595 "bluetooth/le/AdvertiseData$Builder;");
596 if (!jni_mid_addServiceUuid)
598 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
599 return CA_STATUS_FAILED;
602 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
603 jni_mid_addServiceUuid,
605 if (!jni_obj_addServiceUuid)
607 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
608 return CA_STATUS_FAILED;
611 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
612 if (!jni_cid_BTAdapter)
614 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
615 return CA_STATUS_FAILED;
618 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
620 "()Landroid/bluetooth/"
621 "BluetoothAdapter;");
622 if (!jni_mid_getDefaultAdapter)
624 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
625 return CA_STATUS_FAILED;
628 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
629 jni_mid_getDefaultAdapter);
630 if (!jni_obj_BTAdapter)
632 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
633 return CA_STATUS_FAILED;
636 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
637 "getBluetoothLeAdvertiser",
638 "()Landroid/bluetooth/le/"
639 "BluetoothLeAdvertiser;");
640 if (!jni_mid_getBluetoothLeAdvertiser)
642 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
643 return CA_STATUS_FAILED;
646 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
647 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
648 if (!jni_obj_getBluetoothLeAdvertiser)
650 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
651 return CA_STATUS_FAILED;
654 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
655 jni_cid_AdvertiseSettings,
657 "()Landroid/bluetooth/le/"
658 "AdvertiseSettings;");
659 if (!jni_mid_build_LeAdvertiseSettings)
661 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
662 return CA_STATUS_FAILED;
665 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
666 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
667 if (!jni_obj_build_LeAdvertiseSettings)
669 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
670 return CA_STATUS_FAILED;
673 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
675 "()Landroid/bluetooth/le/"
677 if (!jni_mid_build_LeAdvertiseData)
679 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
680 return CA_STATUS_FAILED;
683 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
684 jni_mid_build_LeAdvertiseData);
685 if (!jni_obj_build_LeAdvertiseData)
687 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
688 return CA_STATUS_FAILED;
691 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
692 "android/bluetooth/le/BluetoothLeAdvertiser");
693 if (!jni_cid_leAdvertiser)
695 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
696 return CA_STATUS_FAILED;
699 jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
701 "(Landroid/bluetooth/le/"
702 "AdvertiseSettings;Landroid/bluetooth/"
703 "le/AdvertiseData;Landroid/bluetooth/"
704 "le/AdvertiseCallback;)V");
705 if (!jni_mid_startAdvertising)
707 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
708 return CA_STATUS_FAILED;
711 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
712 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
715 if ((*env)->ExceptionCheck(env))
717 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
718 (*env)->ExceptionDescribe(env);
719 (*env)->ExceptionClear(env);
720 return CA_STATUS_FAILED;
723 OIC_LOG(DEBUG, TAG, "Advertising started!!");
725 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
729 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
731 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
732 VERIFY_NON_NULL(env, TAG, "env is null");
733 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
735 if (!CALEIsEnableBTAdapter(env))
737 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
738 return CA_ADAPTER_NOT_ENABLED;
741 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
742 if (!jni_cid_BTAdapter)
744 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
745 return CA_STATUS_FAILED;
748 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
749 "android/bluetooth/le/BluetoothLeAdvertiser");
750 if (!jni_cid_leAdvertiser)
752 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
753 return CA_STATUS_FAILED;
756 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
758 "()Landroid/bluetooth/"
759 "BluetoothAdapter;");
760 if (!jni_mid_getDefaultAdapter)
762 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
763 return CA_STATUS_FAILED;
766 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
767 "getBluetoothLeAdvertiser",
768 "()Landroid/bluetooth/le/"
769 "BluetoothLeAdvertiser;");
770 if (!jni_mid_getBTLeAdvertiser)
772 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
773 return CA_STATUS_FAILED;
776 jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
778 "(Landroid/bluetooth/le/"
779 "AdvertiseCallback;)V");
780 if (!jni_mid_stopAdvertising)
782 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
783 return CA_STATUS_FAILED;
786 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
787 jni_mid_getDefaultAdapter);
788 if (!jni_obj_BTAdapter)
790 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
791 return CA_STATUS_FAILED;
794 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
795 jni_mid_getBTLeAdvertiser);
796 if (!jni_obj_getBluetoothLeAdvertiser)
798 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
799 return CA_STATUS_FAILED;
802 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
804 if ((*env)->ExceptionCheck(env))
806 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
807 (*env)->ExceptionDescribe(env);
808 (*env)->ExceptionClear(env);
809 return CA_STATUS_FAILED;
812 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
816 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
818 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
819 VERIFY_NON_NULL(env, TAG, "env is null");
820 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
822 if (!CALEIsEnableBTAdapter(env))
824 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
825 return CA_ADAPTER_NOT_ENABLED;
830 OIC_LOG(DEBUG, TAG, "Gatt server already started");
833 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
836 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
837 if (!bluetoothGattServer)
839 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
840 return CA_STATUS_FAILED;
843 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
844 if (!g_bluetoothGattServer)
846 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
847 return CA_STATUS_FAILED;
850 // create gatt service
851 jobject bluetoothGattService = CALEServerCreateGattService(env);
852 if (!bluetoothGattService)
854 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
855 return CA_STATUS_FAILED;
859 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
860 bluetoothGattService);
861 if (CA_STATUS_OK != res)
863 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
868 jobject CALEServerOpenGattServer(JNIEnv *env)
870 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
871 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
873 if (!CALEIsEnableBTAdapter(env))
875 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
879 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
880 if (!jni_cid_context)
882 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
886 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
887 if (!jni_cid_bluetoothManager)
889 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
893 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
895 "Ljava/lang/String;");
896 if (!jni_fid_bluetoothService)
898 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
902 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
904 "(Ljava/lang/String;)"
905 "Ljava/lang/Object;");
906 if (!jni_mid_getSystemService)
908 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
912 jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
914 "(Landroid/content/Context;"
915 "Landroid/bluetooth/"
916 "BluetoothGattServerCallback;)"
917 "Landroid/bluetooth/"
918 "BluetoothGattServer;");
919 if (!jni_mid_openGattServer)
921 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
925 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
926 jni_fid_bluetoothService);
927 if (!jni_obj_bluetoothService)
929 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
933 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
934 jni_mid_getSystemService,
935 jni_obj_bluetoothService);
936 if (!jni_obj_bluetoothManager)
938 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
942 if (g_bluetoothManager)
944 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
946 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
948 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
949 jni_mid_openGattServer,
951 g_bluetoothGattServerCallback);
952 if (!jni_obj_bluetoothGattServer)
954 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
958 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
959 return jni_obj_bluetoothGattServer;
962 jobject CALEServerCreateGattService(JNIEnv *env)
964 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
965 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
967 if (!CALEIsEnableBTAdapter(env))
969 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
973 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
974 "BluetoothGattService");
975 if (!jni_cid_bluetoothGattService)
977 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
981 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
982 "BluetoothGattCharacteristic");
983 if (!jni_cid_bluetoothGattCharacteristic)
985 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
989 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
990 "SERVICE_TYPE_PRIMARY", "I");
991 if (!jni_fid_serviceType)
993 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
997 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
998 jni_cid_bluetoothGattCharacteristic,
999 "PROPERTY_NOTIFY", "I");
1000 if (!jni_fid_readProperties)
1002 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1006 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1007 jni_cid_bluetoothGattCharacteristic,
1008 "PROPERTY_WRITE_NO_RESPONSE", "I");
1009 if (!jni_fid_writeProperties)
1011 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1015 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1016 jni_cid_bluetoothGattCharacteristic,
1017 "PERMISSION_READ", "I");
1018 if (!jni_fid_readPermissions)
1020 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1024 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1025 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1026 if (!jni_fid_writePermissions)
1028 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1032 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1033 "<init>", "(Ljava/util/UUID;I)V");
1034 if (!jni_mid_bluetoothGattService)
1036 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1040 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1041 "addCharacteristic",
1042 "(Landroid/bluetooth/"
1043 "BluetoothGattCharacteristic;)Z");
1044 if (!jni_mid_addCharacteristic)
1046 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1050 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1051 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1052 if (!jni_mid_bluetoothGattCharacteristic)
1054 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1058 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1059 if (!jni_obj_serviceUUID)
1061 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1065 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1066 jni_fid_serviceType);
1067 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1068 jni_mid_bluetoothGattService,
1069 jni_obj_serviceUUID, jni_int_serviceType);
1070 if (!jni_bluetoothGattService)
1072 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1076 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1077 if (!jni_obj_readUuid)
1079 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1083 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1084 jni_cid_bluetoothGattCharacteristic,
1085 jni_fid_readProperties);
1087 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1088 jni_cid_bluetoothGattCharacteristic,
1089 jni_fid_readPermissions);
1091 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1092 jni_cid_bluetoothGattCharacteristic,
1093 jni_fid_writePermissions);
1095 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1096 jni_mid_bluetoothGattCharacteristic,
1097 jni_obj_readUuid, jni_int_readProperties,
1098 jni_int_readPermissions|
1099 jni_int_writePermissions);
1100 if (!jni_readCharacteristic)
1102 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1106 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1107 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1108 if (!jni_boolean_addReadCharacteristic)
1110 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1114 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1115 if (!jni_obj_writeUuid)
1117 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1121 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1122 jni_cid_bluetoothGattCharacteristic,
1123 jni_fid_writeProperties);
1125 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1126 jni_mid_bluetoothGattCharacteristic,
1127 jni_obj_writeUuid, jni_int_writeProperties,
1128 jni_int_writePermissions);
1129 if (!jni_writeCharacteristic)
1131 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1135 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1136 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1137 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1139 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1143 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1144 return jni_bluetoothGattService;
1147 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1149 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1150 VERIFY_NON_NULL(env, TAG, "env is null");
1151 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1153 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1154 "BluetoothGattDescriptor");
1155 if (!jni_cid_bluetoothGattDescriptor)
1157 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1158 return CA_STATUS_FAILED;
1161 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1162 jni_cid_bluetoothGattDescriptor,
1164 "(Ljava/util/UUID;I)V");
1165 if (!jni_mid_bluetoothGattDescriptor)
1167 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1168 return CA_STATUS_FAILED;
1171 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1172 jni_cid_bluetoothGattDescriptor,
1173 "PERMISSION_READ", "I");
1174 if (!jni_fid_readPermissions)
1176 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1177 return CA_STATUS_FAILED;
1180 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1181 if (!jni_obj_readUuid)
1183 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1184 return CA_STATUS_FAILED;
1187 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1188 jni_fid_readPermissions);
1190 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1192 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1193 jni_mid_bluetoothGattDescriptor,
1194 jni_obj_readUuid, jni_int_readPermissions);
1195 if (!jni_readDescriptor)
1197 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1198 return CA_STATUS_FAILED;
1201 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1202 "BluetoothGattCharacteristic");
1203 if (!jni_cid_GattCharacteristic)
1205 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1206 return CA_STATUS_FAILED;
1209 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1211 "(Landroid/bluetooth/"
1212 "BluetoothGattDescriptor;)Z");
1213 if (!jni_mid_addDescriptor)
1215 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1216 return CA_STATUS_FAILED;
1219 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1220 jni_mid_addDescriptor,
1221 jni_readDescriptor);
1223 if (JNI_FALSE == jni_boolean_addDescriptor)
1225 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1226 return CA_STATUS_FAILED;
1230 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1232 return CA_STATUS_OK;
1235 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1236 jobject bluetoothGattService)
1238 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1239 VERIFY_NON_NULL(env, TAG, "env is null");
1240 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1241 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1243 if (!CALEIsEnableBTAdapter(env))
1245 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1246 return CA_ADAPTER_NOT_ENABLED;
1249 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1250 "android/bluetooth/BluetoothGattServer");
1251 if (!jni_cid_bluetoothGattServer)
1253 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1254 return CA_STATUS_FAILED;
1257 jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1259 "(Landroid/bluetooth/BluetoothGattService;)"
1261 if (!jni_mid_addService)
1263 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1264 return CA_STATUS_FAILED;
1267 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1269 bluetoothGattService);
1271 if (JNI_FALSE == jni_boolean_addService)
1273 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1274 return CA_STATUS_FAILED;
1277 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1278 return CA_STATUS_OK;
1281 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1283 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1284 VERIFY_NON_NULL(env, TAG, "env is null");
1285 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1287 if (!CALEIsEnableBTAdapter(env))
1289 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1290 return CA_ADAPTER_NOT_ENABLED;
1293 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1294 "android/bluetooth/BluetoothGattServer");
1295 if (!jni_cid_bluetoothGattServer)
1297 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1298 return CA_STATUS_FAILED;
1301 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1302 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1303 if (!jni_mid_connect)
1305 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1306 return CA_STATUS_FAILED;
1309 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1310 jni_mid_connect, bluetoothDevice,
1312 if (JNI_FALSE == jni_boolean_connect)
1314 OIC_LOG(ERROR, TAG, "Fail to connect");
1315 return CA_STATUS_FAILED;
1318 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1319 return CA_STATUS_OK;
1322 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1324 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1325 VERIFY_NON_NULL(env, TAG, "env is null");
1327 ca_mutex_lock(g_connectedDeviceListMutex);
1328 if (!g_connectedDeviceList)
1330 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1331 ca_mutex_unlock(g_connectedDeviceListMutex);
1332 return CA_STATUS_FAILED;
1335 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1336 for (uint32_t index = 0; index < length; index++)
1338 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1341 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1345 // disconnect for device obj
1346 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1347 if (CA_STATUS_OK != res)
1349 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1354 ca_mutex_unlock(g_connectedDeviceListMutex);
1355 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1356 return CA_STATUS_OK;
1359 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1361 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1362 VERIFY_NON_NULL(env, TAG, "env is null");
1363 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1365 if (!CALEIsEnableBTAdapter(env))
1367 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1368 return CA_ADAPTER_NOT_ENABLED;
1371 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1372 "android/bluetooth/BluetoothGattServer");
1373 if (!jni_cid_bluetoothGattServer)
1375 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1376 return CA_STATUS_FAILED;
1379 jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1381 "(Landroid/bluetooth/BluetoothDevice;)"
1383 if (!jni_mid_cancelConnection)
1385 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1386 return CA_STATUS_FAILED;
1389 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1391 if ((*env)->ExceptionCheck(env))
1393 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1394 (*env)->ExceptionDescribe(env);
1395 (*env)->ExceptionClear(env);
1396 return CA_STATUS_FAILED;
1399 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1400 return CA_STATUS_OK;
1403 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1406 OIC_LOG(DEBUG, TAG, "GattServer Close");
1407 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1408 VERIFY_NON_NULL(env, TAG, "env is null");
1410 // get BluetoothGatt class
1411 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1412 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
1413 if (!jni_cid_BluetoothGatt)
1415 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1416 return CA_STATUS_FAILED;
1419 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1420 if (!jni_mid_closeGatt)
1422 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1423 return CA_STATUS_OK;
1426 // call disconnect gatt method
1427 OIC_LOG(DEBUG, TAG, "request to close GATT");
1428 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1430 if ((*env)->ExceptionCheck(env))
1432 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1433 (*env)->ExceptionDescribe(env);
1434 (*env)->ExceptionClear(env);
1435 return CA_STATUS_FAILED;
1438 return CA_STATUS_OK;
1441 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1443 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1444 VERIFY_NON_NULL(env, TAG, "env is null");
1445 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1446 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1448 if (!CALEIsEnableBTAdapter(env))
1450 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1451 return CA_ADAPTER_NOT_ENABLED;
1454 jobject responseChar = CALEServerSetResponseData(env, responseData);
1457 OIC_LOG(ERROR, TAG, "responseChar is null");
1458 return CA_STATUS_FAILED;
1461 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1462 if (CA_STATUS_OK != result)
1464 OIC_LOG(ERROR, TAG, "Fail to send response data");
1468 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1472 CAResult_t CALEServerInitialize()
1474 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1476 CALeServerJniInit();
1480 OIC_LOG(ERROR, TAG, "g_jvm is null");
1481 return CA_STATUS_FAILED;
1484 bool isAttached = false;
1486 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1489 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1490 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1494 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1495 return CA_STATUS_FAILED;
1500 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1501 if (CA_STATUS_OK != ret)
1503 OIC_LOG(ERROR, TAG, "it is not supported");
1507 (*g_jvm)->DetachCurrentThread(g_jvm);
1512 g_threadSendNotifyCond = ca_cond_new();
1514 ret = CALEServerInitMutexVaraibles();
1515 if (CA_STATUS_OK != ret)
1517 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1521 (*g_jvm)->DetachCurrentThread(g_jvm);
1523 return CA_STATUS_FAILED;
1526 CALEServerJNISetContext();
1527 CALEServerCreateCachedDeviceList();
1529 ret = CALEServerCreateJniInterfaceObject();
1530 if (CA_STATUS_OK != ret)
1532 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1536 (*g_jvm)->DetachCurrentThread(g_jvm);
1538 return CA_STATUS_FAILED;
1543 (*g_jvm)->DetachCurrentThread(g_jvm);
1546 g_isInitializedServer = true;
1547 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1548 return CA_STATUS_OK;
1551 void CALEServerTerminate()
1553 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1557 OIC_LOG(ERROR, TAG, "g_jvm is null");
1561 bool isAttached = false;
1563 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1566 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1567 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1571 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
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 ca_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");
1613 OIC_LOG(ERROR, TAG, "g_jvm is null");
1614 return CA_STATUS_FAILED;
1617 bool isAttached = false;
1619 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1622 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1623 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1627 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1628 return CA_STATUS_FAILED;
1633 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1634 if (CA_STATUS_OK != ret)
1636 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1641 (*g_jvm)->DetachCurrentThread(g_jvm);
1647 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1649 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1650 VERIFY_NON_NULL(data, TAG, "data is null");
1654 OIC_LOG(ERROR, TAG, "g_jvm is null");
1655 return CA_STATUS_FAILED;
1658 bool isAttached = false;
1660 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1663 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1664 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1668 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1669 return CA_STATUS_FAILED;
1674 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1675 if (CA_STATUS_OK != ret)
1677 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1682 (*g_jvm)->DetachCurrentThread(g_jvm);
1688 CAResult_t CALEServerStartMulticastServer()
1690 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1692 if (!g_isInitializedServer)
1694 OIC_LOG(INFO, TAG, "server is not initialized");
1695 return CA_STATUS_FAILED;
1698 if (g_isStartServer)
1700 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1701 return CA_STATUS_FAILED;
1706 OIC_LOG(ERROR, TAG, "g_jvm is null");
1707 return CA_STATUS_FAILED;
1710 bool isAttached = false;
1712 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1715 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1716 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1720 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1721 return CA_STATUS_FAILED;
1726 g_isStartServer = true;
1728 // start gatt server
1729 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1730 if (CA_STATUS_OK != ret)
1732 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1737 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1738 if (CA_STATUS_OK != ret)
1740 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1745 (*g_jvm)->DetachCurrentThread(g_jvm);
1748 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1752 CAResult_t CALEServerStopMulticastServer()
1754 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1756 if (false == g_isStartServer)
1758 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1759 return CA_STATUS_FAILED;
1764 OIC_LOG(ERROR, TAG, "g_jvm is null");
1765 return CA_STATUS_FAILED;
1768 bool isAttached = false;
1770 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1773 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1774 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1778 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1779 return CA_STATUS_FAILED;
1784 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1785 if (CA_STATUS_OK != ret)
1787 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1790 g_isStartServer = false;
1794 (*g_jvm)->DetachCurrentThread(g_jvm);
1797 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1801 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1803 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1804 g_packetReceiveCallback = callback;
1807 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1810 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1812 VERIFY_NON_NULL(env, TAG, "env is null");
1813 VERIFY_NON_NULL(address, TAG, "address is null");
1814 VERIFY_NON_NULL(data, TAG, "data is null");
1816 if (!g_connectedDeviceList)
1818 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1819 return CA_STATUS_FAILED;
1822 ca_mutex_lock(g_threadSendMutex);
1824 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1825 for (uint32_t index = 0; index < length; index++)
1827 OIC_LOG(DEBUG, TAG, "check device address");
1828 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1831 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1835 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1836 if (!jni_setAddress)
1838 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1841 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1844 OIC_LOG(ERROR, TAG, "setAddress is null");
1848 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1849 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1851 if (!strcmp(setAddress, address))
1853 OIC_LOG(DEBUG, TAG, "found the device");
1855 if (g_obj_bluetoothDevice)
1857 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1859 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1860 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1863 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1866 if (g_obj_bluetoothDevice)
1868 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1869 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1870 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1872 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1873 if (CA_STATUS_OK != res)
1875 OIC_LOG(ERROR, TAG, "send has failed");
1876 if (g_obj_bluetoothDevice)
1878 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1879 g_obj_bluetoothDevice = NULL;
1886 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1892 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1893 g_sendBuffer = NULL;
1896 ca_mutex_unlock(g_threadSendMutex);
1897 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1898 return CA_STATUS_OK;
1903 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1904 g_sendBuffer = NULL;
1907 ca_mutex_unlock(g_threadSendMutex);
1908 return CA_SEND_FAILED;
1911 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1913 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1914 VERIFY_NON_NULL(env, TAG, "env is null");
1915 VERIFY_NON_NULL(data, TAG, "data is null");
1917 if (!g_connectedDeviceList)
1919 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1920 return CA_STATUS_FAILED;
1923 ca_mutex_lock(g_threadSendMutex);
1925 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1928 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1929 g_sendBuffer = NULL;
1931 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1932 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1933 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1935 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1936 for (uint32_t index = 0; index < length; index++)
1938 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1941 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1945 // send data for all device
1946 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1947 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1949 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1952 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1956 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1959 OIC_LOG(ERROR, TAG, "address is not available");
1963 if (g_obj_bluetoothDevice)
1965 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1967 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1969 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
1970 if (CA_STATUS_OK != res)
1972 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
1973 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1974 if (g_obj_bluetoothDevice)
1976 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1977 g_obj_bluetoothDevice = NULL;
1982 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
1983 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1988 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1989 g_sendBuffer = NULL;
1992 ca_mutex_unlock(g_threadSendMutex);
1993 return CA_STATUS_OK;
1996 void CALEServerCreateCachedDeviceList()
1998 ca_mutex_lock(g_connectedDeviceListMutex);
1999 // create new object array
2000 if (!g_connectedDeviceList)
2002 OIC_LOG(DEBUG, TAG, "Create device list");
2003 g_connectedDeviceList = u_arraylist_create();
2005 ca_mutex_unlock(g_connectedDeviceListMutex);
2008 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
2010 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
2011 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2013 if (!g_connectedDeviceList)
2015 OIC_LOG(ERROR, TAG, "list is null");
2019 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2020 for (uint32_t index = 0; index < length; index++)
2022 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2026 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2030 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2031 if (!jni_setAddress)
2033 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2037 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2040 OIC_LOG(ERROR, TAG, "setAddress is null");
2044 if (!strcmp(remoteAddress, setAddress))
2046 OIC_LOG(ERROR, TAG, "the device is already set");
2047 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2052 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2057 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2061 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2063 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2064 VERIFY_NON_NULL(device, TAG, "device is null");
2065 VERIFY_NON_NULL(env, TAG, "env is null");
2067 ca_mutex_lock(g_connectedDeviceListMutex);
2069 if (!g_connectedDeviceList)
2071 OIC_LOG(ERROR, TAG, "list is null");
2072 ca_mutex_unlock(g_connectedDeviceListMutex);
2073 return CA_STATUS_FAILED;
2076 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2077 if (!jni_remoteAddress)
2079 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2080 ca_mutex_unlock(g_connectedDeviceListMutex);
2081 return CA_STATUS_FAILED;
2084 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2087 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2088 ca_mutex_unlock(g_connectedDeviceListMutex);
2089 return CA_STATUS_FAILED;
2092 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2094 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2095 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2096 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2099 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2100 ca_mutex_unlock(g_connectedDeviceListMutex);
2101 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2102 return CA_STATUS_OK;
2105 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2107 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2108 VERIFY_NON_NULL(env, TAG, "env is null");
2110 ca_mutex_lock(g_connectedDeviceListMutex);
2111 if (!g_connectedDeviceList)
2113 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2114 ca_mutex_unlock(g_connectedDeviceListMutex);
2115 return CA_STATUS_FAILED;
2118 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2119 for (uint32_t index = 0; index < length; index++)
2121 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2124 (*env)->DeleteGlobalRef(env, jarrayObj);
2128 OICFree(g_connectedDeviceList);
2129 g_connectedDeviceList = NULL;
2130 ca_mutex_unlock(g_connectedDeviceListMutex);
2132 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2133 return CA_STATUS_OK;
2136 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2138 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2139 VERIFY_NON_NULL(env, TAG, "env is null");
2140 VERIFY_NON_NULL(address, TAG, "address is null");
2142 ca_mutex_lock(g_connectedDeviceListMutex);
2143 if (!g_connectedDeviceList)
2145 OIC_LOG(ERROR, TAG, "no deviceList");
2146 ca_mutex_unlock(g_connectedDeviceListMutex);
2147 return CA_STATUS_FAILED;
2150 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2151 for (uint32_t index = 0; index < length; index++)
2153 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2157 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2158 if (!jni_setAddress)
2160 OIC_LOG(ERROR, TAG, "wrong device address");
2163 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2166 OIC_LOG(ERROR, TAG, "setAddress is null");
2170 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2173 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2174 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2178 if (!strcmp(setAddress, remoteAddress))
2180 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2182 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2183 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2184 (*env)->DeleteGlobalRef(env, jarrayObj);
2186 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2188 OIC_LOG(ERROR, TAG, "List removal failed.");
2189 ca_mutex_unlock(g_connectedDeviceListMutex);
2190 return CA_STATUS_FAILED;
2192 ca_mutex_unlock(g_connectedDeviceListMutex);
2193 return CA_STATUS_OK;
2195 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2196 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2200 ca_mutex_unlock(g_connectedDeviceListMutex);
2202 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2204 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2205 return CA_STATUS_FAILED;
2208 JNIEXPORT void JNICALL
2209 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2212 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2213 VERIFY_NON_NULL_VOID(env, TAG, "env");
2214 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2215 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2217 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2220 JNIEXPORT void JNICALL
2221 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2225 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2226 VERIFY_NON_NULL_VOID(env, TAG, "env");
2227 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2228 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2230 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2233 JNIEXPORT void JNICALL
2234 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2235 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2237 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2238 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2240 VERIFY_NON_NULL_VOID(env, TAG, "env");
2241 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2242 VERIFY_NON_NULL_VOID(device, TAG, "device");
2245 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
2247 // STATE_DISCONNECTED
2248 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
2250 if (newState == state_connected)
2253 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2255 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2256 if (!jni_remoteAddress)
2258 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2262 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2265 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2269 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2271 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2272 CALEServerAddDeviceToList(env, device);
2274 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2276 else if (newState == state_disconnected)
2278 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2280 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2281 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2282 if (CA_STATUS_OK != ret)
2284 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2288 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2289 if (CA_STATUS_OK != ret)
2291 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2296 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2301 JNIEXPORT void JNICALL
2302 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2305 jobject gattService)
2307 VERIFY_NON_NULL_VOID(env, TAG, "env");
2308 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2309 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2311 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2314 JNIEXPORT void JNICALL
2315 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2316 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2318 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2319 VERIFY_NON_NULL_VOID(env, TAG, "env");
2320 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2321 VERIFY_NON_NULL_VOID(device, TAG, "device");
2322 VERIFY_NON_NULL_VOID(data, TAG, "data");
2325 JNIEXPORT void JNICALL
2326 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2327 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2329 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2330 VERIFY_NON_NULL_VOID(env, TAG, "env");
2331 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2332 VERIFY_NON_NULL_VOID(device, TAG, "device");
2333 VERIFY_NON_NULL_VOID(data, TAG, "data");
2335 // get Byte Array and covert to uint8_t*
2336 jint length = (*env)->GetArrayLength(env, data);
2339 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2341 uint8_t* requestData = NULL;
2342 requestData = OICMalloc(length);
2345 OIC_LOG(ERROR, TAG, "requestData is null");
2349 memcpy(requestData, jni_byte_requestData, length);
2350 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2352 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2355 OIC_LOG(ERROR, TAG, "jni_address is null");
2356 OICFree(requestData);
2360 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2363 OIC_LOG(ERROR, TAG, "address is null");
2364 OICFree(requestData);
2368 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2370 ca_mutex_lock(g_bleClientBDAddressMutex);
2371 uint32_t sentLength = 0;
2372 g_CABLEServerDataReceivedCallback(address, requestData, length,
2374 ca_mutex_unlock(g_bleClientBDAddressMutex);
2376 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2379 JNIEXPORT void JNICALL
2380 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2385 VERIFY_NON_NULL_VOID(env, TAG, "env");
2386 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2387 VERIFY_NON_NULL_VOID(device, TAG, "device");
2389 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2392 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2393 if (gatt_success != status) // error case
2395 OIC_LOG(ERROR, TAG, "it will be sent again.");
2397 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2398 if (CA_STATUS_OK != res)
2400 OIC_LOG(ERROR, TAG, "send has failed");
2402 if (g_obj_bluetoothDevice)
2404 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2405 g_obj_bluetoothDevice = NULL;
2408 ca_mutex_lock(g_threadSendNotifyMutex);
2409 g_isSignalSetFlag = true;
2410 ca_cond_signal(g_threadSendNotifyCond);
2411 ca_mutex_unlock(g_threadSendNotifyMutex);
2417 OIC_LOG(DEBUG, TAG, "notify success");
2419 if (g_obj_bluetoothDevice)
2421 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2422 g_obj_bluetoothDevice = NULL;
2425 // next data can be sent
2426 ca_mutex_lock(g_threadSendNotifyMutex);
2427 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2428 g_isSignalSetFlag = true;
2429 ca_cond_signal(g_threadSendNotifyCond);
2430 ca_mutex_unlock(g_threadSendNotifyMutex);
2435 JNIEXPORT void JNICALL
2436 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2438 jobject settingsInEffect)
2440 VERIFY_NON_NULL_VOID(env, TAG, "env");
2441 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2442 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2444 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2447 JNIEXPORT void JNICALL
2448 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2452 VERIFY_NON_NULL_VOID(env, TAG, "env");
2453 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2455 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2462 CAResult_t CAStartLEGattServer()
2464 // start gatt service
2465 CALEServerStartMulticastServer();
2467 return CA_STATUS_OK;
2470 CAResult_t CAStopLEGattServer()
2472 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2476 OIC_LOG(ERROR, TAG, "g_jvm is null");
2477 return CA_STATUS_FAILED;
2480 bool isAttached = false;
2482 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2485 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2486 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2490 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2491 return CA_STATUS_FAILED;
2496 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2497 if (CA_STATUS_OK != ret)
2499 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2500 return CA_STATUS_FAILED;
2503 ret = CALEServerStopMulticastServer();
2504 if (CA_STATUS_OK != ret)
2506 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2507 return CA_STATUS_FAILED;
2510 ret = CALEServerDisconnectAllDevices(env);
2511 if (CA_STATUS_OK != ret)
2513 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2514 return CA_STATUS_FAILED;
2517 ret = CALEServerRemoveAllDevices(env);
2518 if (CA_STATUS_OK != ret)
2520 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2521 return CA_STATUS_FAILED;
2524 if (g_leAdvertiseCallback)
2526 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2529 if (g_bluetoothGattServer)
2531 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2534 if (g_bluetoothGattServerCallback)
2536 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2539 if (g_obj_bluetoothDevice)
2541 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2542 g_obj_bluetoothDevice = NULL;
2545 ca_mutex_lock(g_threadSendNotifyMutex);
2546 ca_cond_signal(g_threadSendNotifyCond);
2547 ca_mutex_unlock(g_threadSendNotifyMutex);
2549 g_isStartServer = false;
2553 (*g_jvm)->DetachCurrentThread(g_jvm);
2556 return CA_STATUS_OK;
2559 CAResult_t CAInitializeLEGattServer()
2561 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2562 return CALEServerInitialize();
2565 void CATerminateLEGattServer()
2567 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2568 CALEServerTerminate();
2571 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2573 ca_mutex_lock(g_bleReqRespCbMutex);
2574 g_CABLEServerDataReceivedCallback = callback;
2575 ca_mutex_unlock(g_bleReqRespCbMutex);
2578 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2580 g_serverErrorCallback = callback;
2583 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2584 const uint8_t *charValue,
2585 uint32_t charValueLen)
2587 CAResult_t result = CA_SEND_FAILED;
2588 VERIFY_NON_NULL(address, TAG, "env is null");
2589 VERIFY_NON_NULL(charValue, TAG, "device is null");
2593 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2599 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2600 uint32_t charValueLen)
2602 VERIFY_NON_NULL(charValue, TAG, "device is null");
2604 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2609 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2611 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2615 CAResult_t CALEServerInitMutexVaraibles()
2617 if (NULL == g_bleReqRespCbMutex)
2619 g_bleReqRespCbMutex = ca_mutex_new();
2620 if (NULL == g_bleReqRespCbMutex)
2622 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2623 return CA_STATUS_FAILED;
2627 if (NULL == g_bleClientBDAddressMutex)
2629 g_bleClientBDAddressMutex = ca_mutex_new();
2630 if (NULL == g_bleClientBDAddressMutex)
2632 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2633 return CA_STATUS_FAILED;
2637 if (NULL == g_connectedDeviceListMutex)
2639 g_connectedDeviceListMutex = ca_mutex_new();
2640 if (NULL == g_connectedDeviceListMutex)
2642 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2643 return CA_STATUS_FAILED;
2647 if (NULL == g_threadSendMutex)
2649 g_threadSendMutex = ca_mutex_new();
2650 if (NULL == g_threadSendMutex)
2652 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2653 return CA_STATUS_FAILED;
2657 if (NULL == g_threadSendNotifyMutex)
2659 g_threadSendNotifyMutex = ca_mutex_new();
2660 if (NULL == g_threadSendNotifyMutex)
2662 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2663 return CA_STATUS_FAILED;
2667 return CA_STATUS_OK;
2670 void CALEServerTerminateMutexVaraibles()
2672 ca_mutex_free(g_bleReqRespCbMutex);
2673 g_bleReqRespCbMutex = NULL;
2675 ca_mutex_free(g_bleClientBDAddressMutex);
2676 g_bleClientBDAddressMutex = NULL;
2678 ca_mutex_free(g_connectedDeviceListMutex);
2679 g_connectedDeviceListMutex = NULL;
2681 ca_mutex_free(g_threadSendMutex);
2682 g_threadSendMutex = NULL;
2684 ca_mutex_free(g_threadSendNotifyMutex);
2685 g_threadSendNotifyMutex = NULL;
2688 void CALEServerTerminateConditionVaraibles()
2690 OIC_LOG(DEBUG, TAG, "this method is not supported");