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 ******************************************************************/
26 #include "calestate.h"
27 #include "caleclient.h"
28 #include "caleserver.h"
29 #include "caleutils.h"
30 #include "caleinterface.h"
31 #include "caadapterutils.h"
34 #include "oic_malloc.h"
35 #include "oic_string.h"
36 #include "cathreadpool.h" /* for thread pool */
38 #include "uarraylist.h"
39 #include "org_iotivity_ca_CaLeClientInterface.h"
41 //#define TAG PCF("OIC_CA_LE_CLIENT")
42 #define TAG BLE_CLIENT_TAG
44 #define MICROSECS_PER_SEC 1000000
45 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
46 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
47 #define WAIT_TIME_SCANNED_CHECKING 30
49 #define GATT_CONNECTION_PRIORITY_BALANCED 0
50 #define GATT_FAILURE 257
51 #define GATT_INSUFFICIENT_AUTHENTICATION 5
52 #define GATT_INSUFFICIENT_ENCRYPTION 15
53 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
54 #define GATT_INVALID_OFFSET 7
55 #define GATT_READ_NOT_PERMITTED 2
56 #define GATT_REQUEST_NOT_SUPPORTED 6
57 #define GATT_WRITE_NOT_PERMITTED 3
60 #define BLE_SCAN_API_LEVEL (100) //(21)
61 #define BLE_MIN_API_LEVEL (18)
64 static ca_thread_pool_t g_threadPoolHandle = NULL;
67 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
68 static u_arraylist_t *g_gattObjectList = NULL;
69 static u_arraylist_t *g_deviceStateList = NULL;
71 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
72 static CABLEErrorHandleCallback g_clientErrorCallback;
73 static jobject g_leScanCallback = NULL;
74 static jobject g_leGattCallback = NULL;
75 static jobject g_context = NULL;
76 static jobjectArray g_uuidList = NULL;
78 // it will be prevent to start send logic when adapter has stopped.
79 static bool g_isStartedLEClient = false;
81 static jbyteArray g_sendBuffer = NULL;
82 static uint32_t g_targetCnt = 0;
83 static uint32_t g_currentSentCnt = 0;
84 static bool g_isFinishedSendData = false;
85 static oc_mutex g_SendFinishMutex = NULL;
86 static oc_mutex g_threadMutex = NULL;
87 static oc_cond g_threadCond = NULL;
88 static oc_cond g_deviceDescCond = NULL;
90 static oc_mutex g_threadSendMutex = NULL;
91 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
92 static oc_cond g_threadWriteCharacteristicCond = NULL;
93 static bool g_isSignalSetFlag = false;
95 static oc_mutex g_bleServerBDAddressMutex = NULL;
97 static oc_mutex g_deviceListMutex = NULL;
98 static oc_mutex g_gattObjectMutex = NULL;
99 static oc_mutex g_deviceStateListMutex = NULL;
101 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
102 static oc_cond g_deviceScanRetryDelayCond = NULL;
104 static oc_mutex g_threadScanIntervalMutex = NULL;
105 static oc_cond g_threadScanIntervalCond = NULL;
107 static oc_mutex g_threadSendStateMutex = NULL;
108 static oc_mutex g_setValueMutex = NULL;
110 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
111 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
112 static int32_t g_intervalCount = 0;
113 static bool g_isWorkingScanThread = false;
114 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
115 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
117 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
118 static int32_t g_jniIntSdk = -1;
120 static bool g_setHighQoS = true;
121 static bool g_setFullScanFlag = true;
122 jclass g_LEInterface = NULL;
124 * check if retry logic for connection routine has to be stopped or not.
125 * in case of error value including this method, connection routine has to be stopped.
126 * since there is no retry logic for this error reason in this client.
127 * @param state constant value of bluetoothgatt.
128 * @return true - waiting for background connection in BT platform.
129 * false - connection routine has to be stopped.
131 static bool CALECheckConnectionStateValue(jint state)
135 case GATT_CONNECTION_PRIORITY_BALANCED:
137 case GATT_INSUFFICIENT_AUTHENTICATION:
138 case GATT_INSUFFICIENT_ENCRYPTION:
139 case GATT_INVALID_ATTRIBUTE_LENGTH:
140 case GATT_INVALID_OFFSET:
141 case GATT_READ_NOT_PERMITTED:
142 case GATT_REQUEST_NOT_SUPPORTED:
143 case GATT_WRITE_NOT_PERMITTED:
151 * delete global reference for g_sendBuffer
152 * @param[in] env JNI interface pointer.
154 static void CALEDeleteSendBuffer(JNIEnv *env)
156 OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
157 oc_mutex_lock(g_setValueMutex);
160 OIC_LOG(INFO, TAG, "delete send buffer");
161 (*env)->DeleteGlobalRef(env, g_sendBuffer);
164 oc_mutex_unlock(g_setValueMutex);
167 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
168 CALEScanState_t nextScanningStep)
170 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
171 g_scanIntervalTime, intervalTime, nextScanningStep);
173 // previous time should be stored.
174 if (0 < workingCount)
176 g_scanIntervalTimePrev = g_scanIntervalTime;
178 g_scanIntervalTime = intervalTime;
179 g_intervalCount = workingCount;
180 g_nextScanningStep = nextScanningStep;
183 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
184 CALEScanState_t nextScanningStep)
186 if (intervalTime == g_scanIntervalTime
187 && workingCount == g_intervalCount
188 && nextScanningStep == g_nextScanningStep)
190 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
194 oc_mutex_lock(g_threadScanIntervalMutex);
195 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
196 oc_cond_signal(g_threadScanIntervalCond);
197 oc_mutex_unlock(g_threadScanIntervalMutex);
200 static void CALEScanThread(void* object)
204 bool isAttached = false;
206 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
209 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
213 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
219 oc_mutex_lock(g_threadScanIntervalMutex);
220 while(g_isWorkingScanThread)
222 OIC_LOG(DEBUG, TAG, "scan waiting time out");
223 if (BLE_SCAN_ENABLE == g_curScanningStep)
226 CAResult_t ret = CALEClientStopScan();
227 if (CA_STATUS_OK != ret)
229 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
232 else if (BLE_SCAN_DISABLE == g_curScanningStep)
235 CAResult_t ret = CALEClientStartScan();
236 if (CA_STATUS_OK != ret)
238 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
243 OIC_LOG(DEBUG, TAG, "scan thread is started");
245 CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
248 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
249 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
250 g_threadScanIntervalMutex,
251 g_scanIntervalTime * MICROSECS_PER_SEC))
253 // called signal scan thread will be terminated
254 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
255 if (BLE_SCAN_DISABLE == g_nextScanningStep)
257 g_curScanningStep = BLE_SCAN_ENABLE;
261 g_curScanningStep = BLE_SCAN_DISABLE;
266 if (BLE_SCAN_ENABLE == g_curScanningStep)
268 if (g_intervalCount > 0)
270 if (g_intervalCount == 1)
272 OIC_LOG(DEBUG, TAG, "reset default time");
273 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
276 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
278 g_curScanningStep = BLE_SCAN_DISABLE;
282 g_curScanningStep = BLE_SCAN_ENABLE;
286 oc_mutex_unlock(g_threadScanIntervalMutex);
290 (*g_jvm)->DetachCurrentThread(g_jvm);
294 CAResult_t CALEClientStartScanWithInterval()
296 if (g_isWorkingScanThread)
298 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
302 // initialize scan flags
303 g_curScanningStep = BLE_SCAN_NONE;
304 g_isWorkingScanThread = true;
306 g_scanIntervalTime = g_scanIntervalTimePrev;
307 g_nextScanningStep = BLE_SCAN_ENABLE;
309 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
311 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
312 g_isWorkingScanThread = false;
313 return CA_STATUS_FAILED;
319 void CALEClientStopScanWithInterval()
321 g_isWorkingScanThread = false;
322 oc_cond_signal(g_threadScanIntervalCond);
326 void CALEClientJniInit()
328 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
329 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
332 void CALEClientJNISetContext()
334 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
335 g_context = (jobject) CANativeJNIGetContext();
338 CAResult_t CALECreateJniInterfaceObject()
340 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
344 OIC_LOG(ERROR, TAG, "g_context is null");
345 return CA_STATUS_FAILED;
350 OIC_LOG(ERROR, TAG, "g_jvm is null");
351 return CA_STATUS_FAILED;
354 bool isAttached = false;
356 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
359 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
363 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
364 return CA_STATUS_FAILED;
369 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
370 "getApplicationContext",
371 "()Landroid/content/Context;");
373 if (!mid_getApplicationContext)
375 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
376 return CA_STATUS_FAILED;
379 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
380 mid_getApplicationContext);
381 if (!jApplicationContext)
383 OIC_LOG(ERROR, TAG, "Could not get application context");
387 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
388 if (!jni_LEInterface)
390 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
393 g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
395 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
396 "(Landroid/content/Context;)V");
397 if (!LeInterfaceConstructorMethod)
399 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
403 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
404 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
408 (*g_jvm)->DetachCurrentThread(g_jvm);
414 CACheckJNIException(env);
417 (*g_jvm)->DetachCurrentThread(g_jvm);
420 return CA_STATUS_FAILED;
423 CAResult_t CALEClientInitialize()
425 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
431 OIC_LOG(ERROR, TAG, "g_jvm is null");
432 return CA_STATUS_FAILED;
435 bool isAttached = false;
437 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
440 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
444 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
445 return CA_STATUS_FAILED;
450 g_jniIntSdk = CALEGetBuildVersion(env);
451 if (g_jniIntSdk < BLE_MIN_API_LEVEL)
453 OIC_LOG(ERROR, TAG, "it is not supported");
457 (*g_jvm)->DetachCurrentThread(g_jvm);
459 return CA_STATUS_FAILED;
462 CAResult_t ret = CALEClientInitGattMutexVaraibles();
463 if (CA_STATUS_OK != ret)
465 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
466 CALEClientTerminateGattMutexVariables();
470 (*g_jvm)->DetachCurrentThread(g_jvm);
476 g_deviceDescCond = oc_cond_new();
478 // init mutex for send logic
479 g_threadCond = oc_cond_new();
480 g_threadWriteCharacteristicCond = oc_cond_new();
481 g_deviceScanRetryDelayCond = oc_cond_new();
482 g_threadScanIntervalCond = oc_cond_new();
484 CALEClientCreateDeviceList();
485 CALEClientJNISetContext();
487 ret = CALEClientCreateUUIDList();
488 if (CA_STATUS_OK != ret)
490 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
494 (*g_jvm)->DetachCurrentThread(g_jvm);
500 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
501 if (CA_STATUS_OK != ret)
503 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
507 (*g_jvm)->DetachCurrentThread(g_jvm);
512 g_isStartedLEClient = true;
516 (*g_jvm)->DetachCurrentThread(g_jvm);
522 void CALEClientTerminate()
524 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
528 OIC_LOG(ERROR, TAG, "g_jvm is null");
532 bool isAttached = false;
534 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
537 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
541 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
548 CAResult_t ret = CALEClientStopScan();
549 if (CA_STATUS_OK != ret)
551 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
554 if (g_leScanCallback)
556 (*env)->DeleteGlobalRef(env, g_leScanCallback);
557 g_leScanCallback = NULL;
560 if (g_leGattCallback)
562 (*env)->DeleteGlobalRef(env, g_leGattCallback);
563 g_leGattCallback = NULL;
568 (*env)->DeleteGlobalRef(env, g_LEInterface);
569 g_LEInterface = NULL;
572 CALEDeleteSendBuffer(env);
576 (*env)->DeleteGlobalRef(env, g_uuidList);
580 ret = CALERemoveAllDeviceState(g_deviceStateList,
581 g_deviceStateListMutex);
582 if (CA_STATUS_OK != ret)
584 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
587 oc_mutex_lock(g_deviceStateListMutex);
588 OICFree(g_deviceStateList);
589 g_deviceStateList = NULL;
590 oc_mutex_unlock(g_deviceStateListMutex);
592 ret = CALEClientRemoveAllScanDevices(env);
593 if (CA_STATUS_OK != ret)
595 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
598 ret = CALEClientRemoveAllGattObjs(env);
599 if (CA_STATUS_OK != ret)
601 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
604 CALEClientSetSendFinishFlag(true);
606 CALEClientTerminateGattMutexVariables();
607 CALEClientDestroyJniInterface();
609 oc_cond_free(g_deviceDescCond);
610 oc_cond_free(g_threadCond);
611 oc_cond_free(g_threadWriteCharacteristicCond);
612 oc_cond_free(g_deviceScanRetryDelayCond);
613 oc_cond_free(g_threadScanIntervalCond);
615 g_deviceDescCond = NULL;
617 g_threadWriteCharacteristicCond = NULL;
618 g_deviceScanRetryDelayCond = NULL;
619 g_threadScanIntervalCond = NULL;
621 g_isSignalSetFlag = false;
624 CALEClientStopScanWithInterval();
628 (*g_jvm)->DetachCurrentThread(g_jvm);
632 jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
634 OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
638 OIC_LOG(ERROR, TAG, "g_jvm is null");
642 bool isAttached = false;
644 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
647 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
651 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
657 jstring jni_address = (*env)->NewStringUTF(env, address);
658 jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
659 "connectGattforHidden",
660 "(Landroid/bluetooth/BluetoothDevice;"
661 "Ljava/lang/String;Z)"
662 "Landroid/bluetooth/BluetoothGatt;");
663 if (!jni_connectGattHiddenMethod)
665 OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
669 jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
670 jni_connectGattHiddenMethod,
671 btDevice, jni_address, autoconnect);
673 if (CACheckJNIException(env))
675 OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
679 OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
683 (*g_jvm)->DetachCurrentThread(g_jvm);
689 CACheckJNIException(env);
694 (*g_jvm)->DetachCurrentThread(g_jvm);
700 CAResult_t CALEClientDestroyJniInterface()
702 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
706 OIC_LOG(ERROR, TAG, "g_jvm is null");
707 return CA_STATUS_FAILED;
710 bool isAttached = false;
712 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
715 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
719 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
720 return CA_STATUS_FAILED;
725 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
726 if (!jni_LeInterface)
728 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
732 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
733 "destroyLeInterface",
735 if (!jni_InterfaceDestroyMethod)
737 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
741 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
743 if (CACheckJNIException(env))
745 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
749 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
753 (*g_jvm)->DetachCurrentThread(g_jvm);
759 CACheckJNIException(env);
764 (*g_jvm)->DetachCurrentThread(g_jvm);
767 return CA_STATUS_FAILED;
770 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
772 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
773 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
777 CAResult_t res = CALEClientDisconnect(env, gatt);
778 if (CA_STATUS_OK != res)
780 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
783 CALEClientUpdateSendCnt(env);
786 CAResult_t CALEClientSendNegotiationMessage(const char* address)
788 VERIFY_NON_NULL(address, TAG, "address is null");
790 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
793 CAResult_t CALEClientSendUnicastMessage(const char* address,
795 const uint32_t dataLen)
797 VERIFY_NON_NULL(address, TAG, "address is null");
798 VERIFY_NON_NULL(data, TAG, "data is null");
800 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
803 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
804 const uint32_t dataLen)
806 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
807 VERIFY_NON_NULL(data, TAG, "data is null");
811 OIC_LOG(ERROR, TAG, "g_jvm is null");
812 return CA_STATUS_FAILED;
815 bool isAttached = false;
817 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
820 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
824 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
825 return CA_STATUS_FAILED;
830 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
831 if (CA_STATUS_OK != ret)
833 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
838 (*g_jvm)->DetachCurrentThread(g_jvm);
844 CAResult_t CALEClientStartUnicastServer(const char* address)
849 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
851 return CA_NOT_SUPPORTED;
854 CAResult_t CALEClientStartMulticastServer()
856 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
858 return CA_NOT_SUPPORTED;
861 void CALEClientStopUnicastServer()
863 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
866 void CALEClientStopMulticastServer()
868 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
871 void CALEClientSetCallback(CAPacketReceiveCallback callback)
873 g_packetReceiveCallback = callback;
876 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
878 g_clientErrorCallback = callback;
881 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
883 VERIFY_NON_NULL(env, TAG, "env");
887 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
888 return CA_STATUS_FAILED;
891 if (0 == u_arraylist_length(g_deviceList) // multicast
892 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
894 // Wait for LE peripherals to be discovered.
896 // Number of times to wait for discovery to complete.
897 static size_t const RETRIES = 5;
899 static uint64_t const TIMEOUT =
900 2 * MICROSECS_PER_SEC; // Microseconds
902 // set scan interval and start scan
903 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
905 bool devicesDiscovered = false;
906 for (size_t i = 0; i < RETRIES; ++i)
908 OIC_LOG(DEBUG, TAG, "waiting for target device");
909 if (oc_cond_wait_for(g_deviceDescCond,
911 TIMEOUT) == OC_WAIT_SUCCESS)
913 OIC_LOG(DEBUG, TAG, "time out");
914 oc_mutex_lock(g_deviceListMutex);
915 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
916 oc_mutex_unlock(g_deviceListMutex);
918 if (0 < scannedDeviceLen)
920 if (!address // multicast
921 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
923 devicesDiscovered = true;
930 OIC_LOG(INFO, TAG, "waiting..");
932 oc_mutex_lock(g_deviceScanRetryDelayMutex);
933 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
934 g_deviceScanRetryDelayMutex,
935 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
937 OIC_LOG(INFO, TAG, "finish to waiting for target device");
938 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
941 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
944 // checking whether a target device is found while waiting for time-out.
945 if (CALEClientIsDeviceInScanDeviceList(env, address))
947 devicesDiscovered = true;
956 // reset scan interval time after checking scanned devices
957 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
959 // time out for scanning devices
960 if (!devicesDiscovered)
962 return CA_STATUS_FAILED;
967 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
974 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
975 const uint32_t dataLen)
977 OIC_LOG(INFO, TAG, "CALEClientSendUnicastMessageImpl in");
978 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
980 VERIFY_NON_NULL(address, TAG, "address is null");
984 OIC_LOG(ERROR, TAG, "g_jvm is null");
985 return CA_STATUS_FAILED;
988 bool isAttached = false;
990 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
993 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
996 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
997 return CA_STATUS_FAILED;
1002 oc_mutex_lock(g_threadSendMutex);
1004 CALEClientSetSendFinishFlag(false);
1006 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
1007 if (CA_STATUS_OK != ret)
1009 OIC_LOG(INFO, TAG, "there is no scanned device");
1013 if (g_context && g_deviceList)
1015 uint32_t length = u_arraylist_length(g_deviceList);
1016 for (uint32_t index = 0; index < length; index++)
1018 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1021 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1025 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1026 if (!jni_setAddress)
1028 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1032 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1035 OIC_LOG(ERROR, TAG, "setAddress is null");
1036 CACheckJNIException(env);
1040 if (!strcasecmp(setAddress, address))
1042 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1043 (*env)->DeleteLocalRef(env, jni_setAddress);
1045 CALEDeleteSendBuffer(env);
1047 if (data && dataLen > 0)
1049 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1050 CACheckJNIException(env);
1051 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1052 CACheckJNIException(env);
1053 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1054 CACheckJNIException(env);
1057 // Target device to send message is just one.
1060 ret = CALEClientSendData(env, jarrayObj);
1061 if (CA_STATUS_OK != ret)
1063 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1067 OIC_LOG(INFO, TAG, "wake up");
1070 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1071 (*env)->DeleteLocalRef(env, jni_setAddress);
1075 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1077 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1078 // if there is no connection state.
1079 oc_mutex_lock(g_threadMutex);
1080 if (!g_isFinishedSendData)
1082 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1083 oc_cond_wait(g_threadCond, g_threadMutex);
1084 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
1086 oc_mutex_unlock(g_threadMutex);
1090 (*g_jvm)->DetachCurrentThread(g_jvm);
1093 oc_mutex_unlock(g_threadSendMutex);
1094 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1095 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1098 g_deviceStateListMutex))
1100 OIC_LOG(INFO, TAG, "send success");
1103 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1104 STATE_SEND_MTU_NEGO_SUCCESS,
1106 g_deviceStateListMutex))
1108 OIC_LOG(INFO, TAG, "mtu nego success");
1113 OIC_LOG(ERROR, TAG, "send failure");
1114 ret = CA_SEND_FAILED;
1118 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1121 g_deviceStateListMutex);
1122 if (CA_STATUS_OK != resetRet)
1124 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1125 ret = CA_SEND_FAILED;
1134 (*g_jvm)->DetachCurrentThread(g_jvm);
1137 oc_mutex_unlock(g_threadSendMutex);
1138 return CA_SEND_FAILED;
1141 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1142 const uint32_t dataLen)
1144 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1145 VERIFY_NON_NULL(data, TAG, "data is null");
1146 VERIFY_NON_NULL(env, TAG, "env is null");
1150 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1151 return CA_STATUS_FAILED;
1154 oc_mutex_lock(g_threadSendMutex);
1156 CALEClientSetSendFinishFlag(false);
1158 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1159 CALEDeleteSendBuffer(env);
1161 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1162 if (CA_STATUS_OK != res)
1164 OIC_LOG(INFO, TAG, "there is no scanned device");
1168 uint32_t length = u_arraylist_length(g_deviceList);
1169 g_targetCnt = length;
1171 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1172 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1173 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1175 for (uint32_t index = 0; index < length; index++)
1177 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1180 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1184 res = CALEClientSendData(env, jarrayObj);
1185 if (res != CA_STATUS_OK)
1187 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1191 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1193 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1194 oc_mutex_lock(g_threadMutex);
1195 if (!g_isFinishedSendData)
1197 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1198 oc_cond_wait(g_threadCond, g_threadMutex);
1199 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1201 oc_mutex_unlock(g_threadMutex);
1202 oc_mutex_unlock(g_threadSendMutex);
1203 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1204 return CA_STATUS_OK;
1207 oc_mutex_unlock(g_threadSendMutex);
1208 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1209 return CA_SEND_FAILED;
1212 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1214 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1215 VERIFY_NON_NULL(device, TAG, "device is null");
1216 VERIFY_NON_NULL(env, TAG, "env is null");
1218 // get BLE address from bluetooth device object.
1219 char* address = NULL;
1220 CALEState_t* state = NULL;
1221 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1224 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1225 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1228 OIC_LOG(ERROR, TAG, "address is not available");
1229 CACheckJNIException(env);
1230 return CA_STATUS_FAILED;
1232 oc_mutex_lock(g_deviceStateListMutex);
1233 state = CALEGetStateInfo(address, g_deviceStateList);
1234 oc_mutex_unlock(g_deviceStateListMutex);
1237 // Since disconnect event can be caused from BT stack while connection step is running.
1238 // DeviceState has to have current status for processing send failure.
1239 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1240 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1242 STATE_SEND_PREPARING);
1243 if (CA_STATUS_OK != res)
1245 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1248 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1250 return CA_STATUS_FAILED;
1255 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1257 // cancel previous connection request before connection
1258 // if there is gatt object in g_gattObjectList.
1261 jobject gatt = CALEClientGetGattObjInList(env, address);
1264 CAResult_t res = CALEClientDisconnect(env, gatt);
1265 if (CA_STATUS_OK != res)
1267 OIC_LOG(INFO, TAG, "there is no gatt object");
1270 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1273 // connection request
1274 jobject newGatt = CALEClientConnect(env, device,
1276 if (NULL == newGatt)
1278 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1279 return CA_STATUS_FAILED;
1284 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1285 STATE_SERVICE_CONNECTED,
1287 g_deviceStateListMutex))
1289 OIC_LOG(INFO, TAG, "GATT has already connected");
1291 jobject gatt = CALEClientGetGattObjInList(env, address);
1294 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1295 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1296 return CA_STATUS_FAILED;
1299 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1300 if (CA_STATUS_OK != ret)
1302 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1303 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1306 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1308 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1311 g_deviceStateListMutex))
1313 OIC_LOG(INFO, TAG, "service connecting...");
1315 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1318 g_deviceStateListMutex))
1320 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1322 // cancel previous connection request before connection
1323 // if there is gatt object in g_gattObjectList.
1326 jobject gatt = CALEClientGetGattObjInList(env, address);
1329 CAResult_t res = CALEClientDisconnect(env, gatt);
1330 if (CA_STATUS_OK != res)
1332 OIC_LOG(INFO, TAG, "there is no gatt object");
1335 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1338 OIC_LOG(DEBUG, TAG, "start to connect LE");
1339 jobject gatt = CALEClientConnect(env, device,
1340 CALEGetFlagFromState(env, jni_address,
1341 CA_LE_AUTO_CONNECT_FLAG,
1343 g_deviceStateListMutex));
1347 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1348 return CA_STATUS_FAILED;
1353 return CA_STATUS_OK;
1356 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1358 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1359 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1361 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1362 "()Landroid/bluetooth/BluetoothDevice;");
1363 if (!jni_mid_getDevice)
1365 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1369 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1370 if (!jni_obj_device)
1372 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1373 CACheckJNIException(env);
1377 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1380 OIC_LOG(ERROR, TAG, "jni_address is null");
1381 CACheckJNIException(env);
1391 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1394 OIC_LOG(DEBUG, TAG, "Gatt Close");
1395 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1396 VERIFY_NON_NULL(env, TAG, "env is null");
1398 // get BluetoothGatt method
1399 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1400 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1401 if (!jni_mid_closeGatt)
1403 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1404 return CA_STATUS_OK;
1407 // call disconnect gatt method
1408 OIC_LOG(DEBUG, TAG, "request to close GATT");
1409 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1411 if (CACheckJNIException(env))
1413 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1414 return CA_STATUS_FAILED;
1417 return CA_STATUS_OK;
1420 CAResult_t CALEClientStartScan()
1422 if (!g_isStartedLEClient)
1424 OIC_LOG(ERROR, TAG, "LE client is not started");
1425 return CA_STATUS_FAILED;
1430 OIC_LOG(ERROR, TAG, "g_jvm is null");
1431 return CA_STATUS_FAILED;
1434 bool isAttached = false;
1436 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1439 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1442 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1443 return CA_STATUS_FAILED;
1448 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1450 CAResult_t ret = CA_STATUS_OK;
1451 // scan gatt server with UUID
1452 if (g_leScanCallback && g_uuidList)
1454 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
1456 if (!g_setFullScanFlag)
1458 //new uuid scan with callback
1459 ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
1463 //new full scan with callback
1464 ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
1469 if (!g_setFullScanFlag)
1471 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1475 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1479 if (CA_STATUS_OK != ret)
1481 if (CA_ADAPTER_NOT_ENABLED == ret)
1483 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1487 OIC_LOG(ERROR, TAG, "start scan has failed");
1494 (*g_jvm)->DetachCurrentThread(g_jvm);
1500 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1502 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
1503 VERIFY_NON_NULL(callback, TAG, "callback is null");
1504 VERIFY_NON_NULL(env, TAG, "env is null");
1506 if (!CALEIsEnableBTAdapter(env))
1508 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1509 return CA_ADAPTER_NOT_ENABLED;
1512 // get default bt adapter class
1513 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1514 if (!jni_cid_BTAdapter)
1516 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1517 CACheckJNIException(env);
1518 return CA_STATUS_FAILED;
1521 // get remote bt adapter method
1522 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1523 "getDefaultAdapter",
1524 METHODID_OBJECTNONPARAM);
1525 if (!jni_mid_getDefaultAdapter)
1527 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1528 CACheckJNIException(env);
1529 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1530 return CA_STATUS_FAILED;
1533 // get start le scan method
1534 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1535 "(Landroid/bluetooth/BluetoothAdapter$"
1536 "LeScanCallback;)Z");
1537 if (!jni_mid_startLeScan)
1539 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1540 CACheckJNIException(env);
1541 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1542 return CA_STATUS_FAILED;
1545 // gat bt adapter object
1546 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1547 jni_mid_getDefaultAdapter);
1548 if (!jni_obj_BTAdapter)
1550 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1551 CACheckJNIException(env);
1552 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1553 return CA_STATUS_FAILED;
1556 // call start le scan method
1557 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1558 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1559 jni_mid_startLeScan, callback);
1560 if (!jni_obj_startLeScan)
1562 OIC_LOG(INFO, TAG, "startLeScan has failed");
1563 CACheckJNIException(env);
1567 OIC_LOG(DEBUG, TAG, "LeScan has started");
1570 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1571 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1572 return CA_STATUS_OK;
1575 CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
1577 OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
1578 VERIFY_NON_NULL(callback, TAG, "callback is null");
1579 VERIFY_NON_NULL(env, TAG, "env is null");
1581 if (!CALEIsEnableBTAdapter(env))
1583 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1584 return CA_ADAPTER_NOT_ENABLED;
1587 CAResult_t res = CA_STATUS_FAILED;
1588 // get default bt adapter class
1589 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1590 if (!jni_cid_BTAdapter)
1592 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1593 CACheckJNIException(env);
1594 return CA_STATUS_FAILED;
1597 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1598 "getDefaultAdapter",
1599 "()Landroid/bluetooth/"
1600 "BluetoothAdapter;");
1601 if (!jni_mid_getDefaultAdapter)
1603 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1604 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1605 return CA_STATUS_FAILED;
1608 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1609 jni_mid_getDefaultAdapter);
1610 if (!jni_obj_BTAdapter)
1612 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1613 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1614 return CA_STATUS_FAILED;
1617 // get bluetoothLeScanner class
1618 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1619 if (!jni_cid_leScanner)
1621 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1622 CACheckJNIException(env);
1623 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1624 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1625 return CA_STATUS_FAILED;
1628 // get remote bt adapter method
1629 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1630 "getBluetoothLeScanner",
1631 "()Landroid/bluetooth/"
1632 "le/BluetoothLeScanner;");
1633 if (!jni_mid_getBluetoothLeScanner)
1635 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
1636 CACheckJNIException(env);
1640 // get startScan(ScanCallback callback) method
1641 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
1642 "(Landroid/bluetooth/le/ScanCallback;)V");
1643 if (!jni_mid_startScan)
1645 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1646 CACheckJNIException(env);
1650 // gat le scanner object
1651 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
1652 jni_mid_getBluetoothLeScanner);
1653 if (!jni_obj_leScanner)
1655 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
1656 CACheckJNIException(env);
1660 // call startScan method
1661 OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
1662 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
1663 if (CACheckJNIException(env))
1665 OIC_LOG(INFO, TAG, "startScan has failed");
1666 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1670 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
1673 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1674 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1675 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1679 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1681 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
1682 VERIFY_NON_NULL(callback, TAG, "callback is null");
1683 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1684 VERIFY_NON_NULL(env, TAG, "env is null");
1686 if (!CALEIsEnableBTAdapter(env))
1688 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1689 return CA_ADAPTER_NOT_ENABLED;
1692 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1693 if (!jni_cid_BTAdapter)
1695 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1696 CACheckJNIException(env);
1697 return CA_STATUS_FAILED;
1700 // get remote bt adapter method
1701 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1702 "getDefaultAdapter",
1703 METHODID_OBJECTNONPARAM);
1704 if (!jni_mid_getDefaultAdapter)
1706 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1707 CACheckJNIException(env);
1708 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1709 return CA_STATUS_FAILED;
1712 // get start le scan method
1713 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1714 "([Ljava/util/UUID;Landroid/bluetooth/"
1715 "BluetoothAdapter$LeScanCallback;)Z");
1716 if (!jni_mid_startLeScan)
1718 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1719 CACheckJNIException(env);
1720 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1721 return CA_STATUS_FAILED;
1724 // get bt adapter object
1725 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1726 jni_mid_getDefaultAdapter);
1727 if (!jni_obj_BTAdapter)
1729 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1730 CACheckJNIException(env);
1731 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1732 return CA_STATUS_FAILED;
1735 // call start le scan method
1736 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1737 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1738 jni_mid_startLeScan, uuids, callback);
1739 if (!jni_obj_startLeScan)
1741 OIC_LOG(INFO, TAG, "startLeScan has failed");
1742 CACheckJNIException(env);
1746 OIC_LOG(DEBUG, TAG, "LeScan has started");
1749 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1750 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1751 return CA_STATUS_OK;
1754 CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
1756 OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
1757 VERIFY_NON_NULL(callback, TAG, "callback is null");
1758 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1759 VERIFY_NON_NULL(env, TAG, "env is null");
1761 if (!CALEIsEnableBTAdapter(env))
1763 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1764 return CA_ADAPTER_NOT_ENABLED;
1767 // get bluetoothLeScanner class
1768 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
1769 if (!jni_cid_leScanner)
1771 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
1772 CACheckJNIException(env);
1773 return CA_STATUS_FAILED;
1776 // get startScan(with UUID) method
1777 jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
1780 "Landroid/bluetooth/le/ScanSettings;"
1781 "Landroid/bluetooth/le/ScanCallback;"
1783 if (!jni_mid_startScan)
1785 OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
1786 CACheckJNIException(env);
1787 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1788 return CA_STATUS_FAILED;
1790 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
1792 // get scanfilter.Builder class id
1793 jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
1794 "android/bluetooth/le/"
1795 "ScanFilter$Builder");
1796 if (!jni_cid_scanfilterBuilder)
1798 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
1799 CACheckJNIException(env);
1800 return CA_STATUS_FAILED;
1803 // get scanfilter.Builder(ctor) method id
1804 jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1806 if (!jni_mid_scanfilterBuilderCtor)
1808 OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
1809 CACheckJNIException(env);
1810 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1811 return CA_STATUS_FAILED;
1814 // call scanfilter.Builder()
1815 jobject jni_obj_scanfilterBuilder = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
1816 jni_mid_scanfilterBuilderCtor);
1817 if (!jni_obj_scanfilterBuilder)
1819 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder is null");
1820 CACheckJNIException(env);
1821 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1822 return CA_STATUS_FAILED;
1825 // get scanfilter.Builder.setServiceUuid method id
1826 jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
1828 "(Landroid/os/ParcelUuid;)Landroid/"
1829 "bluetooth/le/ScanFilter$Builder;");
1830 if (!jni_mid_setServiceUuid)
1832 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
1833 CACheckJNIException(env);
1834 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1835 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1836 return CA_STATUS_FAILED;
1839 // get scanfilter.Builder.build method id
1840 jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
1841 jni_cid_scanfilterBuilder,
1843 "()Landroid/bluetooth/le/"
1845 if (!jni_mid_build_scanfilterBuilder)
1847 OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
1848 CACheckJNIException(env);
1849 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1850 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1851 return CA_STATUS_FAILED;
1853 (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
1855 // call ParcelUuid.fromSting(uuid)
1856 jobject jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, OIC_GATT_SERVICE_UUID);
1857 if (!jni_obj_parcelUuid)
1859 OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
1860 CACheckJNIException(env);
1861 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1862 return CA_STATUS_FAILED;
1865 // call setServiceUuid(uuid)
1866 jobject jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
1867 jni_obj_scanfilterBuilder,
1868 jni_mid_setServiceUuid,
1869 jni_obj_parcelUuid);
1870 if (!jni_obj_setServiceUuid)
1872 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
1873 CACheckJNIException(env);
1874 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1875 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1876 return CA_STATUS_FAILED;
1878 (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
1879 (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
1882 jobject jni_obj_scanfilter = (*env)->CallObjectMethod(env,
1883 jni_obj_scanfilterBuilder,
1884 jni_mid_build_scanfilterBuilder);
1885 if (!jni_obj_scanfilter)
1887 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter is null");
1888 CACheckJNIException(env);
1889 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1890 return CA_STATUS_FAILED;
1892 (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
1894 // get scanSettings.Builder class id
1895 jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
1896 "android/bluetooth/le/"
1897 "ScanSettings$Builder");
1898 if (!jni_cid_scanSettingsBuilder)
1900 OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
1901 CACheckJNIException(env);
1902 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1903 return CA_STATUS_FAILED;
1906 // get scanSettings.Builder(ctor) method id
1907 jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
1909 if (!jni_mid_scanSettingsBuilderCtor)
1911 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
1912 CACheckJNIException(env);
1913 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1914 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1915 return CA_STATUS_FAILED;
1918 // get scanSettings.Builder.setScanMode method id
1919 jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
1922 "bluetooth/le/ScanSettings$Builder;");
1923 if (!jni_mid_setScanMode)
1925 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
1926 CACheckJNIException(env);
1927 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1928 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1929 return CA_STATUS_FAILED;
1932 // get scanSettings.Builder.build method id
1933 jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
1934 jni_cid_scanSettingsBuilder,
1936 "()Landroid/bluetooth/le/"
1938 if (!jni_mid_build_scanSettings)
1940 OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
1941 CACheckJNIException(env);
1942 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1943 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1944 return CA_STATUS_FAILED;
1947 // call scanSettings.Builder()
1948 jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
1949 jni_mid_scanSettingsBuilderCtor);
1950 if (!jni_obj_scanSettingBuilder)
1952 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
1953 CACheckJNIException(env);
1954 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1955 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1956 return CA_STATUS_FAILED;
1958 (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
1960 jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
1961 if (!jni_cid_arrayList)
1963 OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
1964 CACheckJNIException(env);
1965 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1966 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
1967 return CA_STATUS_FAILED;
1970 jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
1971 if (!jni_mid_arrayListCtor)
1973 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
1974 CACheckJNIException(env);
1975 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1976 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
1977 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
1978 return CA_STATUS_FAILED;
1981 jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
1982 "add", "(Ljava/lang/Object;)Z");
1983 if (!jni_mid_arrayListAdd)
1985 OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
1986 CACheckJNIException(env);
1987 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1988 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
1989 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
1990 return CA_STATUS_FAILED;
1993 jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
1994 if (!jni_obj_filterList)
1996 OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
1997 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
1998 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
1999 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2000 return CA_STATUS_FAILED;
2002 (*env)->DeleteLocalRef(env, jni_cid_arrayList);
2004 jboolean jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
2005 jni_mid_arrayListAdd,
2006 jni_obj_scanfilter);
2007 if (!jni_bool_arrayListIsAdded)
2009 OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
2010 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2011 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2012 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2013 return CA_STATUS_FAILED;
2015 (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
2017 // get ScanSettings.SCAN_MODE_BALANCED jint value
2018 jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
2019 "SCAN_MODE_BALANCED");
2020 CACheckJNIException(env);
2022 // call setScanMode(SCAN_MODE_BALANCED)
2023 jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2024 jni_mid_setScanMode,
2025 jni_int_scanBalancedMode);
2026 if (!jni_obj_setScanMode)
2028 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
2029 CACheckJNIException(env);
2030 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2031 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2032 return CA_STATUS_FAILED;
2036 jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
2037 jni_mid_build_scanSettings);
2038 if (!jni_obj_scanSettings)
2040 OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
2041 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2042 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2043 return CA_STATUS_FAILED;
2045 (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
2047 CAResult_t res = CA_STATUS_FAILED;
2048 // get default bt adapter class
2049 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2050 if (!jni_cid_BTAdapter)
2052 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2053 CACheckJNIException(env);
2057 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2058 "getDefaultAdapter",
2059 "()Landroid/bluetooth/"
2060 "BluetoothAdapter;");
2061 if (!jni_mid_getDefaultAdapter)
2063 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2064 CACheckJNIException(env);
2065 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2069 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2070 jni_mid_getDefaultAdapter);
2071 if (!jni_obj_BTAdapter)
2073 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2074 CACheckJNIException(env);
2075 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2079 // get remote bt adapter method
2080 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2081 "getBluetoothLeScanner",
2082 "()Landroid/bluetooth/"
2083 "le/BluetoothLeScanner;");
2084 if (!jni_mid_getBluetoothLeScanner)
2086 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2087 CACheckJNIException(env);
2088 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2089 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2093 // get le scanner object
2094 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2095 jni_mid_getBluetoothLeScanner);
2096 if (!jni_obj_leScanner)
2098 OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
2099 CACheckJNIException(env);
2100 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2101 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2104 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2105 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2107 // call startScan method
2108 OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
2109 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
2110 jni_obj_scanSettings, callback);
2111 if (CACheckJNIException(env))
2113 OIC_LOG(INFO, TAG, "startScan has failed");
2119 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2122 (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
2123 (*env)->DeleteLocalRef(env, jni_obj_filterList);
2127 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
2129 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
2130 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2133 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2136 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
2140 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
2141 "(Ljava/lang/String;)"
2142 "Ljava/util/UUID;");
2143 if (!jni_mid_fromString)
2145 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
2149 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
2150 CACheckJNIException(env);
2151 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
2155 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2159 return jni_obj_uuid;
2162 CACheckJNIException(env);
2166 CAResult_t CALEClientStopScan()
2170 OIC_LOG(ERROR, TAG, "g_jvm is null");
2171 return CA_STATUS_FAILED;
2174 bool isAttached = false;
2176 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2179 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2182 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2183 return CA_STATUS_FAILED;
2188 CAResult_t ret = CA_STATUS_FAILED;
2190 if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
2192 ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
2196 ret = CALEClientStopScanImpl(env, g_leScanCallback);
2199 if (CA_STATUS_OK != ret)
2201 if (CA_ADAPTER_NOT_ENABLED == ret)
2203 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
2207 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
2213 (*g_jvm)->DetachCurrentThread(g_jvm);
2219 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
2221 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
2222 VERIFY_NON_NULL(callback, TAG, "callback is null");
2223 VERIFY_NON_NULL(env, TAG, "env is null");
2225 if (!CALEIsEnableBTAdapter(env))
2227 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2228 return CA_ADAPTER_NOT_ENABLED;
2231 // get default bt adapter class
2232 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2233 if (!jni_cid_BTAdapter)
2235 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2236 CACheckJNIException(env);
2237 return CA_STATUS_FAILED;
2240 // get remote bt adapter method
2241 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2242 "getDefaultAdapter",
2243 METHODID_OBJECTNONPARAM);
2244 if (!jni_mid_getDefaultAdapter)
2246 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2247 CACheckJNIException(env);
2248 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2249 return CA_STATUS_FAILED;
2252 // get start le scan method
2253 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
2254 "(Landroid/bluetooth/"
2255 "BluetoothAdapter$LeScanCallback;)V");
2256 if (!jni_mid_stopLeScan)
2258 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
2259 CACheckJNIException(env);
2260 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2261 return CA_STATUS_FAILED;
2264 // get bt adapter object
2265 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2266 jni_mid_getDefaultAdapter);
2267 if (!jni_obj_BTAdapter)
2269 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2270 CACheckJNIException(env);
2271 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2272 return CA_STATUS_FAILED;
2275 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
2276 // call start le scan method
2277 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
2278 if (CACheckJNIException(env))
2280 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
2281 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2282 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2283 return CA_STATUS_FAILED;
2286 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2287 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2288 return CA_STATUS_OK;
2291 CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
2293 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
2294 VERIFY_NON_NULL(callback, TAG, "callback is null");
2295 VERIFY_NON_NULL(env, TAG, "env is null");
2297 if (!CALEIsEnableBTAdapter(env))
2299 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2300 return CA_ADAPTER_NOT_ENABLED;
2303 // get default bt adapter class
2304 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2305 if (!jni_cid_BTAdapter)
2307 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
2308 CACheckJNIException(env);
2309 return CA_STATUS_FAILED;
2312 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2313 "getDefaultAdapter",
2314 "()Landroid/bluetooth/"
2315 "BluetoothAdapter;");
2316 if (!jni_mid_getDefaultAdapter)
2318 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2319 CACheckJNIException(env);
2320 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2321 return CA_STATUS_FAILED;
2324 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2325 jni_mid_getDefaultAdapter);
2326 if (!jni_obj_BTAdapter)
2328 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2329 CACheckJNIException(env);
2330 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2331 return CA_STATUS_FAILED;
2334 // get bluetoothLeScanner class
2335 jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
2336 if (!jni_cid_leScanner)
2338 OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
2339 CACheckJNIException(env);
2340 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2341 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2342 return CA_STATUS_FAILED;
2345 // get remote bt adapter method
2346 jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2347 "getBluetoothLeScanner",
2348 "()Landroid/bluetooth/"
2349 "le/BluetoothLeScanner;");
2350 if (!jni_mid_getBluetoothLeScanner)
2352 OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
2353 CACheckJNIException(env);
2354 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2355 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2356 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2357 return CA_STATUS_FAILED;
2359 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
2361 // get stopScan(ScanCallback callback) method
2362 jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
2363 "(Landroid/bluetooth/le/ScanCallback;)V");
2364 if (!jni_mid_stopScan)
2366 OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
2367 CACheckJNIException(env);
2368 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
2369 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2370 return CA_STATUS_FAILED;
2372 (*env)->DeleteLocalRef(env, jni_cid_leScanner);
2374 // gat le scanner object
2375 jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
2376 jni_mid_getBluetoothLeScanner);
2377 if (!jni_obj_leScanner)
2379 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
2380 CACheckJNIException(env);
2381 return CA_STATUS_FAILED;
2384 // call stopScan method
2385 OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
2386 (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
2387 if (CACheckJNIException(env))
2389 OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
2390 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2391 return CA_STATUS_FAILED;
2394 (*env)->DeleteLocalRef(env, jni_obj_leScanner);
2395 return CA_STATUS_OK;
2398 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2400 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
2401 VERIFY_NON_NULL(env, TAG, "env is null");
2402 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
2404 oc_mutex_lock(g_threadSendMutex);
2406 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2409 OIC_LOG(ERROR, TAG, "jni_address is not available");
2410 oc_mutex_unlock(g_threadSendMutex);
2411 return CA_STATUS_FAILED;
2414 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2417 OIC_LOG(ERROR, TAG, "address is not available");
2418 CACheckJNIException(env);
2419 oc_mutex_unlock(g_threadSendMutex);
2420 return CA_STATUS_FAILED;
2423 CAResult_t res = CA_STATUS_OK;
2424 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2427 g_deviceStateListMutex))
2429 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
2430 if (NULL == newGatt)
2432 OIC_LOG(INFO, TAG, "newGatt is not available");
2433 res = CA_STATUS_FAILED;
2436 oc_mutex_unlock(g_threadSendMutex);
2441 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2443 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
2444 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2445 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2447 // reset scan interval time after checking scanned devices
2448 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
2450 // since there is no callback related stop success
2451 // and scanning should be stopped before connectGatt is called.
2452 // it should wait a few micro seconds.
2455 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
2456 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
2459 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2462 OIC_LOG(ERROR, TAG, "address is not available");
2466 // close the gatt service
2467 jobject gatt = CALEClientGetGattObjInList(env, address);
2470 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
2471 if (CA_STATUS_OK != res)
2473 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
2474 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2478 // clean previous gatt object after close profile service
2479 res = CALEClientRemoveGattObjForAddr(env, jni_address);
2480 if (CA_STATUS_OK != res)
2482 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
2483 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2487 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2490 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
2493 OIC_LOG(DEBUG, TAG, "re-connection will be started");
2497 // add new gatt object into g_gattObjectList
2498 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
2499 if (CA_STATUS_OK != res)
2501 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
2508 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
2510 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
2511 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2512 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
2514 if (!g_leGattCallback)
2516 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
2520 if (!CALEIsEnableBTAdapter(env))
2522 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2526 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
2529 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
2533 jobject jni_obj_connectGatt = NULL;
2534 jint jni_int_sdk = CALEGetBuildVersion(env);
2535 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
2536 if (jni_int_sdk >= 23) // upper than API level 23
2538 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2540 "(Landroid/content/Context;ZLandroid/"
2541 "bluetooth/BluetoothGattCallback;I)"
2542 "Landroid/bluetooth/BluetoothGatt;");
2543 if (!jni_mid_connectGatt)
2545 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2549 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
2550 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
2551 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2552 jni_mid_connectGatt, NULL,
2553 autoconnect, g_leGattCallback,
2555 if (!jni_obj_connectGatt)
2557 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2558 CACheckJNIException(env);
2559 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2560 CALEClientUpdateSendCnt(env);
2565 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2568 else // lower than API level 23
2571 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2574 OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
2577 OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
2578 jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
2582 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
2584 "(Landroid/content/Context;ZLandroid/"
2585 "bluetooth/BluetoothGattCallback;)"
2586 "Landroid/bluetooth/BluetoothGatt;");
2587 if (!jni_mid_connectGatt)
2589 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
2593 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
2594 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
2595 jni_mid_connectGatt,
2597 autoconnect, g_leGattCallback);
2599 if (!jni_obj_connectGatt)
2601 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
2602 CACheckJNIException(env);
2603 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
2604 CALEClientUpdateSendCnt(env);
2609 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
2614 return jni_obj_connectGatt;
2617 bool CALEClientIsConnected(const char* address)
2619 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
2620 STATE_SERVICE_CONNECTED,
2622 g_deviceStateListMutex))
2624 OIC_LOG(DEBUG, TAG, "current state is connected");
2627 OIC_LOG(DEBUG, TAG, "current state is not connected");
2631 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
2633 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
2635 VERIFY_NON_NULL(env, TAG, "env is null");
2636 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2638 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
2639 if (!jni_cid_BTAdapter)
2641 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
2645 // get remote bt adapter method
2646 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
2647 "getDefaultAdapter",
2648 METHODID_OBJECTNONPARAM);
2649 if (!jni_mid_getDefaultAdapter)
2651 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
2655 // gat bt adapter object
2656 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
2657 jni_mid_getDefaultAdapter);
2658 if (!jni_obj_BTAdapter)
2660 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
2664 // get closeProfileProxy method
2665 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
2666 "closeProfileProxy",
2667 "(ILandroid/bluetooth/"
2668 "BluetoothProfile;)V");
2669 if (!jni_mid_closeProfileProxy)
2671 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
2675 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
2676 if (!jni_cid_BTProfile)
2678 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
2682 // GATT - Constant value : 7 (0x00000007)
2683 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
2687 OIC_LOG(ERROR, TAG, "id_gatt is null");
2691 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
2692 CACheckJNIException(env);
2694 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
2695 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
2696 if (CACheckJNIException(env))
2698 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
2699 return CA_STATUS_FAILED;
2702 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
2703 return CA_STATUS_OK;
2706 CACheckJNIException(env);
2707 return CA_STATUS_FAILED;
2711 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
2713 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
2714 VERIFY_NON_NULL(env, TAG, "env is null");
2715 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2717 // get BluetoothGatt method
2718 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
2719 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2720 "disconnect", "()V");
2721 if (!jni_mid_disconnectGatt)
2723 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
2724 return CA_STATUS_FAILED;
2727 // call disconnect gatt method
2728 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2729 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2730 if (CACheckJNIException(env))
2732 OIC_LOG(ERROR, TAG, "disconnect has failed");
2733 return CA_STATUS_FAILED;
2736 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2738 return CA_STATUS_OK;
2741 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
2743 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
2744 VERIFY_NON_NULL(env, TAG, "env is null");
2746 if (!g_gattObjectList)
2748 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2749 return CA_STATUS_OK;
2752 uint32_t length = u_arraylist_length(g_gattObjectList);
2753 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2754 for (uint32_t index = 0; index < length; index++)
2756 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2757 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2760 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2763 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2764 if (CA_STATUS_OK != res)
2766 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2771 return CA_STATUS_OK;
2774 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2776 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2777 VERIFY_NON_NULL(env, TAG, "env is null");
2779 if (!g_gattObjectList)
2781 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2782 return CA_STATUS_OK;
2785 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2788 OIC_LOG(ERROR, TAG, "address is null");
2789 CACheckJNIException(env);
2790 return CA_STATUS_FAILED;
2793 uint32_t length = u_arraylist_length(g_gattObjectList);
2794 for (uint32_t index = 0; index < length; index++)
2796 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2799 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2803 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2804 if (!jni_setAddress)
2806 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2807 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2808 return CA_STATUS_FAILED;
2811 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2814 OIC_LOG(ERROR, TAG, "setAddress is null");
2815 CACheckJNIException(env);
2816 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2817 return CA_STATUS_FAILED;
2820 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2821 if (!strcasecmp(address, setAddress))
2823 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2824 if (CA_STATUS_OK != res)
2826 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2827 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2828 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2829 return CA_STATUS_FAILED;
2831 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2832 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2833 return CA_STATUS_OK;
2835 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2837 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2839 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2840 return CA_STATUS_OK;
2843 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
2845 VERIFY_NON_NULL(env, TAG, "env is null");
2846 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2848 if (!CALEIsEnableBTAdapter(env))
2850 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2851 return CA_ADAPTER_NOT_ENABLED;
2854 // get BluetoothGatt.requestMtu method
2855 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
2856 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2857 "requestMtu", "(I)Z");
2858 if (!jni_mid_requestMtu)
2860 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
2861 return CA_STATUS_FAILED;
2865 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
2866 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
2869 OIC_LOG(ERROR, TAG, "requestMtu has failed");
2870 CACheckJNIException(env);
2871 return CA_STATUS_FAILED;
2874 return CA_STATUS_OK;
2877 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2879 VERIFY_NON_NULL(env, TAG, "env is null");
2880 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2882 if (!CALEIsEnableBTAdapter(env))
2884 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2885 return CA_ADAPTER_NOT_ENABLED;
2888 // get BluetoothGatt.discoverServices method
2889 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2890 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2891 "discoverServices", "()Z");
2892 if (!jni_mid_discoverServices)
2894 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2895 return CA_STATUS_FAILED;
2898 // call disconnect gatt method
2899 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2900 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2903 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2904 CACheckJNIException(env);
2905 return CA_STATUS_FAILED;
2908 return CA_STATUS_OK;
2911 static void CALEWriteCharacteristicThread(void* object)
2913 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2915 bool isAttached = false;
2917 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2920 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2924 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2930 jobject gatt = (jobject)object;
2931 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2932 if (CA_STATUS_OK != ret)
2934 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2939 (*g_jvm)->DetachCurrentThread(g_jvm);
2943 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2945 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2947 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2948 VERIFY_NON_NULL(env, TAG, "env is null");
2950 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2953 CALEClientSendFinish(env, gatt);
2954 return CA_STATUS_FAILED;
2957 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2960 CACheckJNIException(env);
2961 CALEClientSendFinish(env, gatt);
2962 return CA_STATUS_FAILED;
2965 oc_mutex_lock(g_threadSendStateMutex);
2967 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
2969 g_deviceStateListMutex))
2971 OIC_LOG(INFO, TAG, "current state is SENDING");
2972 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2973 oc_mutex_unlock(g_threadSendStateMutex);
2974 return CA_STATUS_OK;
2977 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
2980 g_deviceStateListMutex))
2982 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2983 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2984 CALEClientSendFinish(env, gatt);
2985 oc_mutex_unlock(g_threadSendStateMutex);
2986 return CA_STATUS_FAILED;
2989 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2991 oc_mutex_unlock(g_threadSendStateMutex);
2993 jbyteArray sendData = NULL;
2994 oc_mutex_lock(g_setValueMutex);
2997 OIC_LOG(INFO, TAG, "alloc local reference for data");
2998 sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
3002 OIC_LOG(ERROR, TAG, "send Buffer is empty");
3003 oc_mutex_unlock(g_setValueMutex);
3004 return CA_STATUS_FAILED;
3006 oc_mutex_unlock(g_setValueMutex);
3009 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
3010 if (!jni_obj_character)
3014 (*env)->DeleteLocalRef(env, sendData);
3016 CALEClientSendFinish(env, gatt);
3017 return CA_STATUS_FAILED;
3022 (*env)->DeleteLocalRef(env, sendData);
3025 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
3026 if (CA_STATUS_OK != ret)
3028 CALEClientSendFinish(env, gatt);
3029 return CA_STATUS_FAILED;
3032 // wait for callback for write Characteristic with success to sent data
3033 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
3034 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3035 if (!g_isSignalSetFlag)
3037 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
3038 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
3039 g_threadWriteCharacteristicMutex,
3040 WAIT_TIME_WRITE_CHARACTERISTIC))
3042 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
3043 g_isSignalSetFlag = false;
3044 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3045 return CA_STATUS_FAILED;
3048 // reset flag set by writeCharacteristic Callback
3049 g_isSignalSetFlag = false;
3050 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3052 CALEClientUpdateSendCnt(env);
3054 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
3055 return CA_STATUS_OK;
3058 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
3060 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
3061 VERIFY_NON_NULL(env, TAG, "env is null");
3062 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3064 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
3065 CACheckJNIException(env);
3066 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
3067 (void*)gattParam, NULL))
3069 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
3070 return CA_STATUS_FAILED;
3073 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
3074 return CA_STATUS_OK;
3077 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
3078 jobject gattCharacteristic)
3080 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
3081 VERIFY_NON_NULL(env, TAG, "env is null");
3082 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3083 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
3085 if (!CALEIsEnableBTAdapter(env))
3087 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3088 return CA_STATUS_FAILED;
3091 // get BluetoothGatt.write characteristic method
3092 OIC_LOG(DEBUG, TAG, "write characteristic method");
3093 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3094 "writeCharacteristic",
3095 "(Landroid/bluetooth/"
3096 "BluetoothGattCharacteristic;)Z");
3097 if (!jni_mid_writeCharacteristic)
3099 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
3100 return CA_STATUS_FAILED;
3103 // call disconnect gatt method
3104 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
3105 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
3106 jni_mid_writeCharacteristic,
3107 gattCharacteristic);
3110 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
3114 CACheckJNIException(env);
3115 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
3116 return CA_STATUS_FAILED;
3119 return CA_STATUS_OK;
3122 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
3124 VERIFY_NON_NULL(env, TAG, "env is null");
3125 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3127 if (!CALEIsEnableBTAdapter(env))
3129 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3130 return CA_STATUS_FAILED;
3133 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3136 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3137 CACheckJNIException(env);
3138 return CA_STATUS_FAILED;
3141 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3142 if (!jni_obj_GattCharacteristic)
3144 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3145 return CA_STATUS_FAILED;
3148 OIC_LOG(DEBUG, TAG, "read characteristic method");
3149 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3150 "readCharacteristic",
3151 "(Landroid/bluetooth/"
3152 "BluetoothGattCharacteristic;)Z");
3153 if (!jni_mid_readCharacteristic)
3155 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
3156 return CA_STATUS_FAILED;
3159 // call disconnect gatt method
3160 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
3161 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
3162 jni_obj_GattCharacteristic);
3165 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
3169 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
3170 CACheckJNIException(env);
3171 return CA_STATUS_FAILED;
3174 return CA_STATUS_OK;
3177 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
3178 jobject characteristic)
3180 VERIFY_NON_NULL(env, TAG, "env is null");
3181 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3182 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3184 if (!CALEIsEnableBTAdapter(env))
3186 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3187 return CA_ADAPTER_NOT_ENABLED;
3190 // get BluetoothGatt.setCharacteristicNotification method
3191 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
3192 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3193 "setCharacteristicNotification",
3194 "(Landroid/bluetooth/"
3195 "BluetoothGattCharacteristic;Z)Z");
3196 if (!jni_mid_setNotification)
3198 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3199 return CA_STATUS_FAILED;
3202 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
3203 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
3204 characteristic, JNI_TRUE);
3205 if (JNI_TRUE == ret)
3207 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
3211 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
3212 CACheckJNIException(env);
3213 return CA_STATUS_FAILED;
3216 return CA_STATUS_OK;
3219 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
3221 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3222 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3223 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
3225 if (!CALEIsEnableBTAdapter(env))
3227 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3231 // get BluetoothGatt.getService method
3232 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
3233 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3235 "(Ljava/util/UUID;)Landroid/bluetooth/"
3236 "BluetoothGattService;");
3237 if (!jni_mid_getService)
3239 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
3243 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3244 if (!jni_obj_service_uuid)
3246 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
3250 // get bluetooth gatt service
3251 OIC_LOG(DEBUG, TAG, "request to get service");
3252 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
3253 jni_obj_service_uuid);
3254 if (!jni_obj_gattService)
3256 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
3257 CACheckJNIException(env);
3261 // get bluetooth gatt service method
3262 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
3263 "BluetoothGattService",
3264 "getCharacteristic",
3265 "(Ljava/util/UUID;)"
3266 "Landroid/bluetooth/"
3267 "BluetoothGattCharacteristic;");
3268 if (!jni_mid_getCharacteristic)
3270 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
3274 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
3277 OIC_LOG(ERROR, TAG, "uuid is null");
3278 CACheckJNIException(env);
3282 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
3283 if (!jni_obj_tx_uuid)
3285 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
3286 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3290 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
3291 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
3292 jni_mid_getCharacteristic,
3294 if (!jni_obj_GattCharacteristic)
3296 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
3297 CACheckJNIException(env);
3301 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
3302 return jni_obj_GattCharacteristic;
3305 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
3307 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
3308 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3309 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
3310 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
3312 if (!CALEIsEnableBTAdapter(env))
3314 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3318 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
3321 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3325 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
3326 if (!jni_obj_GattCharacteristic)
3328 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3332 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
3333 "/BluetoothGattCharacteristic");
3334 if (!jni_cid_BTGattCharacteristic)
3336 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
3340 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
3341 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
3343 if (!jni_mid_setValue)
3345 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3349 OIC_LOG(DEBUG, TAG, "CALL API - setValue");
3350 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
3352 if (JNI_TRUE == ret)
3354 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
3358 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
3364 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
3366 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
3367 "setWriteType", "(I)V");
3368 if (!jni_mid_setWriteType)
3370 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
3374 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
3375 "WRITE_TYPE_NO_RESPONSE", "I");
3376 if (!jni_fid_no_response)
3378 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
3382 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
3383 jni_fid_no_response);
3384 CACheckJNIException(env);
3386 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
3387 if (CACheckJNIException(env))
3389 OIC_LOG(ERROR, TAG, "setWriteType has failed");
3394 OIC_LOG(DEBUG, TAG, "It will run with response property");
3397 return jni_obj_GattCharacteristic;
3400 CACheckJNIException(env);
3404 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
3406 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
3407 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3409 if (!CALEIsEnableBTAdapter(env))
3411 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3415 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
3416 "BluetoothGattCharacteristic",
3417 "getValue", "()[B");
3418 if (!jni_mid_getValue)
3420 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
3424 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
3426 CACheckJNIException(env);
3427 return jni_obj_data_array;
3430 CAResult_t CALEClientCreateUUIDList()
3434 OIC_LOG(ERROR, TAG, "g_jvm is null");
3435 return CA_STATUS_FAILED;
3438 bool isAttached = false;
3440 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3443 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3447 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3448 return CA_STATUS_FAILED;
3453 // create new object array
3454 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
3455 if (!jni_cid_uuid_list)
3457 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
3458 CACheckJNIException(env);
3462 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
3463 jni_cid_uuid_list, NULL);
3464 if (!jni_obj_uuid_list)
3466 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
3467 CACheckJNIException(env);
3472 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
3475 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
3478 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
3480 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
3481 CACheckJNIException(env);
3485 (*g_jvm)->DetachCurrentThread(g_jvm);
3488 return CA_STATUS_OK;
3495 (*g_jvm)->DetachCurrentThread(g_jvm);
3497 return CA_STATUS_FAILED;
3500 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
3501 jobject characteristic)
3503 VERIFY_NON_NULL(env, TAG, "env is null");
3504 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
3505 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
3507 if (!CALEIsEnableBTAdapter(env))
3509 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
3510 return CA_ADAPTER_NOT_ENABLED;
3513 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
3514 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
3515 "BluetoothGattCharacteristic",
3517 "(Ljava/util/UUID;)Landroid/bluetooth/"
3518 "BluetoothGattDescriptor;");
3519 if (!jni_mid_getDescriptor)
3521 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
3522 return CA_STATUS_FAILED;
3525 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
3526 if (!jni_obj_cc_uuid)
3528 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
3531 OIC_LOG(DEBUG, TAG, "request to get descriptor");
3532 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
3533 jni_mid_getDescriptor, jni_obj_cc_uuid);
3534 if (!jni_obj_descriptor)
3536 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
3540 OIC_LOG(DEBUG, TAG, "set value in descriptor");
3541 jclass jni_cid_descriptor = (*env)->FindClass(env,
3542 "android/bluetooth/BluetoothGattDescriptor");
3543 if (!jni_cid_descriptor)
3545 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
3549 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
3550 if (!jni_mid_setValue)
3552 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
3556 jfieldID jni_fid_NotiValue = NULL;
3559 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
3560 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3561 "ENABLE_INDICATION_VALUE", "[B");
3562 if (!jni_fid_NotiValue)
3564 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3570 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
3571 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
3572 "ENABLE_NOTIFICATION_VALUE", "[B");
3573 if (!jni_fid_NotiValue)
3575 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
3580 jboolean jni_setvalue = (*env)->CallBooleanMethod(
3581 env, jni_obj_descriptor, jni_mid_setValue,
3582 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
3585 OIC_LOG(DEBUG, TAG, "setValue success");
3589 OIC_LOG(ERROR, TAG, "setValue has failed");
3593 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
3595 "(Landroid/bluetooth/"
3596 "BluetoothGattDescriptor;)Z");
3597 if (!jni_mid_writeDescriptor)
3599 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
3600 return CA_STATUS_FAILED;
3603 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
3604 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
3605 jni_obj_descriptor);
3608 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
3612 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
3616 return CA_STATUS_OK;
3619 CACheckJNIException(env);
3620 return CA_STATUS_FAILED;
3623 void CALEClientCreateScanDeviceList(JNIEnv *env)
3625 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
3626 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3628 oc_mutex_lock(g_deviceListMutex);
3629 // create new object array
3630 if (g_deviceList == NULL)
3632 OIC_LOG(DEBUG, TAG, "Create device list");
3634 g_deviceList = u_arraylist_create();
3636 oc_mutex_unlock(g_deviceListMutex);
3639 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
3641 VERIFY_NON_NULL(device, TAG, "device is null");
3642 VERIFY_NON_NULL(env, TAG, "env is null");
3644 oc_mutex_lock(g_deviceListMutex);
3648 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3649 oc_mutex_unlock(g_deviceListMutex);
3650 return CA_STATUS_FAILED;
3653 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
3654 if (!jni_remoteAddress)
3656 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3657 oc_mutex_unlock(g_deviceListMutex);
3658 return CA_STATUS_FAILED;
3661 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3664 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3665 CACheckJNIException(env);
3666 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3667 oc_mutex_unlock(g_deviceListMutex);
3668 return CA_STATUS_FAILED;
3671 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
3673 jobject gdevice = (*env)->NewGlobalRef(env, device);
3674 CACheckJNIException(env);
3675 u_arraylist_add(g_deviceList, gdevice);
3676 oc_cond_signal(g_deviceDescCond);
3677 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
3679 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3680 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3682 oc_mutex_unlock(g_deviceListMutex);
3684 return CA_STATUS_OK;
3687 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
3689 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
3690 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3694 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
3698 uint32_t length = u_arraylist_length(g_deviceList);
3699 for (uint32_t index = 0; index < length; index++)
3701 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3704 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3708 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3709 if (!jni_setAddress)
3711 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3715 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3718 OIC_LOG(ERROR, TAG, "setAddress is null");
3719 CACheckJNIException(env);
3720 (*env)->DeleteLocalRef(env, jni_setAddress);
3724 if (!strcasecmp(remoteAddress, setAddress))
3726 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3727 (*env)->DeleteLocalRef(env, jni_setAddress);
3731 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3732 (*env)->DeleteLocalRef(env, jni_setAddress);
3737 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
3739 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
3740 VERIFY_NON_NULL(env, TAG, "env is null");
3742 oc_mutex_lock(g_deviceListMutex);
3746 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3747 oc_mutex_unlock(g_deviceListMutex);
3748 return CA_STATUS_FAILED;
3751 uint32_t length = u_arraylist_length(g_deviceList);
3752 for (uint32_t index = 0; index < length; index++)
3754 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3757 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3760 (*env)->DeleteGlobalRef(env, jarrayObj);
3764 OICFree(g_deviceList);
3765 g_deviceList = NULL;
3767 oc_mutex_unlock(g_deviceListMutex);
3768 return CA_STATUS_OK;
3771 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
3773 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
3774 VERIFY_NON_NULL(address, TAG, "address is null");
3775 VERIFY_NON_NULL(env, TAG, "env is null");
3777 oc_mutex_lock(g_deviceListMutex);
3781 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3782 oc_mutex_unlock(g_deviceListMutex);
3783 return CA_STATUS_FAILED;
3786 uint32_t length = u_arraylist_length(g_deviceList);
3787 for (uint32_t index = 0; index < length; index++)
3789 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3792 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3793 oc_mutex_unlock(g_deviceListMutex);
3794 return CA_STATUS_FAILED;
3797 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3798 if (!jni_setAddress)
3800 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3801 oc_mutex_unlock(g_deviceListMutex);
3802 return CA_STATUS_FAILED;
3805 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3808 OIC_LOG(ERROR, TAG, "setAddress is null");
3809 CACheckJNIException(env);
3810 oc_mutex_unlock(g_deviceListMutex);
3811 return CA_STATUS_FAILED;
3814 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
3817 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3818 CACheckJNIException(env);
3819 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3820 oc_mutex_unlock(g_deviceListMutex);
3821 return CA_STATUS_FAILED;
3824 if (!strcasecmp(setAddress, remoteAddress))
3826 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3827 (*env)->DeleteGlobalRef(env, jarrayObj);
3829 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3830 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3832 if (NULL == u_arraylist_remove(g_deviceList, index))
3834 OIC_LOG(ERROR, TAG, "List removal failed.");
3835 oc_mutex_unlock(g_deviceListMutex);
3836 return CA_STATUS_FAILED;
3838 oc_mutex_unlock(g_deviceListMutex);
3839 return CA_STATUS_OK;
3841 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3842 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3845 oc_mutex_unlock(g_deviceListMutex);
3846 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
3848 return CA_STATUS_OK;
3855 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
3857 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
3858 VERIFY_NON_NULL(env, TAG, "env is null");
3859 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3861 oc_mutex_lock(g_gattObjectMutex);
3863 if (!g_gattObjectList)
3865 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
3866 oc_mutex_unlock(g_gattObjectMutex);
3867 return CA_STATUS_FAILED;
3870 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3871 if (!jni_remoteAddress)
3873 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3874 oc_mutex_unlock(g_gattObjectMutex);
3875 return CA_STATUS_FAILED;
3878 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3881 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3882 CACheckJNIException(env);
3883 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3884 oc_mutex_unlock(g_gattObjectMutex);
3885 return CA_STATUS_FAILED;
3888 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3889 if (!CALEClientIsGattObjInList(env, remoteAddress))
3891 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3892 u_arraylist_add(g_gattObjectList, newGatt);
3893 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3896 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3897 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3898 oc_mutex_unlock(g_gattObjectMutex);
3899 return CA_STATUS_OK;
3902 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3904 VERIFY_NON_NULL(env, TAG, "env is null");
3905 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3907 uint32_t length = u_arraylist_length(g_gattObjectList);
3908 for (uint32_t index = 0; index < length; index++)
3910 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3913 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3917 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3918 if (!jni_setAddress)
3920 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3924 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3927 OIC_LOG(ERROR, TAG, "setAddress is null");
3928 CACheckJNIException(env);
3929 (*env)->DeleteLocalRef(env, jni_setAddress);
3933 if (!strcasecmp(remoteAddress, setAddress))
3935 OIC_LOG(DEBUG, TAG, "the device is already set");
3936 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3937 (*env)->DeleteLocalRef(env, jni_setAddress);
3940 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3941 (*env)->DeleteLocalRef(env, jni_setAddress);
3944 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3948 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3950 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3951 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3952 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3954 oc_mutex_lock(g_gattObjectMutex);
3955 uint32_t length = u_arraylist_length(g_gattObjectList);
3956 for (uint32_t index = 0; index < length; index++)
3958 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3961 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3962 oc_mutex_unlock(g_gattObjectMutex);
3966 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3967 if (!jni_setAddress)
3969 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3970 oc_mutex_unlock(g_gattObjectMutex);
3974 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3977 OIC_LOG(ERROR, TAG, "setAddress is null");
3978 CACheckJNIException(env);
3979 (*env)->DeleteLocalRef(env, jni_setAddress);
3980 oc_mutex_unlock(g_gattObjectMutex);
3984 if (!strcasecmp(remoteAddress, setAddress))
3986 OIC_LOG(DEBUG, TAG, "the device is already set");
3987 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3988 oc_mutex_unlock(g_gattObjectMutex);
3991 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3992 (*env)->DeleteLocalRef(env, jni_setAddress);
3995 oc_mutex_unlock(g_gattObjectMutex);
3996 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
4000 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
4002 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
4003 VERIFY_NON_NULL(env, TAG, "env is null");
4005 oc_mutex_lock(g_gattObjectMutex);
4006 if (!g_gattObjectList)
4008 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4009 oc_mutex_unlock(g_gattObjectMutex);
4010 return CA_STATUS_OK;
4013 uint32_t length = u_arraylist_length(g_gattObjectList);
4014 for (uint32_t index = 0; index < length; index++)
4016 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4019 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4022 (*env)->DeleteGlobalRef(env, jarrayObj);
4026 OICFree(g_gattObjectList);
4027 g_gattObjectList = NULL;
4028 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
4029 oc_mutex_unlock(g_gattObjectMutex);
4030 return CA_STATUS_OK;
4033 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
4035 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
4036 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
4037 VERIFY_NON_NULL(env, TAG, "env is null");
4039 oc_mutex_lock(g_gattObjectMutex);
4040 if (!g_gattObjectList)
4042 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4043 oc_mutex_unlock(g_gattObjectMutex);
4044 return CA_STATUS_OK;
4047 uint32_t length = u_arraylist_length(g_gattObjectList);
4048 for (uint32_t index = 0; index < length; index++)
4050 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4053 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4054 oc_mutex_unlock(g_gattObjectMutex);
4055 return CA_STATUS_FAILED;
4058 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4059 if (!jni_setAddress)
4061 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4062 oc_mutex_unlock(g_gattObjectMutex);
4063 return CA_STATUS_FAILED;
4066 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4069 OIC_LOG(ERROR, TAG, "setAddress is null");
4070 CACheckJNIException(env);
4071 oc_mutex_unlock(g_gattObjectMutex);
4072 return CA_STATUS_FAILED;
4075 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
4076 if (!jni_remoteAddress)
4078 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
4079 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4080 oc_mutex_unlock(g_gattObjectMutex);
4081 return CA_STATUS_FAILED;
4084 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
4087 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4088 CACheckJNIException(env);
4089 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4090 oc_mutex_unlock(g_gattObjectMutex);
4091 return CA_STATUS_FAILED;
4094 if (!strcasecmp(setAddress, remoteAddress))
4096 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4097 (*env)->DeleteGlobalRef(env, jarrayObj);
4099 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4100 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4102 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4104 OIC_LOG(ERROR, TAG, "List removal failed.");
4105 oc_mutex_unlock(g_gattObjectMutex);
4106 return CA_STATUS_FAILED;
4108 oc_mutex_unlock(g_gattObjectMutex);
4109 return CA_STATUS_OK;
4111 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4112 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
4115 oc_mutex_unlock(g_gattObjectMutex);
4116 OIC_LOG(DEBUG, TAG, "there are no target object");
4117 return CA_STATUS_OK;
4120 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
4122 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
4123 VERIFY_NON_NULL(addr, TAG, "addr is null");
4124 VERIFY_NON_NULL(env, TAG, "env is null");
4126 oc_mutex_lock(g_gattObjectMutex);
4127 if (!g_gattObjectList)
4129 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
4130 oc_mutex_unlock(g_gattObjectMutex);
4131 return CA_STATUS_OK;
4134 uint32_t length = u_arraylist_length(g_gattObjectList);
4135 for (uint32_t index = 0; index < length; index++)
4137 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4140 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4141 oc_mutex_unlock(g_gattObjectMutex);
4142 return CA_STATUS_FAILED;
4145 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4146 if (!jni_setAddress)
4148 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
4149 oc_mutex_unlock(g_gattObjectMutex);
4150 return CA_STATUS_FAILED;
4153 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
4156 OIC_LOG(ERROR, TAG, "setAddress is null");
4157 CACheckJNIException(env);
4158 oc_mutex_unlock(g_gattObjectMutex);
4159 return CA_STATUS_FAILED;
4162 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
4165 OIC_LOG(ERROR, TAG, "remoteAddress is null");
4166 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4167 oc_mutex_unlock(g_gattObjectMutex);
4168 return CA_STATUS_FAILED;
4171 if (!strcasecmp(setAddress, remoteAddress))
4173 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
4174 (*env)->DeleteGlobalRef(env, jarrayObj);
4176 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4177 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4178 if (NULL == u_arraylist_remove(g_gattObjectList, index))
4180 OIC_LOG(ERROR, TAG, "List removal failed.");
4181 oc_mutex_unlock(g_gattObjectMutex);
4182 return CA_STATUS_FAILED;
4184 oc_mutex_unlock(g_gattObjectMutex);
4185 return CA_STATUS_OK;
4187 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
4188 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
4191 oc_mutex_unlock(g_gattObjectMutex);
4192 OIC_LOG(DEBUG, TAG, "there are no target object");
4193 return CA_STATUS_FAILED;
4196 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
4198 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
4199 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
4201 // get Bluetooth Address
4202 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
4203 if (!jni_btTargetAddress)
4205 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4209 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
4212 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4213 CACheckJNIException(env);
4217 // get method ID of getDevice()
4218 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4219 "getDevice", METHODID_BT_DEVICE);
4220 if (!jni_mid_getDevice)
4222 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4223 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4227 oc_mutex_lock(g_gattObjectMutex);
4229 size_t length = u_arraylist_length(g_gattObjectList);
4230 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
4231 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
4233 for (size_t index = 0; index < length; index++)
4235 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
4238 oc_mutex_unlock(g_gattObjectMutex);
4239 OIC_LOG(ERROR, TAG, "jarrayObj is null");
4240 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4244 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
4245 if (!jni_obj_device)
4247 CACheckJNIException(env);
4248 oc_mutex_unlock(g_gattObjectMutex);
4249 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4250 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4254 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
4257 oc_mutex_unlock(g_gattObjectMutex);
4258 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4259 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4260 (*env)->DeleteLocalRef(env, jni_obj_device);
4264 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
4267 CACheckJNIException(env);
4268 oc_mutex_unlock(g_gattObjectMutex);
4269 OIC_LOG(ERROR, TAG, "btAddress is not available");
4270 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4271 (*env)->DeleteLocalRef(env, jni_btAddress);
4272 (*env)->DeleteLocalRef(env, jni_obj_device);
4276 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
4277 if (!strcasecmp(targetAddress, btAddress))
4279 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
4282 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
4285 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
4287 oc_mutex_unlock(g_gattObjectMutex);
4288 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4289 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4290 (*env)->DeleteLocalRef(env, jni_btAddress);
4291 (*env)->DeleteLocalRef(env, jni_obj_device);
4292 return jni_LEAddress;
4294 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
4295 (*env)->DeleteLocalRef(env, jni_btAddress);
4296 (*env)->DeleteLocalRef(env, jni_obj_device);
4298 oc_mutex_unlock(g_gattObjectMutex);
4300 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
4301 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
4308 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
4310 uint16_t state_type,
4311 uint16_t target_state)
4313 VERIFY_NON_NULL(device, TAG, "device is null");
4315 // get Bluetooth Address
4316 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
4319 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
4320 return CA_STATUS_FAILED;
4323 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
4326 OIC_LOG(ERROR, TAG, "targetAddress is not available");
4327 CACheckJNIException(env);
4328 (*env)->DeleteLocalRef(env, jni_Address);
4329 return CA_STATUS_FAILED;
4332 if (CALEIsValidState(address, state_type, target_state,
4334 g_deviceStateListMutex))
4336 (*env)->DeleteLocalRef(env, jni_Address);
4337 return CA_STATUS_OK;
4340 CAResult_t res = CALEUpdateDeviceState(address, state_type,
4343 g_deviceStateListMutex);
4344 if (CA_STATUS_OK != res)
4346 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4348 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
4349 (*env)->DeleteLocalRef(env, jni_Address);
4354 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
4355 jint state_idx, jboolean flag)
4357 return CALESetFlagToState(env, jni_address, state_idx, flag,
4358 g_deviceStateList, g_deviceStateListMutex);
4361 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
4363 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
4364 g_deviceStateListMutex);
4367 uint16_t CALEClientGetMtuSize(const char* address)
4369 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
4372 void CALEClientCreateDeviceList()
4374 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
4376 // create new object array
4377 if (!g_gattObjectList)
4379 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
4381 g_gattObjectList = u_arraylist_create();
4384 if (!g_deviceStateList)
4386 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
4388 g_deviceStateList = u_arraylist_create();
4393 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
4395 g_deviceList = u_arraylist_create();
4399 CAResult_t CALEClientResetDeviceStateForAll()
4401 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
4405 * Check Sent Count for remove g_sendBuffer
4407 void CALEClientUpdateSendCnt(JNIEnv *env)
4409 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
4411 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4413 oc_mutex_lock(g_threadMutex);
4417 if (g_targetCnt <= g_currentSentCnt)
4420 g_currentSentCnt = 0;
4422 CALEDeleteSendBuffer(env);
4424 // notity the thread
4425 oc_cond_signal(g_threadCond);
4426 oc_cond_signal(g_threadWriteCharacteristicCond);
4428 CALEClientSetSendFinishFlag(true);
4429 OIC_LOG(DEBUG, TAG, "set signal for send data");
4432 #ifdef SCAN_INTERVAL
4433 // reset interval scan logic
4434 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4438 oc_mutex_unlock(g_threadMutex);
4441 CAResult_t CALEClientInitGattMutexVaraibles()
4443 if (NULL == g_bleServerBDAddressMutex)
4445 g_bleServerBDAddressMutex = oc_mutex_new();
4446 if (NULL == g_bleServerBDAddressMutex)
4448 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4449 return CA_STATUS_FAILED;
4453 if (NULL == g_threadMutex)
4455 g_threadMutex = oc_mutex_new();
4456 if (NULL == g_threadMutex)
4458 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4459 return CA_STATUS_FAILED;
4463 if (NULL == g_threadSendMutex)
4465 g_threadSendMutex = oc_mutex_new();
4466 if (NULL == g_threadSendMutex)
4468 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4469 return CA_STATUS_FAILED;
4473 if (NULL == g_deviceListMutex)
4475 g_deviceListMutex = oc_mutex_new();
4476 if (NULL == g_deviceListMutex)
4478 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4479 return CA_STATUS_FAILED;
4483 if (NULL == g_gattObjectMutex)
4485 g_gattObjectMutex = oc_mutex_new();
4486 if (NULL == g_gattObjectMutex)
4488 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4489 return CA_STATUS_FAILED;
4493 if (NULL == g_deviceStateListMutex)
4495 g_deviceStateListMutex = oc_mutex_new();
4496 if (NULL == g_deviceStateListMutex)
4498 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4499 return CA_STATUS_FAILED;
4503 if (NULL == g_SendFinishMutex)
4505 g_SendFinishMutex = oc_mutex_new();
4506 if (NULL == g_SendFinishMutex)
4508 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4509 return CA_STATUS_FAILED;
4513 if (NULL == g_threadWriteCharacteristicMutex)
4515 g_threadWriteCharacteristicMutex = oc_mutex_new();
4516 if (NULL == g_threadWriteCharacteristicMutex)
4518 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4519 return CA_STATUS_FAILED;
4523 if (NULL == g_deviceScanRetryDelayMutex)
4525 g_deviceScanRetryDelayMutex = oc_mutex_new();
4526 if (NULL == g_deviceScanRetryDelayMutex)
4528 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4529 return CA_STATUS_FAILED;
4533 if (NULL == g_threadSendStateMutex)
4535 g_threadSendStateMutex = oc_mutex_new();
4536 if (NULL == g_threadSendStateMutex)
4538 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4539 return CA_STATUS_FAILED;
4543 if (NULL == g_threadScanIntervalMutex)
4545 g_threadScanIntervalMutex = oc_mutex_new();
4546 if (NULL == g_threadScanIntervalMutex)
4548 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4549 return CA_STATUS_FAILED;
4553 if (NULL == g_setValueMutex)
4555 g_setValueMutex = oc_mutex_new();
4556 if (NULL == g_setValueMutex)
4558 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
4559 return CA_STATUS_FAILED;
4563 return CA_STATUS_OK;
4566 void CALEClientTerminateGattMutexVariables()
4569 oc_mutex_free(g_bleServerBDAddressMutex);
4570 g_bleServerBDAddressMutex = NULL;
4572 oc_mutex_free(g_threadMutex);
4573 g_threadMutex = NULL;
4575 oc_mutex_free(g_threadSendMutex);
4576 g_threadSendMutex = NULL;
4578 oc_mutex_free(g_deviceListMutex);
4579 g_deviceListMutex = NULL;
4581 oc_mutex_free(g_SendFinishMutex);
4582 g_SendFinishMutex = NULL;
4584 oc_mutex_free(g_threadWriteCharacteristicMutex);
4585 g_threadWriteCharacteristicMutex = NULL;
4587 oc_mutex_free(g_deviceScanRetryDelayMutex);
4588 g_deviceScanRetryDelayMutex = NULL;
4590 oc_mutex_free(g_threadSendStateMutex);
4591 g_threadSendStateMutex = NULL;
4593 oc_mutex_free(g_threadScanIntervalMutex);
4594 g_threadScanIntervalMutex = NULL;
4596 oc_mutex_free(g_gattObjectMutex);
4597 g_gattObjectMutex = NULL;
4599 oc_mutex_free(g_deviceStateListMutex);
4600 g_deviceStateListMutex = NULL;
4602 oc_mutex_free(g_setValueMutex);
4603 g_setValueMutex = NULL;
4606 void CALEClientSetSendFinishFlag(bool flag)
4608 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
4610 oc_mutex_lock(g_SendFinishMutex);
4611 g_isFinishedSendData = flag;
4612 oc_mutex_unlock(g_SendFinishMutex);
4619 CAResult_t CAStartLEGattClient()
4621 // init mutex for send logic
4622 if (!g_deviceDescCond)
4624 g_deviceDescCond = oc_cond_new();
4629 g_threadCond = oc_cond_new();
4632 if (!g_threadWriteCharacteristicCond)
4634 g_threadWriteCharacteristicCond = oc_cond_new();
4637 if (!g_threadScanIntervalCond)
4639 g_threadScanIntervalCond = oc_cond_new();
4642 CAResult_t ret = CALEClientStartScanWithInterval();
4643 if (CA_STATUS_OK != ret)
4645 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4649 g_isStartedLEClient = true;
4650 return CA_STATUS_OK;
4653 void CAStopLEGattClient()
4655 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4659 OIC_LOG(ERROR, TAG, "g_jvm is null");
4663 bool isAttached = false;
4665 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4668 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4672 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4678 CAResult_t ret = CALEClientDisconnectAll(env);
4679 if (CA_STATUS_OK != ret)
4681 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4684 CALEClientStopScanWithInterval();
4686 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4687 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4688 oc_cond_signal(g_threadWriteCharacteristicCond);
4689 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4691 CALEClientSetSendFinishFlag(true);
4692 oc_mutex_lock(g_threadMutex);
4693 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
4694 oc_cond_signal(g_threadCond);
4695 oc_mutex_unlock(g_threadMutex);
4697 oc_mutex_lock(g_deviceScanRetryDelayMutex);
4698 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4699 oc_cond_signal(g_deviceScanRetryDelayCond);
4700 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
4702 oc_mutex_lock(g_threadScanIntervalMutex);
4703 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4704 oc_cond_signal(g_threadScanIntervalCond);
4705 oc_mutex_unlock(g_threadScanIntervalMutex);
4707 oc_mutex_lock(g_threadSendMutex);
4708 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
4709 oc_cond_signal(g_deviceDescCond);
4710 oc_mutex_unlock(g_threadSendMutex);
4712 oc_cond_free(g_deviceDescCond);
4713 oc_cond_free(g_threadCond);
4714 oc_cond_free(g_threadWriteCharacteristicCond);
4715 oc_cond_free(g_deviceScanRetryDelayCond);
4716 oc_cond_free(g_threadScanIntervalCond);
4718 g_deviceDescCond = NULL;
4719 g_threadCond = NULL;
4720 g_threadWriteCharacteristicCond = NULL;
4721 g_deviceScanRetryDelayCond = NULL;
4722 g_threadScanIntervalCond = NULL;
4726 (*g_jvm)->DetachCurrentThread(g_jvm);
4731 CAResult_t CAInitializeLEGattClient()
4733 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4734 CALEClientInitialize();
4735 return CA_STATUS_OK;
4738 void CATerminateLEGattClient()
4740 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
4741 CAStopLEGattClient();
4742 CALEClientTerminate();
4743 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
4746 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4747 uint32_t dataLen, CALETransferType_t type,
4750 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
4751 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4753 if (LE_UNICAST != type || position < 0)
4755 OIC_LOG(ERROR, TAG, "this request is not unicast");
4756 return CA_STATUS_INVALID_PARAM;
4759 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4762 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4764 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4765 VERIFY_NON_NULL(data, TAG, "data is null");
4767 return CALEClientSendMulticastMessage(data, dataLen);
4770 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4773 g_CABLEClientDataReceivedCallback = callback;
4777 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4779 g_threadPoolHandle = handle;
4782 CAResult_t CAGetLEAddress(char **local_address)
4784 VERIFY_NON_NULL(local_address, TAG, "local_address");
4785 return CA_NOT_SUPPORTED;
4788 JNIEXPORT void JNICALL
4789 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4792 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4793 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4794 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4795 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4797 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4798 CACheckJNIException(env);
4801 JNIEXPORT void JNICALL
4802 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
4806 OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
4807 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4808 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4809 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4811 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4812 CACheckJNIException(env);
4815 JNIEXPORT void JNICALL
4816 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4819 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4820 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4821 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4822 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4824 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4825 CACheckJNIException(env);
4828 JNIEXPORT void JNICALL
4829 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4832 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4833 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4834 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4836 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4837 if (CA_STATUS_OK != res)
4839 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4843 JNIEXPORT void JNICALL
4844 Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
4847 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4848 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4853 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
4858 "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
4862 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
4866 OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
4870 OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
4876 * Class: org_iotivity_ca_jar_caleinterface
4877 * Method: CALeGattConnectionStateChangeCallback
4878 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4880 JNIEXPORT void JNICALL
4881 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4887 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4889 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4890 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4891 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4893 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4895 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4898 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4902 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4905 OIC_LOG(ERROR, TAG, "address is null");
4906 CACheckJNIException(env);
4909 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4911 if (state_connected == newstate)
4913 OIC_LOG(DEBUG, TAG, "LE is connected");
4914 if (GATT_SUCCESS == status)
4916 CAResult_t res = CALEUpdateDeviceState(address,
4917 CA_LE_CONNECTION_STATE,
4920 g_deviceStateListMutex);
4921 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4922 if (CA_STATUS_OK != res)
4924 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4928 res = CALEClientAddGattobjToList(env, gatt);
4929 if (CA_STATUS_OK != res)
4931 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4935 res = CALEClientDiscoverServices(env, gatt);
4936 if (CA_STATUS_OK != res)
4938 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4944 OIC_LOG(INFO, TAG, "unknown status");
4945 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4948 else // STATE_DISCONNECTED == newstate
4950 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4952 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
4953 g_deviceStateList, g_deviceStateListMutex))
4955 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
4956 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4959 g_deviceStateListMutex);
4960 if (CA_STATUS_OK != res)
4962 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4966 CAResult_t res = CALEUpdateDeviceState(address,
4967 CA_LE_CONNECTION_STATE,
4970 g_deviceStateListMutex);
4971 if (CA_STATUS_OK != res)
4973 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4975 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4977 res = CALEClientGattClose(env, gatt);
4978 if (CA_STATUS_OK != res)
4980 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4983 if (CALECheckConnectionStateValue(status))
4985 // this state is unexpected reason to disconnect
4986 // if the reason is suitable, connection logic of the device will be destroyed.
4987 OIC_LOG(INFO, TAG, "connection logic destroy");
4991 // other reason except for gatt_success is expected to running
4992 // background connection in BT platform.
4993 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4995 CALEClientUpdateSendCnt(env);
5001 CALEClientSendFinish(env, gatt);
5006 * Class: org_iotivity_ca_jar_caleinterface
5007 * Method: CALeGattServicesDiscoveredCallback
5008 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
5010 JNIEXPORT void JNICALL
5011 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
5016 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
5017 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5018 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5019 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5021 if (GATT_SUCCESS != status) // discovery error
5023 CALEClientSendFinish(env, gatt);
5027 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5030 CALEClientSendFinish(env, gatt);
5034 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5037 CACheckJNIException(env);
5038 CALEClientSendFinish(env, gatt);
5042 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
5045 OIC_LOG(ERROR, TAG, "jni_uuid is null");
5049 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
5050 if (!jni_obj_GattCharacteristic)
5052 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
5056 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
5057 jni_obj_GattCharacteristic);
5058 if (CA_STATUS_OK != res)
5060 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
5064 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
5065 if (CA_STATUS_OK != res)
5067 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
5069 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
5070 g_deviceStateList, g_deviceStateListMutex);
5071 if (CA_STATUS_OK != res)
5073 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5077 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5078 STATE_SERVICE_CONNECTED,
5080 g_deviceStateListMutex);
5081 if (CA_STATUS_OK != res)
5083 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5087 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5088 if (CA_STATUS_OK != res)
5090 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5096 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
5097 g_deviceStateList, g_deviceStateListMutex);
5098 if (CA_STATUS_OK != res)
5100 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
5105 #ifdef SCAN_INTERVAL
5106 // reset interval scan logic
5107 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
5110 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
5111 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5116 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
5117 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5118 CALEClientSendFinish(env, gatt);
5123 * Class: org_iotivity_ca_jar_caleinterface
5124 * Method: CALeGattCharacteristicWritjclasseCallback
5125 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
5127 JNIEXPORT void JNICALL
5128 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
5129 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
5131 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
5132 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5133 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5134 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5136 // send success & signal
5137 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5143 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5146 CACheckJNIException(env);
5150 if (GATT_SUCCESS != status) // error case
5152 OIC_LOG(ERROR, TAG, "send failure");
5155 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5156 if (CA_STATUS_OK != res)
5158 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
5159 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5160 g_isSignalSetFlag = true;
5161 oc_cond_signal(g_threadWriteCharacteristicCond);
5162 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5164 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5167 g_deviceStateListMutex);
5168 if (CA_STATUS_OK != res)
5170 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5173 if (g_clientErrorCallback)
5175 jint length = (*env)->GetArrayLength(env, data);
5176 CACheckJNIException(env);
5177 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
5178 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
5179 false, "writeChar failure");
5182 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5188 OIC_LOG(DEBUG, TAG, "send success");
5189 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5192 g_deviceStateListMutex);
5193 if (CA_STATUS_OK != res)
5195 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5198 oc_mutex_lock(g_threadWriteCharacteristicMutex);
5199 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
5200 g_isSignalSetFlag = true;
5201 oc_cond_signal(g_threadWriteCharacteristicCond);
5202 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
5204 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
5205 (*env)->GetArrayLength(env, data),
5206 true, "writeChar success");
5209 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5215 CALEClientSendFinish(env, gatt);
5220 * Class: org_iotivity_ca_jar_caleinterface
5221 * Method: CALeGattCharacteristicChangedCallback
5222 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
5224 JNIEXPORT void JNICALL
5225 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
5226 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
5228 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
5229 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5230 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5231 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5232 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
5234 // get Byte Array and convert to uint8_t*
5235 jint length = (*env)->GetArrayLength(env, data);
5238 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
5239 CACheckJNIException(env);
5241 uint8_t* receivedData = OICMalloc(length);
5244 OIC_LOG(ERROR, TAG, "receivedData is null");
5248 memcpy(receivedData, jni_byte_responseData, length);
5249 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
5251 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5254 OIC_LOG(ERROR, TAG, "jni_address is null");
5255 OICFree(receivedData);
5259 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5262 OIC_LOG(ERROR, TAG, "address is null");
5263 CACheckJNIException(env);
5264 OICFree(receivedData);
5268 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
5269 receivedData, length);
5271 uint32_t sentLength = 0;
5272 oc_mutex_lock(g_bleServerBDAddressMutex);
5273 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
5274 oc_mutex_unlock(g_bleServerBDAddressMutex);
5276 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5280 * Class: org_iotivity_ca_jar_caleinterface
5281 * Method: CALeGattDescriptorWriteCallback
5282 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
5284 JNIEXPORT void JNICALL
5285 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
5289 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
5290 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
5291 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
5292 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
5294 if (GATT_SUCCESS != status) // error
5299 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5305 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5308 CACheckJNIException(env);
5312 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
5313 STATE_SERVICE_CONNECTED,
5315 g_deviceStateListMutex);
5316 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5317 if (CA_STATUS_OK != res)
5319 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5323 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
5324 if (CA_STATUS_OK != res)
5326 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
5334 CALEClientSendFinish(env, gatt);
5338 JNIEXPORT void JNICALL
5339 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
5345 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
5346 "mtu[%d-including Header size 3 byte]", status, mtu);
5350 if (0 == status || 133 == status)
5354 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
5355 if (CA_STATUS_OK != res)
5357 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
5362 OIC_LOG(INFO, TAG, "mtu nego is done");
5363 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
5366 CALEClientSendFinish(env, gatt);
5370 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
5373 CACheckJNIException(env);
5374 (*env)->DeleteLocalRef(env, jni_address);
5375 CALEClientSendFinish(env, gatt);
5380 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
5381 g_deviceStateList, g_deviceStateListMutex);
5382 if (CA_STATUS_OK != res)
5384 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
5387 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
5388 STATE_SEND_MTU_NEGO_SUCCESS,
5390 g_deviceStateListMutex);
5391 if (CA_STATUS_OK != res)
5393 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
5395 CALEClientUpdateSendCnt(env);
5396 (*env)->ReleaseStringUTFChars(env, jni_address, address);
5397 (*env)->DeleteLocalRef(env, jni_address);