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 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
349 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
351 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
353 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
354 return CA_SEND_FAILED;
357 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
358 ca_mutex_lock(g_threadSendNotifyMutex);
359 if (!g_isSignalSetFlag)
361 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
362 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
363 WAIT_TIME_WRITE_CHARACTERISTIC))
365 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
366 ca_mutex_unlock(g_threadSendNotifyMutex);
367 return CA_STATUS_FAILED;
370 // reset flag set by writeCharacteristic Callback
371 g_isSignalSetFlag = false;
372 ca_mutex_unlock(g_threadSendNotifyMutex);
373 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
377 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
378 jint offset, jbyteArray value)
380 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
381 VERIFY_NON_NULL(env, TAG, "env is null");
382 VERIFY_NON_NULL(device, TAG, "device is null");
383 VERIFY_NON_NULL(value, TAG, "value is null");
385 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
387 if (!CALEIsEnableBTAdapter(env))
389 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
390 return CA_ADAPTER_NOT_ENABLED;
393 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
394 "android/bluetooth/BluetoothGattServer");
395 if (!jni_cid_bluetoothGattServer)
397 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
398 return CA_STATUS_FAILED;
401 jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
403 "(Landroid/bluetooth/BluetoothDevice;"
405 if (!jni_mid_sendResponse)
407 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
408 return CA_STATUS_FAILED;
411 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
412 jni_mid_sendResponse, device,
413 requestId, status, offset,
415 if (JNI_FALSE == jni_boolean_sendResponse)
417 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
418 return CA_SEND_FAILED;
421 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
425 CAResult_t CALEStartAdvertise()
429 OIC_LOG(ERROR, TAG, "g_jvm is null");
430 return CA_STATUS_FAILED;
433 bool isAttached = false;
435 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
438 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
439 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
443 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
444 return CA_STATUS_FAILED;
450 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
451 if (CA_STATUS_OK != ret)
453 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
458 (*g_jvm)->DetachCurrentThread(g_jvm);
463 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
465 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
466 VERIFY_NON_NULL(env, TAG, "env is null");
467 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
469 if (!CALEIsEnableBTAdapter(env))
471 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
472 return CA_ADAPTER_NOT_ENABLED;
475 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
476 "android/bluetooth/le/"
477 "AdvertiseSettings$Builder");
478 if (!jni_cid_AdvertiseSettings)
480 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
481 return CA_STATUS_FAILED;
484 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
486 if (!jni_mid_AdvertiseSettings)
488 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
489 return CA_STATUS_FAILED;
492 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
493 jni_mid_AdvertiseSettings);
494 if (!jni_AdvertiseSettings)
496 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
497 return CA_STATUS_FAILED;
500 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
502 "(I)Landroid/bluetooth/le/"
503 "AdvertiseSettings$Builder;");
504 if (!jni_mid_setAdvertiseMode)
506 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
507 return CA_STATUS_FAILED;
510 // 0: Low power, 1: Balanced
511 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
512 jni_mid_setAdvertiseMode, 0);
513 if (!jni_obj_setAdvertiseMode)
515 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
516 return CA_STATUS_FAILED;
519 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
521 "(Z)Landroid/bluetooth/le/"
522 "AdvertiseSettings$Builder;");
523 if (!jni_mid_setConnectable)
525 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
526 return CA_STATUS_FAILED;
529 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
530 jni_mid_setConnectable, JNI_TRUE);
531 if (!jni_obj_setConnectable)
533 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
534 return CA_STATUS_FAILED;
537 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
538 "(I)Landroid/bluetooth/le/"
539 "AdvertiseSettings$Builder;");
540 if (!jni_mid_setTimeout)
542 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
543 return CA_STATUS_FAILED;
546 //A value of 0 will disable the time limit
547 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
548 jni_mid_setTimeout, 0);
549 if (!jni_obj_setTimeout)
551 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
552 return CA_STATUS_FAILED;
555 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
556 "android/bluetooth/le/"
557 "AdvertiseData$Builder");
558 if (!jni_cid_AdvertiseDataBuilder)
560 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
561 return CA_STATUS_FAILED;
564 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
566 if (!jni_mid_AdvertiseDataBuilder)
568 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
569 return CA_STATUS_FAILED;
572 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
573 jni_mid_AdvertiseDataBuilder);
574 if (!jni_AdvertiseDataBuilder)
576 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
577 return CA_STATUS_FAILED;
580 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
581 if (!jni_obj_serviceUUID)
583 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
584 return CA_STATUS_FAILED;
587 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
590 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
591 return CA_STATUS_FAILED;
594 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
596 "(Landroid/os/ParcelUuid;)Landroid/"
597 "bluetooth/le/AdvertiseData$Builder;");
598 if (!jni_mid_addServiceUuid)
600 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
601 return CA_STATUS_FAILED;
604 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
605 jni_mid_addServiceUuid,
607 if (!jni_obj_addServiceUuid)
609 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
610 return CA_STATUS_FAILED;
613 // Device name has to be included in advertise packet after Android API 23
614 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
615 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
616 "setIncludeDeviceName",
619 "AdvertiseData$Builder;");
620 if (!jni_mid_setIncludeDeviceName)
622 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
623 return CA_STATUS_FAILED;
626 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
627 jni_mid_setIncludeDeviceName,
629 if (!jni_obj_setIncludeDeviceName)
631 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
632 return CA_STATUS_FAILED;
635 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
636 if (!jni_cid_BTAdapter)
638 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
639 return CA_STATUS_FAILED;
642 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
644 "()Landroid/bluetooth/"
645 "BluetoothAdapter;");
646 if (!jni_mid_getDefaultAdapter)
648 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
649 return CA_STATUS_FAILED;
652 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
653 jni_mid_getDefaultAdapter);
654 if (!jni_obj_BTAdapter)
656 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
657 return CA_STATUS_FAILED;
660 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
661 "getBluetoothLeAdvertiser",
662 "()Landroid/bluetooth/le/"
663 "BluetoothLeAdvertiser;");
664 if (!jni_mid_getBluetoothLeAdvertiser)
666 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
667 return CA_STATUS_FAILED;
670 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
671 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
672 if (!jni_obj_getBluetoothLeAdvertiser)
674 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
675 return CA_STATUS_FAILED;
678 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
679 jni_cid_AdvertiseSettings,
681 "()Landroid/bluetooth/le/"
682 "AdvertiseSettings;");
683 if (!jni_mid_build_LeAdvertiseSettings)
685 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
686 return CA_STATUS_FAILED;
689 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
690 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
691 if (!jni_obj_build_LeAdvertiseSettings)
693 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
694 return CA_STATUS_FAILED;
697 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
699 "()Landroid/bluetooth/le/"
701 if (!jni_mid_build_LeAdvertiseData)
703 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
704 return CA_STATUS_FAILED;
707 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
708 jni_mid_build_LeAdvertiseData);
709 if (!jni_obj_build_LeAdvertiseData)
711 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
712 return CA_STATUS_FAILED;
715 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
716 "android/bluetooth/le/BluetoothLeAdvertiser");
717 if (!jni_cid_leAdvertiser)
719 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
720 return CA_STATUS_FAILED;
723 jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
725 "(Landroid/bluetooth/le/"
726 "AdvertiseSettings;Landroid/bluetooth/"
727 "le/AdvertiseData;Landroid/bluetooth/"
728 "le/AdvertiseCallback;)V");
729 if (!jni_mid_startAdvertising)
731 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
732 return CA_STATUS_FAILED;
735 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
736 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
739 if ((*env)->ExceptionCheck(env))
741 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
742 (*env)->ExceptionDescribe(env);
743 (*env)->ExceptionClear(env);
744 return CA_STATUS_FAILED;
747 OIC_LOG(DEBUG, TAG, "Advertising started!!");
749 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
753 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
755 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
756 VERIFY_NON_NULL(env, TAG, "env is null");
757 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
759 if (!CALEIsEnableBTAdapter(env))
761 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
762 return CA_ADAPTER_NOT_ENABLED;
765 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
766 if (!jni_cid_BTAdapter)
768 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
769 return CA_STATUS_FAILED;
772 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
773 "android/bluetooth/le/BluetoothLeAdvertiser");
774 if (!jni_cid_leAdvertiser)
776 OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
777 return CA_STATUS_FAILED;
780 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
782 "()Landroid/bluetooth/"
783 "BluetoothAdapter;");
784 if (!jni_mid_getDefaultAdapter)
786 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
787 return CA_STATUS_FAILED;
790 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
791 "getBluetoothLeAdvertiser",
792 "()Landroid/bluetooth/le/"
793 "BluetoothLeAdvertiser;");
794 if (!jni_mid_getBTLeAdvertiser)
796 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
797 return CA_STATUS_FAILED;
800 jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
802 "(Landroid/bluetooth/le/"
803 "AdvertiseCallback;)V");
804 if (!jni_mid_stopAdvertising)
806 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
807 return CA_STATUS_FAILED;
810 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
811 jni_mid_getDefaultAdapter);
812 if (!jni_obj_BTAdapter)
814 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
815 return CA_STATUS_FAILED;
818 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
819 jni_mid_getBTLeAdvertiser);
820 if (!jni_obj_getBluetoothLeAdvertiser)
822 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
823 return CA_STATUS_FAILED;
826 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
828 if ((*env)->ExceptionCheck(env))
830 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
831 (*env)->ExceptionDescribe(env);
832 (*env)->ExceptionClear(env);
833 return CA_STATUS_FAILED;
836 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
840 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
842 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
843 VERIFY_NON_NULL(env, TAG, "env is null");
844 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
846 if (!CALEIsEnableBTAdapter(env))
848 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
849 return CA_ADAPTER_NOT_ENABLED;
854 OIC_LOG(DEBUG, TAG, "Gatt server already started");
857 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
860 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
861 if (!bluetoothGattServer)
863 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
864 return CA_STATUS_FAILED;
867 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
868 if (!g_bluetoothGattServer)
870 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
871 return CA_STATUS_FAILED;
874 // create gatt service
875 jobject bluetoothGattService = CALEServerCreateGattService(env);
876 if (!bluetoothGattService)
878 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
879 return CA_STATUS_FAILED;
883 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
884 bluetoothGattService);
885 if (CA_STATUS_OK != res)
887 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
892 jobject CALEServerOpenGattServer(JNIEnv *env)
894 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
895 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
897 if (!CALEIsEnableBTAdapter(env))
899 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
903 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
904 if (!jni_cid_context)
906 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
910 jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
911 if (!jni_cid_bluetoothManager)
913 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
917 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
919 "Ljava/lang/String;");
920 if (!jni_fid_bluetoothService)
922 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
926 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
928 "(Ljava/lang/String;)"
929 "Ljava/lang/Object;");
930 if (!jni_mid_getSystemService)
932 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
936 jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
938 "(Landroid/content/Context;"
939 "Landroid/bluetooth/"
940 "BluetoothGattServerCallback;)"
941 "Landroid/bluetooth/"
942 "BluetoothGattServer;");
943 if (!jni_mid_openGattServer)
945 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
949 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
950 jni_fid_bluetoothService);
951 if (!jni_obj_bluetoothService)
953 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
957 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
958 jni_mid_getSystemService,
959 jni_obj_bluetoothService);
960 if (!jni_obj_bluetoothManager)
962 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
966 if (g_bluetoothManager)
968 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
970 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
972 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
973 jni_mid_openGattServer,
975 g_bluetoothGattServerCallback);
976 if (!jni_obj_bluetoothGattServer)
978 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
982 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
983 return jni_obj_bluetoothGattServer;
986 jobject CALEServerCreateGattService(JNIEnv *env)
988 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
989 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
991 if (!CALEIsEnableBTAdapter(env))
993 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
997 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
998 "BluetoothGattService");
999 if (!jni_cid_bluetoothGattService)
1001 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
1005 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1006 "BluetoothGattCharacteristic");
1007 if (!jni_cid_bluetoothGattCharacteristic)
1009 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
1013 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
1014 "SERVICE_TYPE_PRIMARY", "I");
1015 if (!jni_fid_serviceType)
1017 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
1021 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
1022 jni_cid_bluetoothGattCharacteristic,
1023 "PROPERTY_NOTIFY", "I");
1024 if (!jni_fid_readProperties)
1026 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1030 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1031 jni_cid_bluetoothGattCharacteristic,
1032 "PROPERTY_WRITE_NO_RESPONSE", "I");
1033 if (!jni_fid_writeProperties)
1035 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1039 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1040 jni_cid_bluetoothGattCharacteristic,
1041 "PERMISSION_READ", "I");
1042 if (!jni_fid_readPermissions)
1044 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1048 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1049 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1050 if (!jni_fid_writePermissions)
1052 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1056 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1057 "<init>", "(Ljava/util/UUID;I)V");
1058 if (!jni_mid_bluetoothGattService)
1060 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1064 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1065 "addCharacteristic",
1066 "(Landroid/bluetooth/"
1067 "BluetoothGattCharacteristic;)Z");
1068 if (!jni_mid_addCharacteristic)
1070 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1074 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1075 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1076 if (!jni_mid_bluetoothGattCharacteristic)
1078 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1082 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1083 if (!jni_obj_serviceUUID)
1085 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1089 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1090 jni_fid_serviceType);
1091 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1092 jni_mid_bluetoothGattService,
1093 jni_obj_serviceUUID, jni_int_serviceType);
1094 if (!jni_bluetoothGattService)
1096 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1100 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1101 if (!jni_obj_readUuid)
1103 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1107 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1108 jni_cid_bluetoothGattCharacteristic,
1109 jni_fid_readProperties);
1111 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1112 jni_cid_bluetoothGattCharacteristic,
1113 jni_fid_readPermissions);
1115 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1116 jni_cid_bluetoothGattCharacteristic,
1117 jni_fid_writePermissions);
1119 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1120 jni_mid_bluetoothGattCharacteristic,
1121 jni_obj_readUuid, jni_int_readProperties,
1122 jni_int_readPermissions|
1123 jni_int_writePermissions);
1124 if (!jni_readCharacteristic)
1126 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1130 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1131 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1132 if (!jni_boolean_addReadCharacteristic)
1134 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1138 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1139 if (!jni_obj_writeUuid)
1141 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1145 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1146 jni_cid_bluetoothGattCharacteristic,
1147 jni_fid_writeProperties);
1149 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1150 jni_mid_bluetoothGattCharacteristic,
1151 jni_obj_writeUuid, jni_int_writeProperties,
1152 jni_int_writePermissions);
1153 if (!jni_writeCharacteristic)
1155 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1159 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1160 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1161 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1163 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1167 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1168 return jni_bluetoothGattService;
1171 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1173 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1174 VERIFY_NON_NULL(env, TAG, "env is null");
1175 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1177 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1178 "BluetoothGattDescriptor");
1179 if (!jni_cid_bluetoothGattDescriptor)
1181 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1182 return CA_STATUS_FAILED;
1185 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1186 jni_cid_bluetoothGattDescriptor,
1188 "(Ljava/util/UUID;I)V");
1189 if (!jni_mid_bluetoothGattDescriptor)
1191 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1192 return CA_STATUS_FAILED;
1195 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1196 jni_cid_bluetoothGattDescriptor,
1197 "PERMISSION_READ", "I");
1198 if (!jni_fid_readPermissions)
1200 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1201 return CA_STATUS_FAILED;
1204 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1205 if (!jni_obj_readUuid)
1207 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1208 return CA_STATUS_FAILED;
1211 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1212 jni_fid_readPermissions);
1214 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1216 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1217 jni_mid_bluetoothGattDescriptor,
1218 jni_obj_readUuid, jni_int_readPermissions);
1219 if (!jni_readDescriptor)
1221 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1222 return CA_STATUS_FAILED;
1225 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1226 "BluetoothGattCharacteristic");
1227 if (!jni_cid_GattCharacteristic)
1229 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1230 return CA_STATUS_FAILED;
1233 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1235 "(Landroid/bluetooth/"
1236 "BluetoothGattDescriptor;)Z");
1237 if (!jni_mid_addDescriptor)
1239 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1240 return CA_STATUS_FAILED;
1243 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1244 jni_mid_addDescriptor,
1245 jni_readDescriptor);
1247 if (JNI_FALSE == jni_boolean_addDescriptor)
1249 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1250 return CA_STATUS_FAILED;
1254 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1256 return CA_STATUS_OK;
1259 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1260 jobject bluetoothGattService)
1262 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1263 VERIFY_NON_NULL(env, TAG, "env is null");
1264 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1265 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1267 if (!CALEIsEnableBTAdapter(env))
1269 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1270 return CA_ADAPTER_NOT_ENABLED;
1273 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1274 "android/bluetooth/BluetoothGattServer");
1275 if (!jni_cid_bluetoothGattServer)
1277 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1278 return CA_STATUS_FAILED;
1281 jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1283 "(Landroid/bluetooth/BluetoothGattService;)"
1285 if (!jni_mid_addService)
1287 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1288 return CA_STATUS_FAILED;
1291 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1293 bluetoothGattService);
1295 if (JNI_FALSE == jni_boolean_addService)
1297 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1298 return CA_STATUS_FAILED;
1301 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1302 return CA_STATUS_OK;
1305 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1307 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1308 VERIFY_NON_NULL(env, TAG, "env is null");
1309 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1311 if (!CALEIsEnableBTAdapter(env))
1313 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1314 return CA_ADAPTER_NOT_ENABLED;
1317 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1318 "android/bluetooth/BluetoothGattServer");
1319 if (!jni_cid_bluetoothGattServer)
1321 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1322 return CA_STATUS_FAILED;
1325 jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1326 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1327 if (!jni_mid_connect)
1329 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1330 return CA_STATUS_FAILED;
1333 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1334 jni_mid_connect, bluetoothDevice,
1336 if (JNI_FALSE == jni_boolean_connect)
1338 OIC_LOG(ERROR, TAG, "Fail to connect");
1339 return CA_STATUS_FAILED;
1342 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1343 return CA_STATUS_OK;
1346 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1348 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1349 VERIFY_NON_NULL(env, TAG, "env is null");
1351 ca_mutex_lock(g_connectedDeviceListMutex);
1352 if (!g_connectedDeviceList)
1354 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1355 ca_mutex_unlock(g_connectedDeviceListMutex);
1356 return CA_STATUS_FAILED;
1359 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1360 for (uint32_t index = 0; index < length; index++)
1362 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1365 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1369 // disconnect for device obj
1370 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1371 if (CA_STATUS_OK != res)
1373 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1378 ca_mutex_unlock(g_connectedDeviceListMutex);
1379 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1380 return CA_STATUS_OK;
1383 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1385 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1386 VERIFY_NON_NULL(env, TAG, "env is null");
1387 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1389 if (!CALEIsEnableBTAdapter(env))
1391 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1392 return CA_ADAPTER_NOT_ENABLED;
1395 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1396 "android/bluetooth/BluetoothGattServer");
1397 if (!jni_cid_bluetoothGattServer)
1399 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1400 return CA_STATUS_FAILED;
1403 jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1405 "(Landroid/bluetooth/BluetoothDevice;)"
1407 if (!jni_mid_cancelConnection)
1409 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1410 return CA_STATUS_FAILED;
1413 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1415 if ((*env)->ExceptionCheck(env))
1417 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1418 (*env)->ExceptionDescribe(env);
1419 (*env)->ExceptionClear(env);
1420 return CA_STATUS_FAILED;
1423 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1424 return CA_STATUS_OK;
1427 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1430 OIC_LOG(DEBUG, TAG, "GattServer Close");
1431 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1432 VERIFY_NON_NULL(env, TAG, "env is null");
1434 // get BluetoothGatt class
1435 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1436 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
1437 if (!jni_cid_BluetoothGatt)
1439 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1440 return CA_STATUS_FAILED;
1443 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1444 if (!jni_mid_closeGatt)
1446 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1447 return CA_STATUS_OK;
1450 // call disconnect gatt method
1451 OIC_LOG(DEBUG, TAG, "request to close GATT");
1452 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1454 if ((*env)->ExceptionCheck(env))
1456 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1457 (*env)->ExceptionDescribe(env);
1458 (*env)->ExceptionClear(env);
1459 return CA_STATUS_FAILED;
1462 return CA_STATUS_OK;
1465 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1467 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1468 VERIFY_NON_NULL(env, TAG, "env is null");
1469 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1470 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1472 if (!CALEIsEnableBTAdapter(env))
1474 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1475 return CA_ADAPTER_NOT_ENABLED;
1478 jobject responseChar = CALEServerSetResponseData(env, responseData);
1481 OIC_LOG(ERROR, TAG, "responseChar is null");
1482 return CA_STATUS_FAILED;
1485 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1486 if (CA_STATUS_OK != result)
1488 OIC_LOG(ERROR, TAG, "Fail to send response data");
1492 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1496 CAResult_t CALEServerInitialize()
1498 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1500 CALeServerJniInit();
1504 OIC_LOG(ERROR, TAG, "g_jvm is null");
1505 return CA_STATUS_FAILED;
1508 bool isAttached = false;
1510 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1513 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1514 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1518 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1519 return CA_STATUS_FAILED;
1524 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1525 if (CA_STATUS_OK != ret)
1527 OIC_LOG(ERROR, TAG, "it is not supported");
1531 (*g_jvm)->DetachCurrentThread(g_jvm);
1536 g_threadSendNotifyCond = ca_cond_new();
1538 ret = CALEServerInitMutexVaraibles();
1539 if (CA_STATUS_OK != ret)
1541 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1545 (*g_jvm)->DetachCurrentThread(g_jvm);
1547 return CA_STATUS_FAILED;
1550 CALEServerJNISetContext();
1551 CALEServerCreateCachedDeviceList();
1553 ret = CALEServerCreateJniInterfaceObject();
1554 if (CA_STATUS_OK != ret)
1556 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1560 (*g_jvm)->DetachCurrentThread(g_jvm);
1562 return CA_STATUS_FAILED;
1567 (*g_jvm)->DetachCurrentThread(g_jvm);
1570 g_isInitializedServer = true;
1571 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1572 return CA_STATUS_OK;
1575 void CALEServerTerminate()
1577 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1581 OIC_LOG(ERROR, TAG, "g_jvm is null");
1585 bool isAttached = false;
1587 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1590 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1591 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1595 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1603 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1604 g_sendBuffer = NULL;
1607 if (g_bluetoothManager)
1609 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1610 g_bluetoothManager = NULL;
1613 ca_cond_free(g_threadSendNotifyCond);
1614 g_threadSendNotifyCond = NULL;
1616 CALEServerTerminateMutexVaraibles();
1617 CALEServerTerminateConditionVaraibles();
1619 g_isInitializedServer = false;
1623 (*g_jvm)->DetachCurrentThread(g_jvm);
1626 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1629 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1631 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1632 VERIFY_NON_NULL(address, TAG, "address is null");
1633 VERIFY_NON_NULL(data, TAG, "data is null");
1637 OIC_LOG(ERROR, TAG, "g_jvm is null");
1638 return CA_STATUS_FAILED;
1641 bool isAttached = false;
1643 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1646 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1647 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1651 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1652 return CA_STATUS_FAILED;
1657 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1658 if (CA_STATUS_OK != ret)
1660 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1665 (*g_jvm)->DetachCurrentThread(g_jvm);
1671 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1673 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1674 VERIFY_NON_NULL(data, TAG, "data is null");
1678 OIC_LOG(ERROR, TAG, "g_jvm is null");
1679 return CA_STATUS_FAILED;
1682 bool isAttached = false;
1684 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1687 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1688 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1692 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1693 return CA_STATUS_FAILED;
1698 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1699 if (CA_STATUS_OK != ret)
1701 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1706 (*g_jvm)->DetachCurrentThread(g_jvm);
1712 CAResult_t CALEServerStartMulticastServer()
1714 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1716 if (!g_isInitializedServer)
1718 OIC_LOG(INFO, TAG, "server is not initialized");
1719 return CA_STATUS_FAILED;
1722 if (g_isStartServer)
1724 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1725 return CA_STATUS_FAILED;
1730 OIC_LOG(ERROR, TAG, "g_jvm is null");
1731 return CA_STATUS_FAILED;
1734 bool isAttached = false;
1736 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1739 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1740 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1744 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1745 return CA_STATUS_FAILED;
1750 g_isStartServer = true;
1752 // start gatt server
1753 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1754 if (CA_STATUS_OK != ret)
1756 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1761 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1762 if (CA_STATUS_OK != ret)
1764 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1769 (*g_jvm)->DetachCurrentThread(g_jvm);
1772 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1776 CAResult_t CALEServerStopMulticastServer()
1778 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1780 if (false == g_isStartServer)
1782 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1783 return CA_STATUS_FAILED;
1788 OIC_LOG(ERROR, TAG, "g_jvm is null");
1789 return CA_STATUS_FAILED;
1792 bool isAttached = false;
1794 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1797 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1798 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1802 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1803 return CA_STATUS_FAILED;
1808 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1809 if (CA_STATUS_OK != ret)
1811 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1814 g_isStartServer = false;
1818 (*g_jvm)->DetachCurrentThread(g_jvm);
1821 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1825 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1827 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1828 g_packetReceiveCallback = callback;
1831 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1834 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1836 VERIFY_NON_NULL(env, TAG, "env is null");
1837 VERIFY_NON_NULL(address, TAG, "address is null");
1838 VERIFY_NON_NULL(data, TAG, "data is null");
1840 if (!g_connectedDeviceList)
1842 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1843 return CA_STATUS_FAILED;
1846 ca_mutex_lock(g_threadSendMutex);
1848 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1849 for (uint32_t index = 0; index < length; index++)
1851 OIC_LOG(DEBUG, TAG, "check device address");
1852 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1855 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1859 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1860 if (!jni_setAddress)
1862 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1865 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1868 OIC_LOG(ERROR, TAG, "setAddress is null");
1872 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1873 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1875 if (!strcmp(setAddress, address))
1877 OIC_LOG(DEBUG, TAG, "found the device");
1879 if (g_obj_bluetoothDevice)
1881 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1883 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1884 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1887 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1890 if (g_obj_bluetoothDevice)
1892 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1893 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1894 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1896 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1897 if (CA_STATUS_OK != res)
1899 OIC_LOG(ERROR, TAG, "send has failed");
1900 if (g_obj_bluetoothDevice)
1902 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1903 g_obj_bluetoothDevice = NULL;
1910 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1916 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1917 g_sendBuffer = NULL;
1920 ca_mutex_unlock(g_threadSendMutex);
1921 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1922 return CA_STATUS_OK;
1927 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1928 g_sendBuffer = NULL;
1931 ca_mutex_unlock(g_threadSendMutex);
1932 return CA_SEND_FAILED;
1935 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1937 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1938 VERIFY_NON_NULL(env, TAG, "env is null");
1939 VERIFY_NON_NULL(data, TAG, "data is null");
1941 if (!g_connectedDeviceList)
1943 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1944 return CA_STATUS_FAILED;
1947 ca_mutex_lock(g_threadSendMutex);
1949 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1952 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1953 g_sendBuffer = NULL;
1955 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1956 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1957 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1959 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1960 for (uint32_t index = 0; index < length; index++)
1962 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1965 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1969 // send data for all device
1970 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1971 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1973 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1976 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1980 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1983 OIC_LOG(ERROR, TAG, "address is not available");
1987 if (g_obj_bluetoothDevice)
1989 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1991 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1993 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
1994 if (CA_STATUS_OK != res)
1996 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
1997 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1998 if (g_obj_bluetoothDevice)
2000 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2001 g_obj_bluetoothDevice = NULL;
2006 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
2007 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2012 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2013 g_sendBuffer = NULL;
2016 ca_mutex_unlock(g_threadSendMutex);
2017 return CA_STATUS_OK;
2020 void CALEServerCreateCachedDeviceList()
2022 ca_mutex_lock(g_connectedDeviceListMutex);
2023 // create new object array
2024 if (!g_connectedDeviceList)
2026 OIC_LOG(DEBUG, TAG, "Create device list");
2027 g_connectedDeviceList = u_arraylist_create();
2029 ca_mutex_unlock(g_connectedDeviceListMutex);
2032 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
2034 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
2035 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2037 if (!g_connectedDeviceList)
2039 OIC_LOG(ERROR, TAG, "list is null");
2043 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2044 for (uint32_t index = 0; index < length; index++)
2046 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2050 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2054 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2055 if (!jni_setAddress)
2057 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2061 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2064 OIC_LOG(ERROR, TAG, "setAddress is null");
2068 if (!strcmp(remoteAddress, setAddress))
2070 OIC_LOG(ERROR, TAG, "the device is already set");
2071 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2076 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2081 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2085 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2087 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2088 VERIFY_NON_NULL(device, TAG, "device is null");
2089 VERIFY_NON_NULL(env, TAG, "env is null");
2091 ca_mutex_lock(g_connectedDeviceListMutex);
2093 if (!g_connectedDeviceList)
2095 OIC_LOG(ERROR, TAG, "list is null");
2096 ca_mutex_unlock(g_connectedDeviceListMutex);
2097 return CA_STATUS_FAILED;
2100 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2101 if (!jni_remoteAddress)
2103 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2104 ca_mutex_unlock(g_connectedDeviceListMutex);
2105 return CA_STATUS_FAILED;
2108 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2111 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2112 ca_mutex_unlock(g_connectedDeviceListMutex);
2113 return CA_STATUS_FAILED;
2116 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2118 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2119 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2120 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2123 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2124 ca_mutex_unlock(g_connectedDeviceListMutex);
2125 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2126 return CA_STATUS_OK;
2129 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2131 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2132 VERIFY_NON_NULL(env, TAG, "env is null");
2134 ca_mutex_lock(g_connectedDeviceListMutex);
2135 if (!g_connectedDeviceList)
2137 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2138 ca_mutex_unlock(g_connectedDeviceListMutex);
2139 return CA_STATUS_FAILED;
2142 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2143 for (uint32_t index = 0; index < length; index++)
2145 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2148 (*env)->DeleteGlobalRef(env, jarrayObj);
2152 OICFree(g_connectedDeviceList);
2153 g_connectedDeviceList = NULL;
2154 ca_mutex_unlock(g_connectedDeviceListMutex);
2156 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2157 return CA_STATUS_OK;
2160 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2162 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2163 VERIFY_NON_NULL(env, TAG, "env is null");
2164 VERIFY_NON_NULL(address, TAG, "address is null");
2166 ca_mutex_lock(g_connectedDeviceListMutex);
2167 if (!g_connectedDeviceList)
2169 OIC_LOG(ERROR, TAG, "no deviceList");
2170 ca_mutex_unlock(g_connectedDeviceListMutex);
2171 return CA_STATUS_FAILED;
2174 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2175 for (uint32_t index = 0; index < length; index++)
2177 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2181 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2182 if (!jni_setAddress)
2184 OIC_LOG(ERROR, TAG, "wrong device address");
2187 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2190 OIC_LOG(ERROR, TAG, "setAddress is null");
2194 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2197 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2198 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2202 if (!strcmp(setAddress, remoteAddress))
2204 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2206 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2207 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2208 (*env)->DeleteGlobalRef(env, jarrayObj);
2210 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2212 OIC_LOG(ERROR, TAG, "List removal failed.");
2213 ca_mutex_unlock(g_connectedDeviceListMutex);
2214 return CA_STATUS_FAILED;
2216 ca_mutex_unlock(g_connectedDeviceListMutex);
2217 return CA_STATUS_OK;
2219 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2220 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2224 ca_mutex_unlock(g_connectedDeviceListMutex);
2226 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2228 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2229 return CA_STATUS_FAILED;
2232 JNIEXPORT void JNICALL
2233 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2236 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2237 VERIFY_NON_NULL_VOID(env, TAG, "env");
2238 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2239 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2241 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2244 JNIEXPORT void JNICALL
2245 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2249 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2250 VERIFY_NON_NULL_VOID(env, TAG, "env");
2251 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2252 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2254 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2257 JNIEXPORT void JNICALL
2258 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2259 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2261 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2262 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2264 VERIFY_NON_NULL_VOID(env, TAG, "env");
2265 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2266 VERIFY_NON_NULL_VOID(device, TAG, "device");
2269 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
2271 // STATE_DISCONNECTED
2272 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
2274 if (newState == state_connected)
2277 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2279 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2280 if (!jni_remoteAddress)
2282 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2286 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2289 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2293 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2295 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2296 CALEServerAddDeviceToList(env, device);
2298 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2300 else if (newState == state_disconnected)
2302 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2304 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2305 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2306 if (CA_STATUS_OK != ret)
2308 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2312 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2313 if (CA_STATUS_OK != ret)
2315 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2320 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2325 JNIEXPORT void JNICALL
2326 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2329 jobject gattService)
2331 VERIFY_NON_NULL_VOID(env, TAG, "env");
2332 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2333 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2335 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2338 JNIEXPORT void JNICALL
2339 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2340 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2342 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2343 VERIFY_NON_NULL_VOID(env, TAG, "env");
2344 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2345 VERIFY_NON_NULL_VOID(device, TAG, "device");
2346 VERIFY_NON_NULL_VOID(data, TAG, "data");
2349 JNIEXPORT void JNICALL
2350 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2351 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2353 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2354 VERIFY_NON_NULL_VOID(env, TAG, "env");
2355 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2356 VERIFY_NON_NULL_VOID(device, TAG, "device");
2357 VERIFY_NON_NULL_VOID(data, TAG, "data");
2359 // get Byte Array and covert to uint8_t*
2360 jint length = (*env)->GetArrayLength(env, data);
2363 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2365 uint8_t* requestData = NULL;
2366 requestData = OICMalloc(length);
2369 OIC_LOG(ERROR, TAG, "requestData is null");
2373 memcpy(requestData, jni_byte_requestData, length);
2374 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2376 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2379 OIC_LOG(ERROR, TAG, "jni_address is null");
2380 OICFree(requestData);
2384 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2387 OIC_LOG(ERROR, TAG, "address is null");
2388 OICFree(requestData);
2392 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2394 ca_mutex_lock(g_bleClientBDAddressMutex);
2395 uint32_t sentLength = 0;
2396 g_CABLEServerDataReceivedCallback(address, requestData, length,
2398 ca_mutex_unlock(g_bleClientBDAddressMutex);
2400 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2403 JNIEXPORT void JNICALL
2404 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2409 VERIFY_NON_NULL_VOID(env, TAG, "env");
2410 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2411 VERIFY_NON_NULL_VOID(device, TAG, "device");
2413 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2416 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2417 if (gatt_success != status) // error case
2419 OIC_LOG(ERROR, TAG, "it will be sent again.");
2421 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2422 if (CA_STATUS_OK != res)
2424 OIC_LOG(ERROR, TAG, "send has failed");
2426 if (g_obj_bluetoothDevice)
2428 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2429 g_obj_bluetoothDevice = NULL;
2432 ca_mutex_lock(g_threadSendNotifyMutex);
2433 g_isSignalSetFlag = true;
2434 ca_cond_signal(g_threadSendNotifyCond);
2435 ca_mutex_unlock(g_threadSendNotifyMutex);
2441 OIC_LOG(DEBUG, TAG, "notify success");
2443 if (g_obj_bluetoothDevice)
2445 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2446 g_obj_bluetoothDevice = NULL;
2449 // next data can be sent
2450 ca_mutex_lock(g_threadSendNotifyMutex);
2451 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2452 g_isSignalSetFlag = true;
2453 ca_cond_signal(g_threadSendNotifyCond);
2454 ca_mutex_unlock(g_threadSendNotifyMutex);
2459 JNIEXPORT void JNICALL
2460 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2462 jobject settingsInEffect)
2464 VERIFY_NON_NULL_VOID(env, TAG, "env");
2465 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2466 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2468 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2471 JNIEXPORT void JNICALL
2472 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2476 VERIFY_NON_NULL_VOID(env, TAG, "env");
2477 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2479 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2481 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2482 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2483 if (data_too_large == errorCode)
2485 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2493 CAResult_t CAStartLEGattServer()
2495 // start gatt service
2496 CALEServerStartMulticastServer();
2498 return CA_STATUS_OK;
2501 CAResult_t CAStopLEGattServer()
2503 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2507 OIC_LOG(ERROR, TAG, "g_jvm is null");
2508 return CA_STATUS_FAILED;
2511 bool isAttached = false;
2513 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2516 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2517 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2521 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2522 return CA_STATUS_FAILED;
2527 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2528 if (CA_STATUS_OK != ret)
2530 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2531 return CA_STATUS_FAILED;
2534 ret = CALEServerStopMulticastServer();
2535 if (CA_STATUS_OK != ret)
2537 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2538 return CA_STATUS_FAILED;
2541 ret = CALEServerDisconnectAllDevices(env);
2542 if (CA_STATUS_OK != ret)
2544 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2545 return CA_STATUS_FAILED;
2548 ret = CALEServerRemoveAllDevices(env);
2549 if (CA_STATUS_OK != ret)
2551 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2552 return CA_STATUS_FAILED;
2555 if (g_leAdvertiseCallback)
2557 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2560 if (g_bluetoothGattServer)
2562 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2565 if (g_bluetoothGattServerCallback)
2567 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2570 if (g_obj_bluetoothDevice)
2572 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2573 g_obj_bluetoothDevice = NULL;
2576 ca_mutex_lock(g_threadSendNotifyMutex);
2577 ca_cond_signal(g_threadSendNotifyCond);
2578 ca_mutex_unlock(g_threadSendNotifyMutex);
2580 g_isStartServer = false;
2584 (*g_jvm)->DetachCurrentThread(g_jvm);
2587 return CA_STATUS_OK;
2590 CAResult_t CAInitializeLEGattServer()
2592 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2593 return CALEServerInitialize();
2596 void CATerminateLEGattServer()
2598 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2599 CALEServerTerminate();
2602 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2604 ca_mutex_lock(g_bleReqRespCbMutex);
2605 g_CABLEServerDataReceivedCallback = callback;
2606 ca_mutex_unlock(g_bleReqRespCbMutex);
2609 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2611 g_serverErrorCallback = callback;
2614 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2615 const uint8_t *charValue,
2616 uint32_t charValueLen)
2618 CAResult_t result = CA_SEND_FAILED;
2619 VERIFY_NON_NULL(address, TAG, "env is null");
2620 VERIFY_NON_NULL(charValue, TAG, "device is null");
2624 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2630 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2631 uint32_t charValueLen)
2633 VERIFY_NON_NULL(charValue, TAG, "device is null");
2635 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2640 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2642 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2646 CAResult_t CALEServerInitMutexVaraibles()
2648 if (NULL == g_bleReqRespCbMutex)
2650 g_bleReqRespCbMutex = ca_mutex_new();
2651 if (NULL == g_bleReqRespCbMutex)
2653 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2654 return CA_STATUS_FAILED;
2658 if (NULL == g_bleClientBDAddressMutex)
2660 g_bleClientBDAddressMutex = ca_mutex_new();
2661 if (NULL == g_bleClientBDAddressMutex)
2663 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2664 return CA_STATUS_FAILED;
2668 if (NULL == g_connectedDeviceListMutex)
2670 g_connectedDeviceListMutex = ca_mutex_new();
2671 if (NULL == g_connectedDeviceListMutex)
2673 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2674 return CA_STATUS_FAILED;
2678 if (NULL == g_threadSendMutex)
2680 g_threadSendMutex = ca_mutex_new();
2681 if (NULL == g_threadSendMutex)
2683 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2684 return CA_STATUS_FAILED;
2688 if (NULL == g_threadSendNotifyMutex)
2690 g_threadSendNotifyMutex = ca_mutex_new();
2691 if (NULL == g_threadSendNotifyMutex)
2693 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2694 return CA_STATUS_FAILED;
2698 return CA_STATUS_OK;
2701 void CALEServerTerminateMutexVaraibles()
2703 ca_mutex_free(g_bleReqRespCbMutex);
2704 g_bleReqRespCbMutex = NULL;
2706 ca_mutex_free(g_bleClientBDAddressMutex);
2707 g_bleClientBDAddressMutex = NULL;
2709 ca_mutex_free(g_connectedDeviceListMutex);
2710 g_connectedDeviceListMutex = NULL;
2712 ca_mutex_free(g_threadSendMutex);
2713 g_threadSendMutex = NULL;
2715 ca_mutex_free(g_threadSendNotifyMutex);
2716 g_threadSendNotifyMutex = NULL;
2719 void CALEServerTerminateConditionVaraibles()
2721 OIC_LOG(DEBUG, TAG, "this method is not supported");