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
41 #define INVALID_STATE -1
43 static JavaVM *g_jvm = NULL;
44 static jobject g_context = NULL;
45 static jobject g_bluetoothGattServer = NULL;
46 static jobject g_bluetoothGattServerCallback = NULL;
47 static jobject g_leAdvertiseCallback = NULL;
48 static jobject g_bluetoothManager = NULL;
50 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
51 static CABLEErrorHandleCallback g_serverErrorCallback;
53 static u_arraylist_t *g_connectedDeviceList = NULL;
55 static bool g_isStartServer = false;
56 static bool g_isInitializedServer = false;
58 static jbyteArray g_sendBuffer = NULL;
59 static jobject g_obj_bluetoothDevice = NULL;
61 static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
62 static ca_mutex g_bleReqRespCbMutex = NULL;
63 static ca_mutex g_bleClientBDAddressMutex = NULL;
64 static ca_mutex g_connectedDeviceListMutex = NULL;
66 static ca_mutex g_threadSendMutex = NULL;
67 static ca_mutex g_threadSendNotifyMutex = NULL;
68 static ca_cond g_threadSendNotifyCond = NULL;
69 static bool g_isSignalSetFlag = false;
71 static jint g_state_connected = INVALID_STATE;
72 static jint g_state_disconnected = INVALID_STATE;
74 static const char CLASSPATH_BT_ADVERTISE_CB[] = "android/bluetooth/le/AdvertiseCallback";
75 static const char CLASSPATH_BT_GATTSERVER[] = "android/bluetooth/BluetoothGattServer";
77 void CALEServerJNISetContext()
79 OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
80 g_context = (jobject) CANativeJNIGetContext();
83 void CALeServerJniInit()
85 OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
86 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
89 CAResult_t CALEServerCreateJniInterfaceObject()
91 OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
95 OIC_LOG(ERROR, TAG, "g_context is null");
96 return CA_STATUS_FAILED;
101 OIC_LOG(ERROR, TAG, "g_jvm is null");
102 return CA_STATUS_FAILED;
105 bool isAttached = false;
107 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
110 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
111 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
115 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
116 return CA_STATUS_FAILED;
121 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
122 if (!jni_LEInterface)
124 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
128 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
130 if (!LeInterfaceConstructorMethod)
132 OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
136 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
137 OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
141 (*g_jvm)->DetachCurrentThread(g_jvm);
150 (*g_jvm)->DetachCurrentThread(g_jvm);
153 return CA_STATUS_FAILED;
157 * get the current connection state of the gatt profile to the remote device.
158 * @param[in] env JNI interface pointer.
159 * @param[in] device bluetooth device object
160 * @return state of the profile connection.
162 static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
164 OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
166 VERIFY_NON_NULL_RET(env, TAG, "env", -1);
167 VERIFY_NON_NULL_RET(device, TAG, "device", -1);
169 jmethodID jni_mid_getConnectionState = CAGetJNIMethodID(env, "android/bluetooth"
171 "getConnectionState",
172 "(Landroid/bluetooth/BluetoothDevice"
174 if (!jni_mid_getConnectionState)
176 OIC_LOG(ERROR, TAG, "jni_mid_getConnectionState is null");
180 if (!g_bluetoothManager)
182 OIC_LOG(ERROR, TAG, "g_bluetoothManager is null");
186 jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
187 jni_mid_getConnectionState,
188 device, GATT_PROFILE);
189 OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
193 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
195 OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
196 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
197 VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
199 if (!g_bluetoothGattServer)
201 OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
205 if (!CALEIsEnableBTAdapter(env))
207 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
211 OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
212 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
214 "(Ljava/util/UUID;)Landroid/bluetooth/"
215 "BluetoothGattService;");
216 if (!jni_mid_getService)
218 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
222 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
223 if (!jni_obj_serviceUUID)
225 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
229 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
231 jni_obj_serviceUUID);
232 if (!jni_obj_bluetoothGattService)
234 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
238 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
239 "BluetoothGattService",
242 "Landroid/bluetooth/"
243 "BluetoothGattCharacteristic;");
244 if (!jni_mid_getCharacteristic)
246 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
250 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
251 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
252 if (!jni_obj_responseUUID)
254 OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
258 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
259 env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
260 if (!jni_obj_bluetoothGattCharacteristic)
262 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
266 jmethodID jni_mid_setValue = CAGetJNIMethodID(env, "android/bluetooth/"
267 "BluetoothGattCharacteristic",
268 "setValue", "([B)Z");
269 if (!jni_mid_setValue)
271 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
275 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
276 jni_obj_bluetoothGattCharacteristic,
277 jni_mid_setValue, responseData);
278 if (JNI_FALSE == jni_boolean_setValue)
280 OIC_LOG(ERROR, TAG, "Fail to set response data");
283 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
284 return jni_obj_bluetoothGattCharacteristic;
287 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
289 OIC_LOG(DEBUG, TAG, "CALEServerSendResponseData");
290 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
291 VERIFY_NON_NULL(device, TAG, "device is null");
292 VERIFY_NON_NULL(env, TAG, "env is null");
294 if (!CALEIsEnableBTAdapter(env))
296 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
297 return CA_ADAPTER_NOT_ENABLED;
300 if (!g_bluetoothGattServer)
302 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is not available");
303 return CA_STATUS_FAILED;
306 if (g_state_connected != CALEServerGetConnectionState(env, device))
308 OIC_LOG(ERROR, TAG, "it is not connected state");
309 return CA_STATUS_FAILED;
312 jmethodID jni_mid_notifyCharacteristicChanged = CAGetJNIMethodID(env,
313 CLASSPATH_BT_GATTSERVER,
314 "notifyCharacteristicChanged",
315 "(Landroid/bluetooth/BluetoothDevice;"
316 "Landroid/bluetooth/"
317 "BluetoothGattCharacteristic;Z)Z");
318 if (!jni_mid_notifyCharacteristicChanged)
320 OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
321 return CA_STATUS_FAILED;
324 OIC_LOG(DEBUG, TAG, "CALL API - notifyCharacteristicChanged");
326 jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
327 env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
329 if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
331 OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
332 return CA_SEND_FAILED;
335 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
336 ca_mutex_lock(g_threadSendNotifyMutex);
337 if (!g_isSignalSetFlag)
339 OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
340 if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
341 WAIT_TIME_WRITE_CHARACTERISTIC))
343 OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
344 ca_mutex_unlock(g_threadSendNotifyMutex);
345 return CA_STATUS_FAILED;
348 // reset flag set by writeCharacteristic Callback
349 g_isSignalSetFlag = false;
350 ca_mutex_unlock(g_threadSendNotifyMutex);
351 OIC_LOG(INFO, TAG, "notifyCharacteristic success");
355 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
356 jint offset, jbyteArray value)
358 OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
359 VERIFY_NON_NULL(env, TAG, "env is null");
360 VERIFY_NON_NULL(device, TAG, "device is null");
361 VERIFY_NON_NULL(value, TAG, "value is null");
363 OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
365 if (!CALEIsEnableBTAdapter(env))
367 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
368 return CA_ADAPTER_NOT_ENABLED;
371 if (!g_bluetoothGattServer)
373 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is not available");
374 return CA_STATUS_FAILED;
377 jmethodID jni_mid_sendResponse = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
379 "(Landroid/bluetooth/BluetoothDevice;"
381 if (!jni_mid_sendResponse)
383 OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
384 return CA_STATUS_FAILED;
387 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
388 jni_mid_sendResponse, device,
389 requestId, status, offset,
391 if (JNI_FALSE == jni_boolean_sendResponse)
393 OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
394 return CA_SEND_FAILED;
397 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
401 CAResult_t CALEStartAdvertise()
405 OIC_LOG(ERROR, TAG, "g_jvm is null");
406 return CA_STATUS_FAILED;
409 bool isAttached = false;
411 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
414 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
415 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
419 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
420 return CA_STATUS_FAILED;
426 CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
427 if (CA_STATUS_OK != ret)
429 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
434 (*g_jvm)->DetachCurrentThread(g_jvm);
439 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
441 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
442 VERIFY_NON_NULL(env, TAG, "env is null");
443 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
445 if (!CALEIsEnableBTAdapter(env))
447 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
448 return CA_ADAPTER_NOT_ENABLED;
451 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
452 "android/bluetooth/le/"
453 "AdvertiseSettings$Builder");
454 if (!jni_cid_AdvertiseSettings)
456 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
457 return CA_STATUS_FAILED;
460 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
462 if (!jni_mid_AdvertiseSettings)
464 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
465 return CA_STATUS_FAILED;
468 jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
469 jni_mid_AdvertiseSettings);
470 if (!jni_AdvertiseSettings)
472 OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
473 return CA_STATUS_FAILED;
476 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
478 "(I)Landroid/bluetooth/le/"
479 "AdvertiseSettings$Builder;");
480 if (!jni_mid_setAdvertiseMode)
482 OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
483 return CA_STATUS_FAILED;
486 // 0: Low power, 1: Balanced
487 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
488 jni_mid_setAdvertiseMode, 0);
489 if (!jni_obj_setAdvertiseMode)
491 OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
492 return CA_STATUS_FAILED;
495 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
497 "(Z)Landroid/bluetooth/le/"
498 "AdvertiseSettings$Builder;");
499 if (!jni_mid_setConnectable)
501 OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
502 return CA_STATUS_FAILED;
505 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
506 jni_mid_setConnectable, JNI_TRUE);
507 if (!jni_obj_setConnectable)
509 OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
510 return CA_STATUS_FAILED;
513 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
514 "(I)Landroid/bluetooth/le/"
515 "AdvertiseSettings$Builder;");
516 if (!jni_mid_setTimeout)
518 OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
519 return CA_STATUS_FAILED;
522 //A value of 0 will disable the time limit
523 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
524 jni_mid_setTimeout, 0);
525 if (!jni_obj_setTimeout)
527 OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
528 return CA_STATUS_FAILED;
531 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
532 "android/bluetooth/le/"
533 "AdvertiseData$Builder");
534 if (!jni_cid_AdvertiseDataBuilder)
536 OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
537 return CA_STATUS_FAILED;
540 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
542 if (!jni_mid_AdvertiseDataBuilder)
544 OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
545 return CA_STATUS_FAILED;
548 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
549 jni_mid_AdvertiseDataBuilder);
550 if (!jni_AdvertiseDataBuilder)
552 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
553 return CA_STATUS_FAILED;
556 jobject jni_AdvertiseDataBuilderForScanRsp = (*env)->NewObject(env,
557 jni_cid_AdvertiseDataBuilder,
558 jni_mid_AdvertiseDataBuilder);
559 if (!jni_AdvertiseDataBuilderForScanRsp)
561 OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilderForScanRsp is null");
562 return CA_STATUS_FAILED;
565 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
566 if (!jni_obj_serviceUUID)
568 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
569 return CA_STATUS_FAILED;
572 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
575 OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
576 return CA_STATUS_FAILED;
579 jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
581 "(Landroid/os/ParcelUuid;)Landroid/"
582 "bluetooth/le/AdvertiseData$Builder;");
583 if (!jni_mid_addServiceUuid)
585 OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
586 return CA_STATUS_FAILED;
589 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
590 jni_mid_addServiceUuid,
592 if (!jni_obj_addServiceUuid)
594 OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
595 return CA_STATUS_FAILED;
598 // Device name has to be included in advertise packet after Android API 23
599 OIC_LOG(DEBUG, TAG, "device name will be added into advertise packet");
600 jmethodID jni_mid_setIncludeDeviceName = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
601 "setIncludeDeviceName",
604 "AdvertiseData$Builder;");
605 if (!jni_mid_setIncludeDeviceName)
607 OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
608 return CA_STATUS_FAILED;
611 jobject jni_obj_setIncludeDeviceName = (*env)->CallObjectMethod(env,
612 jni_AdvertiseDataBuilderForScanRsp,
613 jni_mid_setIncludeDeviceName,
615 if (!jni_obj_setIncludeDeviceName)
617 OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
618 return CA_STATUS_FAILED;
621 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
622 if (!jni_cid_BTAdapter)
624 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
625 return CA_STATUS_FAILED;
628 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
630 "()Landroid/bluetooth/"
631 "BluetoothAdapter;");
632 if (!jni_mid_getDefaultAdapter)
634 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
635 return CA_STATUS_FAILED;
638 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
639 jni_mid_getDefaultAdapter);
640 if (!jni_obj_BTAdapter)
642 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
643 return CA_STATUS_FAILED;
646 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
647 "getBluetoothLeAdvertiser",
648 "()Landroid/bluetooth/le/"
649 "BluetoothLeAdvertiser;");
650 if (!jni_mid_getBluetoothLeAdvertiser)
652 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
653 return CA_STATUS_FAILED;
656 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
657 env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
658 if (!jni_obj_getBluetoothLeAdvertiser)
660 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
661 return CA_STATUS_FAILED;
664 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
665 jni_cid_AdvertiseSettings,
667 "()Landroid/bluetooth/le/"
668 "AdvertiseSettings;");
669 if (!jni_mid_build_LeAdvertiseSettings)
671 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
672 return CA_STATUS_FAILED;
675 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
676 env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
677 if (!jni_obj_build_LeAdvertiseSettings)
679 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
680 return CA_STATUS_FAILED;
683 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
685 "()Landroid/bluetooth/le/"
687 if (!jni_mid_build_LeAdvertiseData)
689 OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
690 return CA_STATUS_FAILED;
693 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
694 jni_mid_build_LeAdvertiseData);
695 if (!jni_obj_build_LeAdvertiseData)
697 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
698 return CA_STATUS_FAILED;
701 jobject jni_obj_build_LeAdvertiseDataForScanRsp = (*env)->CallObjectMethod(env,
702 jni_AdvertiseDataBuilderForScanRsp,
703 jni_mid_build_LeAdvertiseData);
704 if (!jni_obj_build_LeAdvertiseDataForScanRsp)
706 OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseDataForScanRsp is null");
707 return CA_STATUS_FAILED;
710 jmethodID jni_mid_startAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
711 "BluetoothLeAdvertiser",
713 "(Landroid/bluetooth/le/"
714 "AdvertiseSettings;Landroid/bluetooth/"
715 "le/AdvertiseData;Landroid/bluetooth/"
716 "le/AdvertiseData;Landroid/bluetooth/"
717 "le/AdvertiseCallback;)V");
718 if (!jni_mid_startAdvertising)
720 OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
721 return CA_STATUS_FAILED;
724 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
725 jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
726 jni_obj_build_LeAdvertiseDataForScanRsp, advertiseCallback);
728 if ((*env)->ExceptionCheck(env))
730 OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
731 (*env)->ExceptionDescribe(env);
732 (*env)->ExceptionClear(env);
733 return CA_STATUS_FAILED;
736 OIC_LOG(DEBUG, TAG, "Advertising started!!");
738 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
742 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
744 OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
745 VERIFY_NON_NULL(env, TAG, "env is null");
746 VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
748 if (!CALEIsEnableBTAdapter(env))
750 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
751 return CA_ADAPTER_NOT_ENABLED;
754 jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
755 if (!jni_cid_BTAdapter)
757 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
758 return CA_STATUS_FAILED;
761 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
763 "()Landroid/bluetooth/"
764 "BluetoothAdapter;");
765 if (!jni_mid_getDefaultAdapter)
767 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
768 return CA_STATUS_FAILED;
771 jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
772 "getBluetoothLeAdvertiser",
773 "()Landroid/bluetooth/le/"
774 "BluetoothLeAdvertiser;");
775 if (!jni_mid_getBTLeAdvertiser)
777 OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
778 return CA_STATUS_FAILED;
781 jmethodID jni_mid_stopAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
782 "BluetoothLeAdvertiser",
784 "(Landroid/bluetooth/le/"
785 "AdvertiseCallback;)V");
786 if (!jni_mid_stopAdvertising)
788 OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
789 return CA_STATUS_FAILED;
792 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
793 jni_mid_getDefaultAdapter);
794 if (!jni_obj_BTAdapter)
796 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
797 return CA_STATUS_FAILED;
800 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
801 jni_mid_getBTLeAdvertiser);
802 if (!jni_obj_getBluetoothLeAdvertiser)
804 OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
805 return CA_STATUS_FAILED;
808 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
810 if ((*env)->ExceptionCheck(env))
812 OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
813 (*env)->ExceptionDescribe(env);
814 (*env)->ExceptionClear(env);
815 return CA_STATUS_FAILED;
818 OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
822 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
824 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
825 VERIFY_NON_NULL(env, TAG, "env is null");
826 VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
828 if (!CALEIsEnableBTAdapter(env))
830 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
831 return CA_ADAPTER_NOT_ENABLED;
836 OIC_LOG(DEBUG, TAG, "Gatt server already started");
839 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
842 jobject bluetoothGattServer = CALEServerOpenGattServer(env);
843 if (!bluetoothGattServer)
845 OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
846 return CA_STATUS_FAILED;
849 g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
850 if (!g_bluetoothGattServer)
852 OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
853 return CA_STATUS_FAILED;
856 // create gatt service
857 jobject bluetoothGattService = CALEServerCreateGattService(env);
858 if (!bluetoothGattService)
860 OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
861 return CA_STATUS_FAILED;
865 CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
866 bluetoothGattService);
867 if (CA_STATUS_OK != res)
869 OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
874 jobject CALEServerOpenGattServer(JNIEnv *env)
876 OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
877 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
879 if (!CALEIsEnableBTAdapter(env))
881 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
885 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
886 if (!jni_cid_context)
888 OIC_LOG(ERROR, TAG, "jni_cid_context is null");
892 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
894 "Ljava/lang/String;");
895 if (!jni_fid_bluetoothService)
897 OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
901 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
903 "(Ljava/lang/String;)"
904 "Ljava/lang/Object;");
905 if (!jni_mid_getSystemService)
907 OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
911 jmethodID jni_mid_openGattServer = CAGetJNIMethodID(env, "android/bluetooth/"
914 "(Landroid/content/Context;"
915 "Landroid/bluetooth/"
916 "BluetoothGattServerCallback;)"
917 "Landroid/bluetooth/"
918 "BluetoothGattServer;");
919 if (!jni_mid_openGattServer)
921 OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
925 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
926 jni_fid_bluetoothService);
927 if (!jni_obj_bluetoothService)
929 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
933 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
934 jni_mid_getSystemService,
935 jni_obj_bluetoothService);
936 if (!jni_obj_bluetoothManager)
938 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
942 if (g_bluetoothManager)
944 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
946 g_bluetoothManager = (*env)->NewGlobalRef(env, jni_obj_bluetoothManager);
948 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
949 jni_mid_openGattServer,
951 g_bluetoothGattServerCallback);
952 if (!jni_obj_bluetoothGattServer)
954 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
958 OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
959 return jni_obj_bluetoothGattServer;
962 jobject CALEServerCreateGattService(JNIEnv *env)
964 OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
965 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
967 if (!CALEIsEnableBTAdapter(env))
969 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
973 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
974 "BluetoothGattService");
975 if (!jni_cid_bluetoothGattService)
977 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
981 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
982 "BluetoothGattCharacteristic");
983 if (!jni_cid_bluetoothGattCharacteristic)
985 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
989 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
990 "SERVICE_TYPE_PRIMARY", "I");
991 if (!jni_fid_serviceType)
993 OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
997 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
998 jni_cid_bluetoothGattCharacteristic,
999 "PROPERTY_NOTIFY", "I");
1000 if (!jni_fid_readProperties)
1002 OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
1006 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
1007 jni_cid_bluetoothGattCharacteristic,
1008 "PROPERTY_WRITE_NO_RESPONSE", "I");
1009 if (!jni_fid_writeProperties)
1011 OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
1015 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1016 jni_cid_bluetoothGattCharacteristic,
1017 "PERMISSION_READ", "I");
1018 if (!jni_fid_readPermissions)
1020 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1024 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
1025 env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
1026 if (!jni_fid_writePermissions)
1028 OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
1032 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1033 "<init>", "(Ljava/util/UUID;I)V");
1034 if (!jni_mid_bluetoothGattService)
1036 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
1040 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
1041 "addCharacteristic",
1042 "(Landroid/bluetooth/"
1043 "BluetoothGattCharacteristic;)Z");
1044 if (!jni_mid_addCharacteristic)
1046 OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
1050 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
1051 env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
1052 if (!jni_mid_bluetoothGattCharacteristic)
1054 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
1058 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
1059 if (!jni_obj_serviceUUID)
1061 OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
1065 jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
1066 jni_fid_serviceType);
1067 jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
1068 jni_mid_bluetoothGattService,
1069 jni_obj_serviceUUID, jni_int_serviceType);
1070 if (!jni_bluetoothGattService)
1072 OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
1076 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1077 if (!jni_obj_readUuid)
1079 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1083 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
1084 jni_cid_bluetoothGattCharacteristic,
1085 jni_fid_readProperties);
1087 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
1088 jni_cid_bluetoothGattCharacteristic,
1089 jni_fid_readPermissions);
1091 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
1092 jni_cid_bluetoothGattCharacteristic,
1093 jni_fid_writePermissions);
1095 jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1096 jni_mid_bluetoothGattCharacteristic,
1097 jni_obj_readUuid, jni_int_readProperties,
1098 jni_int_readPermissions|
1099 jni_int_writePermissions);
1100 if (!jni_readCharacteristic)
1102 OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
1106 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
1107 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
1108 if (!jni_boolean_addReadCharacteristic)
1110 OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1114 jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1115 if (!jni_obj_writeUuid)
1117 OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1121 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1122 jni_cid_bluetoothGattCharacteristic,
1123 jni_fid_writeProperties);
1125 jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1126 jni_mid_bluetoothGattCharacteristic,
1127 jni_obj_writeUuid, jni_int_writeProperties,
1128 jni_int_writePermissions);
1129 if (!jni_writeCharacteristic)
1131 OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1135 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1136 env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1137 if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1139 OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1143 OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1144 return jni_bluetoothGattService;
1147 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
1149 OIC_LOG(DEBUG, TAG, "CALEServerAddDescriptor");
1150 VERIFY_NON_NULL(env, TAG, "env is null");
1151 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1153 jclass jni_cid_bluetoothGattDescriptor = (*env)->FindClass(env, "android/bluetooth/"
1154 "BluetoothGattDescriptor");
1155 if (!jni_cid_bluetoothGattDescriptor)
1157 OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
1158 return CA_STATUS_FAILED;
1161 jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
1162 jni_cid_bluetoothGattDescriptor,
1164 "(Ljava/util/UUID;I)V");
1165 if (!jni_mid_bluetoothGattDescriptor)
1167 OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
1168 return CA_STATUS_FAILED;
1171 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
1172 jni_cid_bluetoothGattDescriptor,
1173 "PERMISSION_READ", "I");
1174 if (!jni_fid_readPermissions)
1176 OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
1177 return CA_STATUS_FAILED;
1180 jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1181 if (!jni_obj_readUuid)
1183 OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
1184 return CA_STATUS_FAILED;
1187 jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
1188 jni_fid_readPermissions);
1190 OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
1192 jobject jni_readDescriptor = (*env)->NewObject(env, jni_cid_bluetoothGattDescriptor,
1193 jni_mid_bluetoothGattDescriptor,
1194 jni_obj_readUuid, jni_int_readPermissions);
1195 if (!jni_readDescriptor)
1197 OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
1198 return CA_STATUS_FAILED;
1201 jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1202 "BluetoothGattCharacteristic");
1203 if (!jni_cid_GattCharacteristic)
1205 OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
1206 return CA_STATUS_FAILED;
1209 jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
1211 "(Landroid/bluetooth/"
1212 "BluetoothGattDescriptor;)Z");
1213 if (!jni_mid_addDescriptor)
1215 OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
1216 return CA_STATUS_FAILED;
1219 jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
1220 jni_mid_addDescriptor,
1221 jni_readDescriptor);
1223 if (JNI_FALSE == jni_boolean_addDescriptor)
1225 OIC_LOG(ERROR, TAG, "addDescriptor has failed");
1226 return CA_STATUS_FAILED;
1230 OIC_LOG(DEBUG, TAG, "addDescriptor success");
1232 return CA_STATUS_OK;
1235 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1236 jobject bluetoothGattService)
1238 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1239 VERIFY_NON_NULL(env, TAG, "env is null");
1240 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1241 VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1243 if (!CALEIsEnableBTAdapter(env))
1245 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1246 return CA_ADAPTER_NOT_ENABLED;
1249 jmethodID jni_mid_addService = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1251 "(Landroid/bluetooth/BluetoothGattService;)"
1253 if (!jni_mid_addService)
1255 OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1256 return CA_STATUS_FAILED;
1259 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1261 bluetoothGattService);
1263 if (JNI_FALSE == jni_boolean_addService)
1265 OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1266 return CA_STATUS_FAILED;
1269 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1270 return CA_STATUS_OK;
1273 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1275 OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1276 VERIFY_NON_NULL(env, TAG, "env is null");
1277 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1279 if (!CALEIsEnableBTAdapter(env))
1281 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1282 return CA_ADAPTER_NOT_ENABLED;
1285 jmethodID jni_mid_connect = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1287 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1288 if (!jni_mid_connect)
1290 OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1291 return CA_STATUS_FAILED;
1294 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1295 jni_mid_connect, bluetoothDevice,
1297 if (JNI_FALSE == jni_boolean_connect)
1299 OIC_LOG(ERROR, TAG, "Fail to connect");
1300 return CA_STATUS_FAILED;
1303 OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1304 return CA_STATUS_OK;
1307 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1309 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1310 VERIFY_NON_NULL(env, TAG, "env is null");
1312 ca_mutex_lock(g_connectedDeviceListMutex);
1313 if (!g_connectedDeviceList)
1315 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1316 ca_mutex_unlock(g_connectedDeviceListMutex);
1317 return CA_STATUS_FAILED;
1320 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1321 for (uint32_t index = 0; index < length; index++)
1323 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1326 OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1330 // disconnect for device obj
1331 CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1332 if (CA_STATUS_OK != res)
1334 OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1339 ca_mutex_unlock(g_connectedDeviceListMutex);
1340 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1341 return CA_STATUS_OK;
1344 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1346 OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1347 VERIFY_NON_NULL(env, TAG, "env is null");
1348 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1350 if (!CALEIsEnableBTAdapter(env))
1352 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1353 return CA_ADAPTER_NOT_ENABLED;
1356 jmethodID jni_mid_cancelConnection = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1358 "(Landroid/bluetooth/BluetoothDevice;)"
1360 if (!jni_mid_cancelConnection)
1362 OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1363 return CA_STATUS_FAILED;
1366 (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1368 if ((*env)->ExceptionCheck(env))
1370 OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1371 (*env)->ExceptionDescribe(env);
1372 (*env)->ExceptionClear(env);
1373 return CA_STATUS_FAILED;
1376 OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1377 return CA_STATUS_OK;
1380 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1383 OIC_LOG(DEBUG, TAG, "GattServer Close");
1384 VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1385 VERIFY_NON_NULL(env, TAG, "env is null");
1387 // get BluetoothGatt class
1388 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1389 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATTSERVER,
1391 if (!jni_mid_closeGatt)
1393 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1394 return CA_STATUS_OK;
1397 // call disconnect gatt method
1398 OIC_LOG(DEBUG, TAG, "request to close GATT");
1399 (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1401 if ((*env)->ExceptionCheck(env))
1403 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1404 (*env)->ExceptionDescribe(env);
1405 (*env)->ExceptionClear(env);
1406 return CA_STATUS_FAILED;
1409 return CA_STATUS_OK;
1412 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1414 OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1415 VERIFY_NON_NULL(env, TAG, "env is null");
1416 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1417 VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1419 if (!CALEIsEnableBTAdapter(env))
1421 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1422 return CA_ADAPTER_NOT_ENABLED;
1425 jobject responseChar = CALEServerSetResponseData(env, responseData);
1428 OIC_LOG(ERROR, TAG, "responseChar is null");
1429 return CA_STATUS_FAILED;
1432 CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1433 if (CA_STATUS_OK != result)
1435 OIC_LOG(ERROR, TAG, "Fail to send response data");
1439 OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1443 CAResult_t CALEServerInitialize()
1445 OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1447 CALeServerJniInit();
1451 OIC_LOG(ERROR, TAG, "g_jvm is null");
1452 return CA_STATUS_FAILED;
1455 bool isAttached = false;
1457 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1460 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1461 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1465 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1466 return CA_STATUS_FAILED;
1471 CAResult_t ret = CALECheckPlatformVersion(env, 21);
1472 if (CA_STATUS_OK != ret)
1474 OIC_LOG(ERROR, TAG, "it is not supported");
1478 (*g_jvm)->DetachCurrentThread(g_jvm);
1483 g_threadSendNotifyCond = ca_cond_new();
1485 ret = CALEServerInitMutexVaraibles();
1486 if (CA_STATUS_OK != ret)
1488 OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1492 (*g_jvm)->DetachCurrentThread(g_jvm);
1494 return CA_STATUS_FAILED;
1497 CALEServerJNISetContext();
1498 CALEServerCreateCachedDeviceList();
1500 ret = CALEServerCreateJniInterfaceObject();
1501 if (CA_STATUS_OK != ret)
1503 OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1507 (*g_jvm)->DetachCurrentThread(g_jvm);
1509 return CA_STATUS_FAILED;
1514 (*g_jvm)->DetachCurrentThread(g_jvm);
1517 g_isInitializedServer = true;
1518 OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1519 return CA_STATUS_OK;
1522 void CALEServerTerminate()
1524 OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1528 OIC_LOG(ERROR, TAG, "g_jvm is null");
1532 bool isAttached = false;
1534 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1537 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1538 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1542 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1550 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1551 g_sendBuffer = NULL;
1554 if (g_bluetoothManager)
1556 (*env)->DeleteGlobalRef(env, g_bluetoothManager);
1557 g_bluetoothManager = NULL;
1560 ca_cond_free(g_threadSendNotifyCond);
1561 g_threadSendNotifyCond = NULL;
1563 CALEServerTerminateMutexVaraibles();
1564 CALEServerTerminateConditionVaraibles();
1566 g_isInitializedServer = false;
1570 (*g_jvm)->DetachCurrentThread(g_jvm);
1573 OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1576 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
1578 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
1579 VERIFY_NON_NULL(address, TAG, "address is null");
1580 VERIFY_NON_NULL(data, TAG, "data is null");
1584 OIC_LOG(ERROR, TAG, "g_jvm is null");
1585 return CA_STATUS_FAILED;
1588 bool isAttached = false;
1590 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1593 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1594 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1598 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1599 return CA_STATUS_FAILED;
1604 CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1605 if (CA_STATUS_OK != ret)
1607 OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1612 (*g_jvm)->DetachCurrentThread(g_jvm);
1618 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
1620 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
1621 VERIFY_NON_NULL(data, TAG, "data is null");
1625 OIC_LOG(ERROR, TAG, "g_jvm is null");
1626 return CA_STATUS_FAILED;
1629 bool isAttached = false;
1631 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1634 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1635 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1639 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1640 return CA_STATUS_FAILED;
1645 CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1646 if (CA_STATUS_OK != ret)
1648 OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1653 (*g_jvm)->DetachCurrentThread(g_jvm);
1659 CAResult_t CALEServerStartMulticastServer()
1661 OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1663 if (!g_isInitializedServer)
1665 OIC_LOG(INFO, TAG, "server is not initialized");
1666 return CA_STATUS_FAILED;
1669 if (g_isStartServer)
1671 OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1672 return CA_STATUS_FAILED;
1677 OIC_LOG(ERROR, TAG, "g_jvm is null");
1678 return CA_STATUS_FAILED;
1681 bool isAttached = false;
1683 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1686 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1687 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1691 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1692 return CA_STATUS_FAILED;
1697 g_isStartServer = true;
1699 // start gatt server
1700 CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1701 if (CA_STATUS_OK != ret)
1703 OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1708 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1709 if (CA_STATUS_OK != ret)
1711 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1714 // get Constants Value from Android Platform
1715 g_state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
1716 g_state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
1720 (*g_jvm)->DetachCurrentThread(g_jvm);
1723 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1727 CAResult_t CALEServerStopMulticastServer()
1729 OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1731 if (false == g_isStartServer)
1733 OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1734 return CA_STATUS_FAILED;
1739 OIC_LOG(ERROR, TAG, "g_jvm is null");
1740 return CA_STATUS_FAILED;
1743 bool isAttached = false;
1745 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1748 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1749 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1753 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1754 return CA_STATUS_FAILED;
1759 CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1760 if (CA_STATUS_OK != ret)
1762 OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1765 g_isStartServer = false;
1769 (*g_jvm)->DetachCurrentThread(g_jvm);
1772 OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1776 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1778 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1779 g_packetReceiveCallback = callback;
1782 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const uint8_t* data,
1785 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p",
1787 VERIFY_NON_NULL(env, TAG, "env is null");
1788 VERIFY_NON_NULL(address, TAG, "address is null");
1789 VERIFY_NON_NULL(data, TAG, "data is null");
1791 if (!g_connectedDeviceList)
1793 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1794 return CA_STATUS_FAILED;
1797 ca_mutex_lock(g_threadSendMutex);
1799 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1800 for (uint32_t index = 0; index < length; index++)
1802 OIC_LOG(DEBUG, TAG, "check device address");
1803 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1806 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1810 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1811 if (!jni_setAddress)
1813 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1816 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1819 OIC_LOG(ERROR, TAG, "setAddress is null");
1823 OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1824 OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1826 if (!strcmp(setAddress, address))
1828 OIC_LOG(DEBUG, TAG, "found the device");
1830 if (g_obj_bluetoothDevice)
1832 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1833 g_obj_bluetoothDevice = NULL;
1838 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1840 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1843 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1846 if (g_obj_bluetoothDevice)
1848 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1849 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1850 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1852 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
1853 if (CA_STATUS_OK != res)
1855 OIC_LOG(ERROR, TAG, "send has failed");
1861 OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1867 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1868 g_sendBuffer = NULL;
1871 ca_mutex_unlock(g_threadSendMutex);
1872 OIC_LOG(INFO, TAG, "unicast - send request is successful");
1873 return CA_STATUS_OK;
1878 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1879 g_sendBuffer = NULL;
1882 if (g_obj_bluetoothDevice)
1884 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1885 g_obj_bluetoothDevice = NULL;
1888 ca_mutex_unlock(g_threadSendMutex);
1889 return CA_SEND_FAILED;
1892 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data, uint32_t dataLen)
1894 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1895 VERIFY_NON_NULL(env, TAG, "env is null");
1896 VERIFY_NON_NULL(data, TAG, "data is null");
1898 if (!g_connectedDeviceList)
1900 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1901 return CA_STATUS_FAILED;
1904 ca_mutex_lock(g_threadSendMutex);
1906 OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
1909 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1910 g_sendBuffer = NULL;
1912 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1913 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1914 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1916 uint32_t length = u_arraylist_length(g_connectedDeviceList);
1917 for (uint32_t index = 0; index < length; index++)
1919 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1922 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1926 // send data for all device
1927 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1928 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1930 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
1933 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
1937 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1940 OIC_LOG(ERROR, TAG, "address is not available");
1944 if (g_obj_bluetoothDevice)
1946 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1947 g_obj_bluetoothDevice = NULL;
1952 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
1955 CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
1956 if (CA_STATUS_OK != res)
1958 OIC_LOG_V(ERROR, TAG, "send has failed for the device[%s]", address);
1959 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1960 if (g_obj_bluetoothDevice)
1962 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
1963 g_obj_bluetoothDevice = NULL;
1968 OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", address);
1969 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1974 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1975 g_sendBuffer = NULL;
1978 ca_mutex_unlock(g_threadSendMutex);
1979 return CA_STATUS_OK;
1982 void CALEServerCreateCachedDeviceList()
1984 ca_mutex_lock(g_connectedDeviceListMutex);
1985 // create new object array
1986 if (!g_connectedDeviceList)
1988 OIC_LOG(DEBUG, TAG, "Create device list");
1989 g_connectedDeviceList = u_arraylist_create();
1991 ca_mutex_unlock(g_connectedDeviceListMutex);
1994 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1996 VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1997 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1999 if (!g_connectedDeviceList)
2001 OIC_LOG(ERROR, TAG, "list is null");
2005 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2006 for (uint32_t index = 0; index < length; index++)
2008 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2012 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2016 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2017 if (!jni_setAddress)
2019 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2023 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2026 OIC_LOG(ERROR, TAG, "setAddress is null");
2030 if (!strcmp(remoteAddress, setAddress))
2032 OIC_LOG(ERROR, TAG, "the device is already set");
2033 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2038 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2043 OIC_LOG(DEBUG, TAG, "there are no device in the list");
2047 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
2049 OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
2050 VERIFY_NON_NULL(device, TAG, "device is null");
2051 VERIFY_NON_NULL(env, TAG, "env is null");
2053 ca_mutex_lock(g_connectedDeviceListMutex);
2055 if (!g_connectedDeviceList)
2057 OIC_LOG(ERROR, TAG, "list is null");
2058 ca_mutex_unlock(g_connectedDeviceListMutex);
2059 return CA_STATUS_FAILED;
2062 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2063 if (!jni_remoteAddress)
2065 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2066 ca_mutex_unlock(g_connectedDeviceListMutex);
2067 return CA_STATUS_FAILED;
2070 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2073 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2074 ca_mutex_unlock(g_connectedDeviceListMutex);
2075 return CA_STATUS_FAILED;
2078 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2080 jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
2081 u_arraylist_add(g_connectedDeviceList, jni_obj_device);
2082 OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
2085 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2086 ca_mutex_unlock(g_connectedDeviceListMutex);
2087 OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
2088 return CA_STATUS_OK;
2091 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
2093 OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
2094 VERIFY_NON_NULL(env, TAG, "env is null");
2096 ca_mutex_lock(g_connectedDeviceListMutex);
2097 if (!g_connectedDeviceList)
2099 OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
2100 ca_mutex_unlock(g_connectedDeviceListMutex);
2101 return CA_STATUS_FAILED;
2104 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2105 for (uint32_t index = 0; index < length; index++)
2107 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2110 (*env)->DeleteGlobalRef(env, jarrayObj);
2114 OICFree(g_connectedDeviceList);
2115 g_connectedDeviceList = NULL;
2116 ca_mutex_unlock(g_connectedDeviceListMutex);
2118 OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
2119 return CA_STATUS_OK;
2122 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
2124 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2125 VERIFY_NON_NULL(env, TAG, "env is null");
2126 VERIFY_NON_NULL(address, TAG, "address is null");
2128 ca_mutex_lock(g_connectedDeviceListMutex);
2129 if (!g_connectedDeviceList)
2131 OIC_LOG(ERROR, TAG, "no deviceList");
2132 ca_mutex_unlock(g_connectedDeviceListMutex);
2133 return CA_STATUS_FAILED;
2136 uint32_t length = u_arraylist_length(g_connectedDeviceList);
2137 for (uint32_t index = 0; index < length; index++)
2139 jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
2143 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2144 if (!jni_setAddress)
2146 OIC_LOG(ERROR, TAG, "wrong device address");
2149 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2152 OIC_LOG(ERROR, TAG, "setAddress is null");
2156 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2159 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2160 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2164 if (!strcmp(setAddress, remoteAddress))
2166 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
2168 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2169 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2170 (*env)->DeleteGlobalRef(env, jarrayObj);
2173 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
2175 OIC_LOG(ERROR, TAG, "List removal failed.");
2176 ca_mutex_unlock(g_connectedDeviceListMutex);
2177 return CA_STATUS_FAILED;
2179 ca_mutex_unlock(g_connectedDeviceListMutex);
2180 return CA_STATUS_OK;
2182 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2183 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2187 ca_mutex_unlock(g_connectedDeviceListMutex);
2189 OIC_LOG(DEBUG, TAG, "there are no device in the device list");
2191 OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
2192 return CA_STATUS_FAILED;
2195 JNIEXPORT void JNICALL
2196 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
2199 OIC_LOG(DEBUG, TAG, "Register Le Gatt Server Callback");
2200 VERIFY_NON_NULL_VOID(env, TAG, "env");
2201 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2202 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2204 g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
2207 JNIEXPORT void JNICALL
2208 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2212 OIC_LOG(DEBUG, TAG, "Register Le Advertise Callback");
2213 VERIFY_NON_NULL_VOID(env, TAG, "env");
2214 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2215 VERIFY_NON_NULL_VOID(callback, TAG, "callback");
2217 g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2220 JNIEXPORT void JNICALL
2221 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2222 JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2224 OIC_LOG(DEBUG, TAG, " Gatt Server ConnectionStateChange Callback");
2225 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2227 VERIFY_NON_NULL_VOID(env, TAG, "env");
2228 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2229 VERIFY_NON_NULL_VOID(device, TAG, "device");
2231 if (newState == g_state_connected)
2234 OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2236 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2237 if (!jni_remoteAddress)
2239 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2243 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2246 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2250 if (false == CALEServerIsDeviceInList(env, remoteAddress))
2252 OIC_LOG(DEBUG, TAG, "add connected device to cache");
2253 CALEServerAddDeviceToList(env, device);
2255 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2257 else if (newState == g_state_disconnected)
2259 OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2261 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2262 CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
2263 if (CA_STATUS_OK != ret)
2265 OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
2269 ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
2270 if (CA_STATUS_OK != ret)
2272 OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
2280 OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2285 JNIEXPORT void JNICALL
2286 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2289 jobject gattService)
2291 VERIFY_NON_NULL_VOID(env, TAG, "env");
2292 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2293 VERIFY_NON_NULL_VOID(gattService, TAG, "gattService");
2297 OIC_LOG_V(DEBUG, TAG, "Gatt Service Added Callback(%d)", status);
2300 JNIEXPORT void JNICALL
2301 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2302 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2304 OIC_LOG(DEBUG, TAG, " Gatt Server Characteristic Read Request Callback");
2305 VERIFY_NON_NULL_VOID(env, TAG, "env");
2306 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2307 VERIFY_NON_NULL_VOID(device, TAG, "device");
2308 VERIFY_NON_NULL_VOID(data, TAG, "data");
2311 JNIEXPORT void JNICALL
2312 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2313 JNIEnv *env, jobject obj, jobject device, jbyteArray data)
2315 OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
2316 VERIFY_NON_NULL_VOID(env, TAG, "env");
2317 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2318 VERIFY_NON_NULL_VOID(device, TAG, "device");
2319 VERIFY_NON_NULL_VOID(data, TAG, "data");
2321 // get Byte Array and covert to uint8_t*
2322 jint length = (*env)->GetArrayLength(env, data);
2325 jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2327 uint8_t* requestData = NULL;
2328 requestData = OICMalloc(length);
2331 OIC_LOG(ERROR, TAG, "requestData is null");
2335 memcpy(requestData, jni_byte_requestData, length);
2336 (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2338 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2341 OIC_LOG(ERROR, TAG, "jni_address is null");
2342 OICFree(requestData);
2346 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2349 OIC_LOG(ERROR, TAG, "address is null");
2350 OICFree(requestData);
2354 OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
2356 ca_mutex_lock(g_bleClientBDAddressMutex);
2357 uint32_t sentLength = 0;
2358 g_CABLEServerDataReceivedCallback(address, requestData, length,
2360 ca_mutex_unlock(g_bleClientBDAddressMutex);
2362 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2365 JNIEXPORT void JNICALL
2366 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2371 VERIFY_NON_NULL_VOID(env, TAG, "env");
2372 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2373 VERIFY_NON_NULL_VOID(device, TAG, "device");
2375 OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
2378 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
2379 if (gatt_success != status) // error case
2381 OIC_LOG(ERROR, TAG, "it will be sent again.");
2383 CAResult_t res = CALEServerSend(env, device, g_sendBuffer);
2384 if (CA_STATUS_OK != res)
2386 OIC_LOG(ERROR, TAG, "send has failed");
2388 if (g_obj_bluetoothDevice)
2390 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2391 g_obj_bluetoothDevice = NULL;
2394 ca_mutex_lock(g_threadSendNotifyMutex);
2395 g_isSignalSetFlag = true;
2396 ca_cond_signal(g_threadSendNotifyCond);
2397 ca_mutex_unlock(g_threadSendNotifyMutex);
2403 OIC_LOG(DEBUG, TAG, "notify success");
2405 if (g_obj_bluetoothDevice)
2407 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2408 g_obj_bluetoothDevice = NULL;
2411 // next data can be sent
2412 ca_mutex_lock(g_threadSendNotifyMutex);
2413 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
2414 g_isSignalSetFlag = true;
2415 ca_cond_signal(g_threadSendNotifyCond);
2416 ca_mutex_unlock(g_threadSendNotifyMutex);
2421 JNIEXPORT void JNICALL
2422 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(JNIEnv *env,
2424 jobject settingsInEffect)
2426 VERIFY_NON_NULL_VOID(env, TAG, "env");
2427 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2428 VERIFY_NON_NULL_VOID(settingsInEffect, TAG, "settingsInEffect");
2430 OIC_LOG(DEBUG, TAG, "LE Advertise Start Success Callback");
2433 JNIEXPORT void JNICALL
2434 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2438 VERIFY_NON_NULL_VOID(env, TAG, "env");
2439 VERIFY_NON_NULL_VOID(obj, TAG, "obj");
2441 OIC_LOG_V(INFO, TAG, "LE Advertise Start Failure Callback(%d)", errorCode);
2443 jint data_too_large = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2444 "ADVERTISE_FAILED_DATA_TOO_LARGE");
2445 jint already_started = CALEGetConstantsValue(env, CLASSPATH_BT_ADVERTISE_CB,
2446 "ADVERTISE_FAILED_ALREADY_STARTED");
2448 if (data_too_large == errorCode)
2450 OIC_LOG_V(ERROR, TAG, "advertise data too large. please check length of device name");
2452 else if (already_started == errorCode)
2454 OIC_LOG_V(INFO, TAG, "advertising is already started");
2462 CAResult_t CAStartLEGattServer()
2464 // start gatt service
2465 CALEServerStartMulticastServer();
2467 return CA_STATUS_OK;
2470 CAResult_t CAStopLEGattServer()
2472 OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
2476 OIC_LOG(ERROR, TAG, "g_jvm is null");
2477 return CA_STATUS_FAILED;
2480 bool isAttached = false;
2482 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2485 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2486 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2490 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2491 return CA_STATUS_FAILED;
2496 CAResult_t ret = CALEServerGattClose(env, g_bluetoothGattServer);
2497 if (CA_STATUS_OK != ret)
2499 OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2500 return CA_STATUS_FAILED;
2503 ret = CALEServerStopMulticastServer();
2504 if (CA_STATUS_OK != ret)
2506 OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
2507 return CA_STATUS_FAILED;
2510 ret = CALEServerDisconnectAllDevices(env);
2511 if (CA_STATUS_OK != ret)
2513 OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
2514 return CA_STATUS_FAILED;
2517 ret = CALEServerRemoveAllDevices(env);
2518 if (CA_STATUS_OK != ret)
2520 OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
2521 return CA_STATUS_FAILED;
2524 if (g_leAdvertiseCallback)
2526 (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
2529 if (g_bluetoothGattServer)
2531 (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
2534 if (g_bluetoothGattServerCallback)
2536 (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
2539 if (g_obj_bluetoothDevice)
2541 (*env)->DeleteGlobalRef(env, g_obj_bluetoothDevice);
2542 g_obj_bluetoothDevice = NULL;
2545 ca_mutex_lock(g_threadSendNotifyMutex);
2546 ca_cond_signal(g_threadSendNotifyCond);
2547 ca_mutex_unlock(g_threadSendNotifyMutex);
2549 g_isStartServer = false;
2553 (*g_jvm)->DetachCurrentThread(g_jvm);
2556 return CA_STATUS_OK;
2559 CAResult_t CAInitializeLEGattServer()
2561 OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
2562 return CALEServerInitialize();
2565 void CATerminateLEGattServer()
2567 OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
2568 CALEServerTerminate();
2571 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
2573 ca_mutex_lock(g_bleReqRespCbMutex);
2574 g_CABLEServerDataReceivedCallback = callback;
2575 ca_mutex_unlock(g_bleReqRespCbMutex);
2578 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2580 g_serverErrorCallback = callback;
2583 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
2584 const uint8_t *charValue,
2585 uint32_t charValueLen)
2587 CAResult_t result = CA_SEND_FAILED;
2588 VERIFY_NON_NULL(address, TAG, "env is null");
2589 VERIFY_NON_NULL(charValue, TAG, "device is null");
2593 result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2599 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
2600 uint32_t charValueLen)
2602 VERIFY_NON_NULL(charValue, TAG, "device is null");
2604 CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2609 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2611 OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
2615 CAResult_t CALEServerInitMutexVaraibles()
2617 if (NULL == g_bleReqRespCbMutex)
2619 g_bleReqRespCbMutex = ca_mutex_new();
2620 if (NULL == g_bleReqRespCbMutex)
2622 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2623 return CA_STATUS_FAILED;
2627 if (NULL == g_bleClientBDAddressMutex)
2629 g_bleClientBDAddressMutex = ca_mutex_new();
2630 if (NULL == g_bleClientBDAddressMutex)
2632 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2633 return CA_STATUS_FAILED;
2637 if (NULL == g_connectedDeviceListMutex)
2639 g_connectedDeviceListMutex = ca_mutex_new();
2640 if (NULL == g_connectedDeviceListMutex)
2642 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2643 return CA_STATUS_FAILED;
2647 if (NULL == g_threadSendMutex)
2649 g_threadSendMutex = ca_mutex_new();
2650 if (NULL == g_threadSendMutex)
2652 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2653 return CA_STATUS_FAILED;
2657 if (NULL == g_threadSendNotifyMutex)
2659 g_threadSendNotifyMutex = ca_mutex_new();
2660 if (NULL == g_threadSendNotifyMutex)
2662 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2663 return CA_STATUS_FAILED;
2667 return CA_STATUS_OK;
2670 void CALEServerTerminateMutexVaraibles()
2672 ca_mutex_free(g_bleReqRespCbMutex);
2673 g_bleReqRespCbMutex = NULL;
2675 ca_mutex_free(g_bleClientBDAddressMutex);
2676 g_bleClientBDAddressMutex = NULL;
2678 ca_mutex_free(g_connectedDeviceListMutex);
2679 g_connectedDeviceListMutex = NULL;
2681 ca_mutex_free(g_threadSendMutex);
2682 g_threadSendMutex = NULL;
2684 ca_mutex_free(g_threadSendNotifyMutex);
2685 g_threadSendNotifyMutex = NULL;
2688 void CALEServerTerminateConditionVaraibles()
2690 OIC_LOG(DEBUG, TAG, "this method is not supported");