1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
24 #include <android/log.h>
26 #include "caleserver.h"
27 #include "caleutils.h"
28 #include "caleinterface.h"
29 #include "caadapterutils.h"
32 #include "oic_malloc.h"
33 #include "cathreadpool.h"
35 #include "uarraylist.h"
36 #include "org_iotivity_ca_CaLeServerInterface.h"
38 #define TAG PCF("OIC_CA_LE_SERVER")
40 #define WAIT_TIME_WRITE_CHARACTERISTIC 10000000
42 static JavaVM *g_jvm = NULL;
43 static jobject g_context = NULL;
44 static jobject g_bluetoothGattServer = NULL;
45 static jobject g_bluetoothGattServerCallback = NULL;
46 static jobject g_leAdvertiseCallback = NULL;
47 static jobject g_bluetoothManager = NULL;
49 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
50 static CABLEErrorHandleCallback g_serverErrorCallback;
52 static u_arraylist_t *g_connectedDeviceList = NULL;
54 static bool g_isStartServer = false;
55 static bool g_isInitializedServer = false;
57 static jbyteArray g_sendBuffer = NULL;
58 static jobject g_obj_bluetoothDevice = NULL;
60 static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
61 static ca_mutex g_bleReqRespCbMutex = NULL;
62 static ca_mutex g_bleClientBDAddressMutex = NULL;
63 static ca_mutex g_connectedDeviceListMutex = NULL;
65 static ca_mutex g_threadSendMutex = NULL;
66 static ca_mutex g_threadSendNotifyMutex = NULL;
67 static ca_cond g_threadSendNotifyCond = NULL;
68 static bool g_isSignalSetFlag = false;
70 static const char CLASSPATH_BT_ADVERTISE_CB[] = "android/bluetooth/le/AdvertiseCallback";
72 void CALEServerJNISetContext()
74 OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
75 g_context = (jobject) CANativeJNIGetContext();
78 void CALeServerJniInit()
80 OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
81 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
84 CAResult_t CALEServerCreateJniInterfaceObject()
86 OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
90 OIC_LOG(ERROR, TAG, "g_context is null");
91 return CA_STATUS_FAILED;
96 OIC_LOG(ERROR, TAG, "g_jvm is null");
97 return CA_STATUS_FAILED;
100 bool isAttached = false;
102 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
105 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
106 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
110 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
111 return CA_STATUS_FAILED;
116 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
117 if (!jni_LEInterface)
119 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
123 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
125 if (!LeInterfaceConstructorMethod)
127 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
131 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
132 OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
136 (*g_jvm)->DetachCurrentThread(g_jvm);
145 (*g_jvm)->DetachCurrentThread(g_jvm);
148 return CA_STATUS_FAILED;
152 * get the current connection state of the gatt profile to the remote device.
153 * @param[in] env JNI interface pointer.
154 * @param[in] device bluetooth device object
155 * @return state of the profile connection.
157 static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
159 OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
161 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
162 VERIFY_NON_NULL_RET(device, TAG, "device", -1);
164 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
165 if (!jni_cid_bluetoothManager)
167 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
171 jmethodID jni_mid_getConnectionState = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
172 "getConnectionState",
173 "(Landroid/bluetooth/BluetoothDevice"
175 if (!jni_mid_getConnectionState)
177 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
181 if (!g_bluetoothManager)
183 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
187 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
188 jni_mid_getConnectionState,
189 device, GATT_PROFILE);
190 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
194 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
196 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
197 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
198 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
200 if (!g_bluetoothGattServer)
202 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
206 if (!CALEIsEnableBTAdapter(env))
208 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
212 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
214 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
215 "android/bluetooth/BluetoothGattServer");
216 if (!jni_cid_bluetoothGattServer)
218 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
222 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
223 "BluetoothGattService");
224 if (!jni_cid_bluetoothGattService)
226 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
230 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
231 "BluetoothGattCharacteristic");
232 if (!jni_cid_bluetoothGattCharacteristic)
234 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
238 jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
240 "(Ljava/util/UUID;)Landroid/bluetooth/"
241 "BluetoothGattService;");
242 if (!jni_mid_getService)
244 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
248 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
249 if (!jni_obj_serviceUUID)
251 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
255 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
257 jni_obj_serviceUUID);
258 if (!jni_obj_bluetoothGattService)
260 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
264 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
267 "Landroid/bluetooth/"
268 "BluetoothGattCharacteristic;");
269 if (!jni_mid_getCharacteristic)
271 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
275 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
276 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
277 if (!jni_obj_responseUUID)
279 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
283 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
284 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
285 if (!jni_obj_bluetoothGattCharacteristic)
287 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
291 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
292 "setValue", "([B)Z");
293 if (!jni_mid_setValue)
295 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
299 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
300 jni_obj_bluetoothGattCharacteristic,
301 jni_mid_setValue, responseData);
302 if (JNI_FALSE == jni_boolean_setValue)
304 OIC_LOG(ERROR, TAG, "Fail to set response data");
307 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
308 return jni_obj_bluetoothGattCharacteristic;
311 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
313 OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
314 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
315 VERIFY_NON_NULL(device, TAG, "device is null");
316 VERIFY_NON_NULL(env, TAG, "env is null");
318 if (!CALEIsEnableBTAdapter(env))
320 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
321 return CA_ADAPTER_NOT_ENABLED;
324 if (STATE_CONNECTED != CALEServerGetConnectionState(env, device))
326 OIC_LOG(ERROR, TAG, "it is not connected state");
327 return CA_STATUS_FAILED;
330 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
331 "android/bluetooth/BluetoothGattServer");
332 if (!jni_cid_bluetoothGattServer)
334 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
335 return CA_STATUS_FAILED;
338 jmethodID jni_mid_notifyCharacteristicChanged = (*env)->GetMethodID(
339 env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
340 "(Landroid/bluetooth/BluetoothDevice;"
341 "Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
342 if (!jni_mid_notifyCharacteristicChanged)
344 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
345 return CA_STATUS_FAILED;
348 OIC_LOG(DEBUG, TAG, "CALL API - notifyCharacteristicChanged");
350 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
351 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
353 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
355 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
356 return CA_SEND_FAILED;
359 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
360 ca_mutex_lock(g_threadSendNotifyMutex);
361 if (!g_isSignalSetFlag)
363 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
364 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
365 WAIT_TIME_WRITE_CHARACTERISTIC))
367 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
368 ca_mutex_unlock(g_threadSendNotifyMutex);
369 return CA_STATUS_FAILED;
372 // reset flag set by writeCharacteristic Callback
373 g_isSignalSetFlag = false;
374 ca_mutex_unlock(g_threadSendNotifyMutex);
375 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
379 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
380 jint offset, jbyteArray value)
382 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
383 VERIFY_NON_NULL(env, TAG, "env is null");
384 VERIFY_NON_NULL(device, TAG, "device is null");
385 VERIFY_NON_NULL(value, TAG, "value is null");
387 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
389 if (!CALEIsEnableBTAdapter(env))
391 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
392 return CA_ADAPTER_NOT_ENABLED;
395 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
396 "android/bluetooth/BluetoothGattServer");
397 if (!jni_cid_bluetoothGattServer)
399 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
400 return CA_STATUS_FAILED;
403 jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
405 "(Landroid/bluetooth/BluetoothDevice;"
407 if (!jni_mid_sendResponse)
409 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
410 return CA_STATUS_FAILED;
413 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
414 jni_mid_sendResponse, device,
415 requestId, status, offset,
417 if (JNI_FALSE == jni_boolean_sendResponse)
419 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
420 return CA_SEND_FAILED;
423 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
427 CAResult_t CALEStartAdvertise()
431 OIC_LOG(ERROR, TAG, "g_jvm is null");
432 return CA_STATUS_FAILED;
435 bool isAttached = false;
437 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
440 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
441 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
445 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
446 return CA_STATUS_FAILED;
452 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
453 if (CA_STATUS_OK != ret)
455 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
460 (*g_jvm)->DetachCurrentThread(g_jvm);
465 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
467 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
468 VERIFY_NON_NULL(env, TAG, "env is null");
469 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
471 if (!CALEIsEnableBTAdapter(env))
473 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
474 return CA_ADAPTER_NOT_ENABLED;
477 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
478 "android/bluetooth/le/"
479 "AdvertiseSettings$Builder");
480 if (!jni_cid_AdvertiseSettings)
482 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
483 return CA_STATUS_FAILED;
486 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
488 if (!jni_mid_AdvertiseSettings)
490 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
491 return CA_STATUS_FAILED;
494 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
495 jni_mid_AdvertiseSettings);
496 if (!jni_AdvertiseSettings)
498 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
499 return CA_STATUS_FAILED;
502 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
504 "(I)Landroid/bluetooth/le/"
505 "AdvertiseSettings$Builder;");
506 if (!jni_mid_setAdvertiseMode)
508 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
509 return CA_STATUS_FAILED;
512 // 0: Low power, 1: Balanced
513 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
514 jni_mid_setAdvertiseMode, 0);
515 if (!jni_obj_setAdvertiseMode)
517 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
518 return CA_STATUS_FAILED;
521 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
523 "(Z)Landroid/bluetooth/le/"
524 "AdvertiseSettings$Builder;");
525 if (!jni_mid_setConnectable)
527 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
528 return CA_STATUS_FAILED;
531 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
532 jni_mid_setConnectable, JNI_TRUE);
533 if (!jni_obj_setConnectable)
535 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
536 return CA_STATUS_FAILED;
539 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
540 "(I)Landroid/bluetooth/le/"
541 "AdvertiseSettings$Builder;");
542 if (!jni_mid_setTimeout)
544 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
545 return CA_STATUS_FAILED;
548 //A value of 0 will disable the time limit
549 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
550 jni_mid_setTimeout, 0);
551 if (!jni_obj_setTimeout)
553 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
554 return CA_STATUS_FAILED;
557 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
558 "android/bluetooth/le/"
559 "AdvertiseData$Builder");
560 if (!jni_cid_AdvertiseDataBuilder)
562 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
563 return CA_STATUS_FAILED;
566 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
568 if (!jni_mid_AdvertiseDataBuilder)
570 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
571 return CA_STATUS_FAILED;
574 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
575 jni_mid_AdvertiseDataBuilder);
576 if (!jni_AdvertiseDataBuilder)
578 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
579 return CA_STATUS_FAILED;
582 jobject jni_AdvertiseDataBuilderForScanRsp = (*env)->NewObject(env,
583 jni_cid_AdvertiseDataBuilder,
584 jni_mid_AdvertiseDataBuilder);
585 if (!jni_AdvertiseDataBuilderForScanRsp)
587 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilderForScanRsp is null");
588 return CA_STATUS_FAILED;
591 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
592 if (!jni_obj_serviceUUID)
594 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
595 return CA_STATUS_FAILED;
598 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
601 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
602 return CA_STATUS_FAILED;
605 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
607 "(Landroid/os/ParcelUuid;)Landroid/"
608 "bluetooth/le/AdvertiseData$Builder;");
609 if (!jni_mid_addServiceUuid)
611 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
612 return CA_STATUS_FAILED;
615 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
616 jni_mid_addServiceUuid,
618 if (!jni_obj_addServiceUuid)
620 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
621 return CA_STATUS_FAILED;
624 // Device name has to be included in advertise packet after Android API 23
625 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
626 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
627 "setIncludeDeviceName",
630 "AdvertiseData$Builder;");
631 if (!jni_mid_setIncludeDeviceName)
633 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
634 return CA_STATUS_FAILED;
637 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env,
638 jni_AdvertiseDataBuilderForScanRsp,
639 jni_mid_setIncludeDeviceName,
641 if (!jni_obj_setIncludeDeviceName)
643 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
644 return CA_STATUS_FAILED;
647 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
648 if (!jni_cid_BTAdapter)
650 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
651 return CA_STATUS_FAILED;
654 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
656 "()Landroid/bluetooth/"
657 "BluetoothAdapter;");
658 if (!jni_mid_getDefaultAdapter)
660 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
661 return CA_STATUS_FAILED;
664 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
665 jni_mid_getDefaultAdapter);
666 if (!jni_obj_BTAdapter)
668 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
669 return CA_STATUS_FAILED;
672 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
673 "getBluetoothLeAdvertiser",
674 "()Landroid/bluetooth/le/"
675 "BluetoothLeAdvertiser;");
676 if (!jni_mid_getBluetoothLeAdvertiser)
678 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
679 return CA_STATUS_FAILED;
682 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
683 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
684 if (!jni_obj_getBluetoothLeAdvertiser)
686 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
687 return CA_STATUS_FAILED;
690 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
691 jni_cid_AdvertiseSettings,
693 "()Landroid/bluetooth/le/"
694 "AdvertiseSettings;");
695 if (!jni_mid_build_LeAdvertiseSettings)
697 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
698 return CA_STATUS_FAILED;
701 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
702 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
703 if (!jni_obj_build_LeAdvertiseSettings)
705 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
706 return CA_STATUS_FAILED;
709 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
711 "()Landroid/bluetooth/le/"
713 if (!jni_mid_build_LeAdvertiseData)
715 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
716 return CA_STATUS_FAILED;
719 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
720 jni_mid_build_LeAdvertiseData);
721 if (!jni_obj_build_LeAdvertiseData)
723 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
724 return CA_STATUS_FAILED;
727 jobject jni_obj_build_LeAdvertiseDataForScanRsp = (*env)->CallObjectMethod(env,
728 jni_AdvertiseDataBuilderForScanRsp,
729 jni_mid_build_LeAdvertiseData);
730 if (!jni_obj_build_LeAdvertiseDataForScanRsp)
732 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseDataForScanRsp is null");
733 return CA_STATUS_FAILED;
736 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
737 "android/bluetooth/le/BluetoothLeAdvertiser");
738 if (!jni_cid_leAdvertiser)
740 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
741 return CA_STATUS_FAILED;
744 jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
746 "(Landroid/bluetooth/le/"
747 "AdvertiseSettings;Landroid/bluetooth/"
748 "le/AdvertiseData;Landroid/bluetooth/"
749 "le/AdvertiseData;Landroid/bluetooth/"
750 "le/AdvertiseCallback;)V");
751 if (!jni_mid_startAdvertising)
753 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
754 return CA_STATUS_FAILED;
757 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
758 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
759 jni_obj_build_LeAdvertiseDataForScanRsp, advertiseCallback);
761 if ((*env)->ExceptionCheck(env))
763 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
764 (*env)->ExceptionDescribe(env);
765 (*env)->ExceptionClear(env);
766 return CA_STATUS_FAILED;
769 OIC_LOG(DEBUG, TAG, "Advertising started!!");
771 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
775 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
777 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
778 VERIFY_NON_NULL(env, TAG, "env is null");
779 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
781 if (!CALEIsEnableBTAdapter(env))
783 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
784 return CA_ADAPTER_NOT_ENABLED;
787 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
788 if (!jni_cid_BTAdapter)
790 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
791 return CA_STATUS_FAILED;
794 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
795 "android/bluetooth/le/BluetoothLeAdvertiser");
796 if (!jni_cid_leAdvertiser)
798 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
799 return CA_STATUS_FAILED;
802 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
804 "()Landroid/bluetooth/"
805 "BluetoothAdapter;");
806 if (!jni_mid_getDefaultAdapter)
808 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
809 return CA_STATUS_FAILED;
812 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
813 "getBluetoothLeAdvertiser",
814 "()Landroid/bluetooth/le/"
815 "BluetoothLeAdvertiser;");
816 if (!jni_mid_getBTLeAdvertiser)
818 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
819 return CA_STATUS_FAILED;
822 jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
824 "(Landroid/bluetooth/le/"
825 "AdvertiseCallback;)V");
826 if (!jni_mid_stopAdvertising)
828 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
829 return CA_STATUS_FAILED;
832 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
833 jni_mid_getDefaultAdapter);
834 if (!jni_obj_BTAdapter)
836 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
837 return CA_STATUS_FAILED;
840 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
841 jni_mid_getBTLeAdvertiser);
842 if (!jni_obj_getBluetoothLeAdvertiser)
844 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
845 return CA_STATUS_FAILED;
848 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
850 if ((*env)->ExceptionCheck(env))
852 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
853 (*env)->ExceptionDescribe(env);
854 (*env)->ExceptionClear(env);
855 return CA_STATUS_FAILED;
858 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
862 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
864 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
865 VERIFY_NON_NULL(env, TAG, "env is null");
866 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
868 if (!CALEIsEnableBTAdapter(env))
870 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
871 return CA_ADAPTER_NOT_ENABLED;
876 OIC_LOG(DEBUG, TAG, "Gatt server already started");
879 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
882 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
883 if (!bluetoothGattServer)
885 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
886 return CA_STATUS_FAILED;
889 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
890 if (!g_bluetoothGattServer)
892 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
893 return CA_STATUS_FAILED;
896 // create gatt service
897 jobject bluetoothGattService = CALEServerCreateGattService(env);
898 if (!bluetoothGattService)
900 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
901 return CA_STATUS_FAILED;
905 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
906 bluetoothGattService);
907 if (CA_STATUS_OK != res)
909 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
914 jobject CALEServerOpenGattServer(JNIEnv *env)
916 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
917 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
919 if (!CALEIsEnableBTAdapter(env))
921 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
925 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
926 if (!jni_cid_context)
928 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
932 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
933 if (!jni_cid_bluetoothManager)
935 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
939 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
941 "Ljava/lang/String;");
942 if (!jni_fid_bluetoothService)
944 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
948 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
950 "(Ljava/lang/String;)"
951 "Ljava/lang/Object;");
952 if (!jni_mid_getSystemService)
954 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
958 jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
960 "(Landroid/content/Context;"
961 "Landroid/bluetooth/"
962 "BluetoothGattServerCallback;)"
963 "Landroid/bluetooth/"
964 "BluetoothGattServer;");
965 if (!jni_mid_openGattServer)
967 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
971 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
972 jni_fid_bluetoothService);
973 if (!jni_obj_bluetoothService)
975 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
979 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
980 jni_mid_getSystemService,
981 jni_obj_bluetoothService);
982 if (!jni_obj_bluetoothManager)
984 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
988 if (g_bluetoothManager)
990 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
992 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
994 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
995 jni_mid_openGattServer,
997 g_bluetoothGattServerCallback);
998 if (!jni_obj_bluetoothGattServer)
1000 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1004 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
1005 return jni_obj_bluetoothGattServer;
1008 jobject CALEServerCreateGattService(JNIEnv *env)
1010 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
1011 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1013 if (!CALEIsEnableBTAdapter(env))
1015 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1019 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
1020 "BluetoothGattService");
1021 if (!jni_cid_bluetoothGattService)
1023 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
1027 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1028 "BluetoothGattCharacteristic");
1029 if (!jni_cid_bluetoothGattCharacteristic)
1031 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
1035 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
1036 "SERVICE_TYPE_PRIMARY", "I");
1037 if (!jni_fid_serviceType)
1039 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
1043 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
1044 jni_cid_bluetoothGattCharacteristic,
1045 "PROPERTY_NOTIFY", "I");
1046 if (!jni_fid_readProperties)
1048 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1052 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1053 jni_cid_bluetoothGattCharacteristic,
1054 "PROPERTY_WRITE_NO_RESPONSE", "I");
1055 if (!jni_fid_writeProperties)
1057 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1061 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1062 jni_cid_bluetoothGattCharacteristic,
1063 "PERMISSION_READ", "I");
1064 if (!jni_fid_readPermissions)
1066 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1070 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1071 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1072 if (!jni_fid_writePermissions)
1074 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1078 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1079 "<init>", "(Ljava/util/UUID;I)V");
1080 if (!jni_mid_bluetoothGattService)
1082 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1086 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1087 "addCharacteristic",
1088 "(Landroid/bluetooth/"
1089 "BluetoothGattCharacteristic;)Z");
1090 if (!jni_mid_addCharacteristic)
1092 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1096 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1097 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1098 if (!jni_mid_bluetoothGattCharacteristic)
1100 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1104 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1105 if (!jni_obj_serviceUUID)
1107 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1111 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1112 jni_fid_serviceType);
1113 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1114 jni_mid_bluetoothGattService,
1115 jni_obj_serviceUUID, jni_int_serviceType);
1116 if (!jni_bluetoothGattService)
1118 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1122 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1123 if (!jni_obj_readUuid)
1125 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1129 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1130 jni_cid_bluetoothGattCharacteristic,
1131 jni_fid_readProperties);
1133 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1134 jni_cid_bluetoothGattCharacteristic,
1135 jni_fid_readPermissions);
1137 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1138 jni_cid_bluetoothGattCharacteristic,
1139 jni_fid_writePermissions);
1141 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1142 jni_mid_bluetoothGattCharacteristic,
1143 jni_obj_readUuid, jni_int_readProperties,
1144 jni_int_readPermissions|
1145 jni_int_writePermissions);
1146 if (!jni_readCharacteristic)
1148 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1152 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1153 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1154 if (!jni_boolean_addReadCharacteristic)
1156 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1160 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1161 if (!jni_obj_writeUuid)
1163 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1167 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1168 jni_cid_bluetoothGattCharacteristic,
1169 jni_fid_writeProperties);
1171 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1172 jni_mid_bluetoothGattCharacteristic,
1173 jni_obj_writeUuid, jni_int_writeProperties,
1174 jni_int_writePermissions);
1175 if (!jni_writeCharacteristic)
1177 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1181 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1182 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1183 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1185 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1189 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1190 return jni_bluetoothGattService;
1193 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1195 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1196 VERIFY_NON_NULL(env, TAG, "env is null");
1197 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1199 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1200 "BluetoothGattDescriptor");
1201 if (!jni_cid_bluetoothGattDescriptor)
1203 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1204 return CA_STATUS_FAILED;
1207 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1208 jni_cid_bluetoothGattDescriptor,
1210 "(Ljava/util/UUID;I)V");
1211 if (!jni_mid_bluetoothGattDescriptor)
1213 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1214 return CA_STATUS_FAILED;
1217 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1218 jni_cid_bluetoothGattDescriptor,
1219 "PERMISSION_READ", "I");
1220 if (!jni_fid_readPermissions)
1222 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1223 return CA_STATUS_FAILED;
1226 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1227 if (!jni_obj_readUuid)
1229 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1230 return CA_STATUS_FAILED;
1233 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1234 jni_fid_readPermissions);
1236 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1238 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1239 jni_mid_bluetoothGattDescriptor,
1240 jni_obj_readUuid, jni_int_readPermissions);
1241 if (!jni_readDescriptor)
1243 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1244 return CA_STATUS_FAILED;
1247 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1248 "BluetoothGattCharacteristic");
1249 if (!jni_cid_GattCharacteristic)
1251 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1252 return CA_STATUS_FAILED;
1255 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1257 "(Landroid/bluetooth/"
1258 "BluetoothGattDescriptor;)Z");
1259 if (!jni_mid_addDescriptor)
1261 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1262 return CA_STATUS_FAILED;
1265 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1266 jni_mid_addDescriptor,
1267 jni_readDescriptor);
1269 if (JNI_FALSE == jni_boolean_addDescriptor)
1271 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1272 return CA_STATUS_FAILED;
1276 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1278 return CA_STATUS_OK;
1281 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1282 jobject bluetoothGattService)
1284 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1285 VERIFY_NON_NULL(env, TAG, "env is null");
1286 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1287 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1289 if (!CALEIsEnableBTAdapter(env))
1291 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1292 return CA_ADAPTER_NOT_ENABLED;
1295 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1296 "android/bluetooth/BluetoothGattServer");
1297 if (!jni_cid_bluetoothGattServer)
1299 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1300 return CA_STATUS_FAILED;
1303 jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1305 "(Landroid/bluetooth/BluetoothGattService;)"
1307 if (!jni_mid_addService)
1309 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1310 return CA_STATUS_FAILED;
1313 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1315 bluetoothGattService);
1317 if (JNI_FALSE == jni_boolean_addService)
1319 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1320 return CA_STATUS_FAILED;
1323 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1324 return CA_STATUS_OK;
1327 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1329 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1330 VERIFY_NON_NULL(env, TAG, "env is null");
1331 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1333 if (!CALEIsEnableBTAdapter(env))
1335 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1336 return CA_ADAPTER_NOT_ENABLED;
1339 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1340 "android/bluetooth/BluetoothGattServer");
1341 if (!jni_cid_bluetoothGattServer)
1343 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1344 return CA_STATUS_FAILED;
1347 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1348 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1349 if (!jni_mid_connect)
1351 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1352 return CA_STATUS_FAILED;
1355 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1356 jni_mid_connect, bluetoothDevice,
1358 if (JNI_FALSE == jni_boolean_connect)
1360 OIC_LOG(ERROR, TAG, "Fail to connect");
1361 return CA_STATUS_FAILED;
1364 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1365 return CA_STATUS_OK;
1368 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1370 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1371 VERIFY_NON_NULL(env, TAG, "env is null");
1373 ca_mutex_lock(g_connectedDeviceListMutex);
1374 if (!g_connectedDeviceList)
1376 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1377 ca_mutex_unlock(g_connectedDeviceListMutex);
1378 return CA_STATUS_FAILED;
1381 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1382 for (uint32_t index = 0; index < length; index++)
1384 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1387 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1391 // disconnect for device obj
1392 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1393 if (CA_STATUS_OK != res)
1395 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1400 ca_mutex_unlock(g_connectedDeviceListMutex);
1401 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1402 return CA_STATUS_OK;
1405 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1407 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1408 VERIFY_NON_NULL(env, TAG, "env is null");
1409 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1411 if (!CALEIsEnableBTAdapter(env))
1413 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1414 return CA_ADAPTER_NOT_ENABLED;
1417 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1418 "android/bluetooth/BluetoothGattServer");
1419 if (!jni_cid_bluetoothGattServer)
1421 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1422 return CA_STATUS_FAILED;
1425 jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1427 "(Landroid/bluetooth/BluetoothDevice;)"
1429 if (!jni_mid_cancelConnection)
1431 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1432 return CA_STATUS_FAILED;
1435 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1437 if ((*env)->ExceptionCheck(env))
1439 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1440 (*env)->ExceptionDescribe(env);
1441 (*env)->ExceptionClear(env);
1442 return CA_STATUS_FAILED;
1445 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1446 return CA_STATUS_OK;
1449 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1452 OIC_LOG(DEBUG, TAG, "GattServer Close");
1453 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1454 VERIFY_NON_NULL(env, TAG, "env is null");
1456 // get BluetoothGatt class
1457 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1458 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
1459 if (!jni_cid_BluetoothGatt)
1461 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1462 return CA_STATUS_FAILED;
1465 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1466 if (!jni_mid_closeGatt)
1468 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1469 return CA_STATUS_OK;
1472 // call disconnect gatt method
1473 OIC_LOG(DEBUG, TAG, "request to close GATT");
1474 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1476 if ((*env)->ExceptionCheck(env))
1478 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1479 (*env)->ExceptionDescribe(env);
1480 (*env)->ExceptionClear(env);
1481 return CA_STATUS_FAILED;
1484 return CA_STATUS_OK;
1487 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1489 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1490 VERIFY_NON_NULL(env, TAG, "env is null");
1491 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1492 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1494 if (!CALEIsEnableBTAdapter(env))
1496 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1497 return CA_ADAPTER_NOT_ENABLED;
1500 jobject responseChar = CALEServerSetResponseData(env, responseData);
1503 OIC_LOG(ERROR, TAG, "responseChar is null");
1504 return CA_STATUS_FAILED;
1507 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1508 if (CA_STATUS_OK != result)
1510 OIC_LOG(ERROR, TAG, "Fail to send response data");
1514 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1518 CAResult_t CALEServerInitialize()
1520 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1522 CALeServerJniInit();
1526 OIC_LOG(ERROR, TAG, "g_jvm is null");
1527 return CA_STATUS_FAILED;
1530 bool isAttached = false;
1532 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1535 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1536 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1540 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1541 return CA_STATUS_FAILED;
1546 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1547 if (CA_STATUS_OK != ret)
1549 OIC_LOG(ERROR, TAG, "it is not supported");
1553 (*g_jvm)->DetachCurrentThread(g_jvm);
1558 g_threadSendNotifyCond = ca_cond_new();
1560 ret = CALEServerInitMutexVaraibles();
1561 if (CA_STATUS_OK != ret)
1563 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1567 (*g_jvm)->DetachCurrentThread(g_jvm);
1569 return CA_STATUS_FAILED;
1572 CALEServerJNISetContext();
1573 CALEServerCreateCachedDeviceList();
1575 ret = CALEServerCreateJniInterfaceObject();
1576 if (CA_STATUS_OK != ret)
1578 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1582 (*g_jvm)->DetachCurrentThread(g_jvm);
1584 return CA_STATUS_FAILED;
1589 (*g_jvm)->DetachCurrentThread(g_jvm);
1592 g_isInitializedServer = true;
1593 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1594 return CA_STATUS_OK;
1597 void CALEServerTerminate()
1599 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1603 OIC_LOG(ERROR, TAG, "g_jvm is null");
1607 bool isAttached = false;
1609 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1612 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1613 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1617 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1625 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1626 g_sendBuffer = NULL;
1629 if (g_bluetoothManager)
1631 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1632 g_bluetoothManager = NULL;
1635 ca_cond_free(g_threadSendNotifyCond);
1636 g_threadSendNotifyCond = NULL;
1638 CALEServerTerminateMutexVaraibles();
1639 CALEServerTerminateConditionVaraibles();
1641 g_isInitializedServer = false;
1645 (*g_jvm)->DetachCurrentThread(g_jvm);
1648 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1651 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1653 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1654 VERIFY_NON_NULL(address, TAG, "address is null");
1655 VERIFY_NON_NULL(data, TAG, "data is null");
1659 OIC_LOG(ERROR, TAG, "g_jvm is null");
1660 return CA_STATUS_FAILED;
1663 bool isAttached = false;
1665 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1668 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1669 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1673 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1674 return CA_STATUS_FAILED;
1679 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1680 if (CA_STATUS_OK != ret)
1682 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1687 (*g_jvm)->DetachCurrentThread(g_jvm);
1693 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1695 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1696 VERIFY_NON_NULL(data, TAG, "data is null");
1700 OIC_LOG(ERROR, TAG, "g_jvm is null");
1701 return CA_STATUS_FAILED;
1704 bool isAttached = false;
1706 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1709 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1710 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1714 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1715 return CA_STATUS_FAILED;
1720 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1721 if (CA_STATUS_OK != ret)
1723 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1728 (*g_jvm)->DetachCurrentThread(g_jvm);
1734 CAResult_t CALEServerStartMulticastServer()
1736 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1738 if (!g_isInitializedServer)
1740 OIC_LOG(INFO, TAG, "server is not initialized");
1741 return CA_STATUS_FAILED;
1744 if (g_isStartServer)
1746 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1747 return CA_STATUS_FAILED;
1752 OIC_LOG(ERROR, TAG, "g_jvm is null");
1753 return CA_STATUS_FAILED;
1756 bool isAttached = false;
1758 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1761 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1762 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1766 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1767 return CA_STATUS_FAILED;
1772 g_isStartServer = true;
1774 // start gatt server
1775 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1776 if (CA_STATUS_OK != ret)
1778 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1783 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1784 if (CA_STATUS_OK != ret)
1786 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1791 (*g_jvm)->DetachCurrentThread(g_jvm);
1794 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1798 CAResult_t CALEServerStopMulticastServer()
1800 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1802 if (false == g_isStartServer)
1804 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1805 return CA_STATUS_FAILED;
1810 OIC_LOG(ERROR, TAG, "g_jvm is null");
1811 return CA_STATUS_FAILED;
1814 bool isAttached = false;
1816 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1819 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1820 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1824 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1825 return CA_STATUS_FAILED;
1830 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1831 if (CA_STATUS_OK != ret)
1833 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1836 g_isStartServer = false;
1840 (*g_jvm)->DetachCurrentThread(g_jvm);
1843 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1847 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1849 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1850 g_packetReceiveCallback = callback;
1853 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1856 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1858 VERIFY_NON_NULL(env, TAG, "env is null");
1859 VERIFY_NON_NULL(address, TAG, "address is null");
1860 VERIFY_NON_NULL(data, TAG, "data is null");
1862 if (!g_connectedDeviceList)
1864 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1865 return CA_STATUS_FAILED;
1868 ca_mutex_lock(g_threadSendMutex);
1870 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1871 for (uint32_t index = 0; index < length; index++)
1873 OIC_LOG(DEBUG, TAG, "check device address");
1874 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1877 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1881 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1882 if (!jni_setAddress)
1884 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1887 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1890 OIC_LOG(ERROR, TAG, "setAddress is null");
1894 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1895 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1897 if (!strcmp(setAddress, address))
1899 OIC_LOG(DEBUG, TAG, "found the device");
1901 if (g_obj_bluetoothDevice)
1903 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1904 g_obj_bluetoothDevice = NULL;
1909 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1911 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1914 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1917 if (g_obj_bluetoothDevice)
1919 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1920 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1921 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1923 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1924 if (CA_STATUS_OK != res)
1926 OIC_LOG(ERROR, TAG, "send has failed");
1932 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1938 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1939 g_sendBuffer = NULL;
1942 ca_mutex_unlock(g_threadSendMutex);
1943 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1944 return CA_STATUS_OK;
1949 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1950 g_sendBuffer = NULL;
1953 if (g_obj_bluetoothDevice)
1955 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1956 g_obj_bluetoothDevice = NULL;
1959 ca_mutex_unlock(g_threadSendMutex);
1960 return CA_SEND_FAILED;
1963 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1965 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1966 VERIFY_NON_NULL(env, TAG, "env is null");
1967 VERIFY_NON_NULL(data, TAG, "data is null");
1969 if (!g_connectedDeviceList)
1971 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1972 return CA_STATUS_FAILED;
1975 ca_mutex_lock(g_threadSendMutex);
1977 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1980 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1981 g_sendBuffer = NULL;
1983 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1984 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1985 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1987 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1988 for (uint32_t index = 0; index < length; index++)
1990 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1993 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1997 // send data for all device
1998 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1999 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
2001 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
2004 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
2008 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2011 OIC_LOG(ERROR, TAG, "address is not available");
2015 if (g_obj_bluetoothDevice)
2017 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2018 g_obj_bluetoothDevice = NULL;
2023 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
2026 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
2027 if (CA_STATUS_OK != res)
2029 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
2030 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2031 if (g_obj_bluetoothDevice)
2033 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2034 g_obj_bluetoothDevice = NULL;
2039 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
2040 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2045 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2046 g_sendBuffer = NULL;
2049 ca_mutex_unlock(g_threadSendMutex);
2050 return CA_STATUS_OK;
2053 void CALEServerCreateCachedDeviceList()
2055 ca_mutex_lock(g_connectedDeviceListMutex);
2056 // create new object array
2057 if (!g_connectedDeviceList)
2059 OIC_LOG(DEBUG, TAG, "Create device list");
2060 g_connectedDeviceList = u_arraylist_create();
2062 ca_mutex_unlock(g_connectedDeviceListMutex);
2065 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
2067 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
2068 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2070 if (!g_connectedDeviceList)
2072 OIC_LOG(ERROR, TAG, "list is null");
2076 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2077 for (uint32_t index = 0; index < length; index++)
2079 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2083 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2087 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2088 if (!jni_setAddress)
2090 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2094 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2097 OIC_LOG(ERROR, TAG, "setAddress is null");
2101 if (!strcmp(remoteAddress, setAddress))
2103 OIC_LOG(ERROR, TAG, "the device is already set");
2104 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2109 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2114 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2118 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2120 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2121 VERIFY_NON_NULL(device, TAG, "device is null");
2122 VERIFY_NON_NULL(env, TAG, "env is null");
2124 ca_mutex_lock(g_connectedDeviceListMutex);
2126 if (!g_connectedDeviceList)
2128 OIC_LOG(ERROR, TAG, "list is null");
2129 ca_mutex_unlock(g_connectedDeviceListMutex);
2130 return CA_STATUS_FAILED;
2133 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2134 if (!jni_remoteAddress)
2136 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2137 ca_mutex_unlock(g_connectedDeviceListMutex);
2138 return CA_STATUS_FAILED;
2141 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2144 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2145 ca_mutex_unlock(g_connectedDeviceListMutex);
2146 return CA_STATUS_FAILED;
2149 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2151 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2152 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2153 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2156 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2157 ca_mutex_unlock(g_connectedDeviceListMutex);
2158 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2159 return CA_STATUS_OK;
2162 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2164 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2165 VERIFY_NON_NULL(env, TAG, "env is null");
2167 ca_mutex_lock(g_connectedDeviceListMutex);
2168 if (!g_connectedDeviceList)
2170 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2171 ca_mutex_unlock(g_connectedDeviceListMutex);
2172 return CA_STATUS_FAILED;
2175 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2176 for (uint32_t index = 0; index < length; index++)
2178 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2181 (*env)->DeleteGlobalRef(env, jarrayObj);
2185 OICFree(g_connectedDeviceList);
2186 g_connectedDeviceList = NULL;
2187 ca_mutex_unlock(g_connectedDeviceListMutex);
2189 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2190 return CA_STATUS_OK;
2193 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2195 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2196 VERIFY_NON_NULL(env, TAG, "env is null");
2197 VERIFY_NON_NULL(address, TAG, "address is null");
2199 ca_mutex_lock(g_connectedDeviceListMutex);
2200 if (!g_connectedDeviceList)
2202 OIC_LOG(ERROR, TAG, "no deviceList");
2203 ca_mutex_unlock(g_connectedDeviceListMutex);
2204 return CA_STATUS_FAILED;
2207 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2208 for (uint32_t index = 0; index < length; index++)
2210 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2214 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2215 if (!jni_setAddress)
2217 OIC_LOG(ERROR, TAG, "wrong device address");
2220 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2223 OIC_LOG(ERROR, TAG, "setAddress is null");
2227 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2230 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2231 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2235 if (!strcmp(setAddress, remoteAddress))
2237 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2239 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2240 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2241 (*env)->DeleteGlobalRef(env, jarrayObj);
2244 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2246 OIC_LOG(ERROR, TAG, "List removal failed.");
2247 ca_mutex_unlock(g_connectedDeviceListMutex);
2248 return CA_STATUS_FAILED;
2250 ca_mutex_unlock(g_connectedDeviceListMutex);
2251 return CA_STATUS_OK;
2253 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2254 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2258 ca_mutex_unlock(g_connectedDeviceListMutex);
2260 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2262 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2263 return CA_STATUS_FAILED;
2266 JNIEXPORT void JNICALL
2267 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2270 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2271 VERIFY_NON_NULL_VOID(env, TAG, "env");
2272 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2273 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2275 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2278 JNIEXPORT void JNICALL
2279 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2283 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2284 VERIFY_NON_NULL_VOID(env, TAG, "env");
2285 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2286 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2288 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2291 JNIEXPORT void JNICALL
2292 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2293 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2295 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2296 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2298 VERIFY_NON_NULL_VOID(env, TAG, "env");
2299 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2300 VERIFY_NON_NULL_VOID(device, TAG, "device");
2303 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
2305 // STATE_DISCONNECTED
2306 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
2308 if (newState == state_connected)
2311 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2313 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2314 if (!jni_remoteAddress)
2316 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2320 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2323 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2327 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2329 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2330 CALEServerAddDeviceToList(env, device);
2332 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2334 else if (newState == state_disconnected)
2336 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2338 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2339 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2340 if (CA_STATUS_OK != ret)
2342 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2346 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2347 if (CA_STATUS_OK != ret)
2349 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2354 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2359 JNIEXPORT void JNICALL
2360 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2363 jobject gattService)
2365 VERIFY_NON_NULL_VOID(env, TAG, "env");
2366 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2367 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2369 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2372 JNIEXPORT void JNICALL
2373 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2374 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2376 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2377 VERIFY_NON_NULL_VOID(env, TAG, "env");
2378 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2379 VERIFY_NON_NULL_VOID(device, TAG, "device");
2380 VERIFY_NON_NULL_VOID(data, TAG, "data");
2383 JNIEXPORT void JNICALL
2384 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2385 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2387 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2388 VERIFY_NON_NULL_VOID(env, TAG, "env");
2389 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2390 VERIFY_NON_NULL_VOID(device, TAG, "device");
2391 VERIFY_NON_NULL_VOID(data, TAG, "data");
2393 // get Byte Array and covert to uint8_t*
2394 jint length = (*env)->GetArrayLength(env, data);
2397 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2399 uint8_t* requestData = NULL;
2400 requestData = OICMalloc(length);
2403 OIC_LOG(ERROR, TAG, "requestData is null");
2407 memcpy(requestData, jni_byte_requestData, length);
2408 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2410 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2413 OIC_LOG(ERROR, TAG, "jni_address is null");
2414 OICFree(requestData);
2418 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2421 OIC_LOG(ERROR, TAG, "address is null");
2422 OICFree(requestData);
2426 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2428 ca_mutex_lock(g_bleClientBDAddressMutex);
2429 uint32_t sentLength = 0;
2430 g_CABLEServerDataReceivedCallback(address, requestData, length,
2432 ca_mutex_unlock(g_bleClientBDAddressMutex);
2434 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2437 JNIEXPORT void JNICALL
2438 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2443 VERIFY_NON_NULL_VOID(env, TAG, "env");
2444 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2445 VERIFY_NON_NULL_VOID(device, TAG, "device");
2447 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2450 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2451 if (gatt_success != status) // error case
2453 OIC_LOG(ERROR, TAG, "it will be sent again.");
2455 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2456 if (CA_STATUS_OK != res)
2458 OIC_LOG(ERROR, TAG, "send has failed");
2460 if (g_obj_bluetoothDevice)
2462 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2463 g_obj_bluetoothDevice = NULL;
2466 ca_mutex_lock(g_threadSendNotifyMutex);
2467 g_isSignalSetFlag = true;
2468 ca_cond_signal(g_threadSendNotifyCond);
2469 ca_mutex_unlock(g_threadSendNotifyMutex);
2475 OIC_LOG(DEBUG, TAG, "notify success");
2477 if (g_obj_bluetoothDevice)
2479 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2480 g_obj_bluetoothDevice = NULL;
2483 // next data can be sent
2484 ca_mutex_lock(g_threadSendNotifyMutex);
2485 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2486 g_isSignalSetFlag = true;
2487 ca_cond_signal(g_threadSendNotifyCond);
2488 ca_mutex_unlock(g_threadSendNotifyMutex);
2493 JNIEXPORT void JNICALL
2494 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2496 jobject settingsInEffect)
2498 VERIFY_NON_NULL_VOID(env, TAG, "env");
2499 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2500 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2502 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2505 JNIEXPORT void JNICALL
2506 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2510 VERIFY_NON_NULL_VOID(env, TAG, "env");
2511 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2513 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2515 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2516 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2517 if (data_too_large == errorCode)
2519 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2527 CAResult_t CAStartLEGattServer()
2529 // start gatt service
2530 CALEServerStartMulticastServer();
2532 return CA_STATUS_OK;
2535 CAResult_t CAStopLEGattServer()
2537 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2541 OIC_LOG(ERROR, TAG, "g_jvm is null");
2542 return CA_STATUS_FAILED;
2545 bool isAttached = false;
2547 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2550 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2551 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2555 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2556 return CA_STATUS_FAILED;
2561 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2562 if (CA_STATUS_OK != ret)
2564 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2565 return CA_STATUS_FAILED;
2568 ret = CALEServerStopMulticastServer();
2569 if (CA_STATUS_OK != ret)
2571 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2572 return CA_STATUS_FAILED;
2575 ret = CALEServerDisconnectAllDevices(env);
2576 if (CA_STATUS_OK != ret)
2578 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2579 return CA_STATUS_FAILED;
2582 ret = CALEServerRemoveAllDevices(env);
2583 if (CA_STATUS_OK != ret)
2585 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2586 return CA_STATUS_FAILED;
2589 if (g_leAdvertiseCallback)
2591 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2594 if (g_bluetoothGattServer)
2596 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2599 if (g_bluetoothGattServerCallback)
2601 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2604 if (g_obj_bluetoothDevice)
2606 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2607 g_obj_bluetoothDevice = NULL;
2610 ca_mutex_lock(g_threadSendNotifyMutex);
2611 ca_cond_signal(g_threadSendNotifyCond);
2612 ca_mutex_unlock(g_threadSendNotifyMutex);
2614 g_isStartServer = false;
2618 (*g_jvm)->DetachCurrentThread(g_jvm);
2621 return CA_STATUS_OK;
2624 CAResult_t CAInitializeLEGattServer()
2626 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2627 return CALEServerInitialize();
2630 void CATerminateLEGattServer()
2632 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2633 CALEServerTerminate();
2636 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2638 ca_mutex_lock(g_bleReqRespCbMutex);
2639 g_CABLEServerDataReceivedCallback = callback;
2640 ca_mutex_unlock(g_bleReqRespCbMutex);
2643 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2645 g_serverErrorCallback = callback;
2648 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2649 const uint8_t *charValue,
2650 uint32_t charValueLen)
2652 CAResult_t result = CA_SEND_FAILED;
2653 VERIFY_NON_NULL(address, TAG, "env is null");
2654 VERIFY_NON_NULL(charValue, TAG, "device is null");
2658 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2664 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2665 uint32_t charValueLen)
2667 VERIFY_NON_NULL(charValue, TAG, "device is null");
2669 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2674 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2676 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2680 CAResult_t CALEServerInitMutexVaraibles()
2682 if (NULL == g_bleReqRespCbMutex)
2684 g_bleReqRespCbMutex = ca_mutex_new();
2685 if (NULL == g_bleReqRespCbMutex)
2687 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2688 return CA_STATUS_FAILED;
2692 if (NULL == g_bleClientBDAddressMutex)
2694 g_bleClientBDAddressMutex = ca_mutex_new();
2695 if (NULL == g_bleClientBDAddressMutex)
2697 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2698 return CA_STATUS_FAILED;
2702 if (NULL == g_connectedDeviceListMutex)
2704 g_connectedDeviceListMutex = ca_mutex_new();
2705 if (NULL == g_connectedDeviceListMutex)
2707 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2708 return CA_STATUS_FAILED;
2712 if (NULL == g_threadSendMutex)
2714 g_threadSendMutex = ca_mutex_new();
2715 if (NULL == g_threadSendMutex)
2717 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2718 return CA_STATUS_FAILED;
2722 if (NULL == g_threadSendNotifyMutex)
2724 g_threadSendNotifyMutex = ca_mutex_new();
2725 if (NULL == g_threadSendNotifyMutex)
2727 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2728 return CA_STATUS_FAILED;
2732 return CA_STATUS_OK;
2735 void CALEServerTerminateMutexVaraibles()
2737 ca_mutex_free(g_bleReqRespCbMutex);
2738 g_bleReqRespCbMutex = NULL;
2740 ca_mutex_free(g_bleClientBDAddressMutex);
2741 g_bleClientBDAddressMutex = NULL;
2743 ca_mutex_free(g_connectedDeviceListMutex);
2744 g_connectedDeviceListMutex = NULL;
2746 ca_mutex_free(g_threadSendMutex);
2747 g_threadSendMutex = NULL;
2749 ca_mutex_free(g_threadSendNotifyMutex);
2750 g_threadSendNotifyMutex = NULL;
2753 void CALEServerTerminateConditionVaraibles()
2755 OIC_LOG(DEBUG, TAG, "this method is not supported");