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")
43 #define MICROSECS_PER_SEC 1000000
44 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
46 #define WAIT_TIME_SCANNED_CHECKING 30
48 #define GATT_CONNECTION_PRIORITY_BALANCED 0
49 #define GATT_FAILURE 257
50 #define GATT_INSUFFICIENT_AUTHENTICATION 5
51 #define GATT_INSUFFICIENT_ENCRYPTION 15
52 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
53 #define GATT_INVALID_OFFSET 7
54 #define GATT_READ_NOT_PERMITTED 2
55 #define GATT_REQUEST_NOT_SUPPORTED 6
56 #define GATT_WRITE_NOT_PERMITTED 3
58 static ca_thread_pool_t g_threadPoolHandle = NULL;
61 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
62 static u_arraylist_t *g_gattObjectList = NULL;
63 static u_arraylist_t *g_deviceStateList = NULL;
65 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
66 static CABLEErrorHandleCallback g_clientErrorCallback;
67 static jobject g_leScanCallback = NULL;
68 static jobject g_leGattCallback = NULL;
69 static jobject g_context = NULL;
70 static jobjectArray g_uuidList = NULL;
72 // it will be prevent to start send logic when adapter has stopped.
73 static bool g_isStartedLEClient = false;
75 static jbyteArray g_sendBuffer = NULL;
76 static uint32_t g_targetCnt = 0;
77 static uint32_t g_currentSentCnt = 0;
78 static bool g_isFinishedSendData = false;
79 static oc_mutex g_SendFinishMutex = NULL;
80 static oc_mutex g_threadMutex = NULL;
81 static oc_cond g_threadCond = NULL;
82 static oc_cond g_deviceDescCond = NULL;
84 static oc_mutex g_threadSendMutex = NULL;
85 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
86 static oc_cond g_threadWriteCharacteristicCond = NULL;
87 static bool g_isSignalSetFlag = false;
89 static oc_mutex g_bleReqRespClientCbMutex = NULL;
90 static oc_mutex g_bleServerBDAddressMutex = NULL;
92 static oc_mutex g_deviceListMutex = NULL;
93 static oc_mutex g_gattObjectMutex = NULL;
94 static oc_mutex g_deviceStateListMutex = NULL;
96 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
97 static oc_cond g_deviceScanRetryDelayCond = NULL;
99 static oc_mutex g_threadScanIntervalMutex = NULL;
100 static oc_cond g_threadScanIntervalCond = NULL;
102 static oc_mutex g_threadSendStateMutex = NULL;
104 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
105 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
106 static int32_t g_intervalCount = 0;
107 static bool g_isWorkingScanThread = false;
108 static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
109 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
111 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
113 static bool g_setHighQoS = true;
116 * check if retry logic for connection routine has to be stopped or not.
117 * in case of error value including this method, connection routine has to be stopped.
118 * since there is no retry logic for this error reason in this client.
119 * @param state constant value of bluetoothgatt.
120 * @return true - waiting for background connection in BT platform.
121 * false - connection routine has to be stopped.
123 static bool CALECheckConnectionStateValue(jint state)
127 case GATT_CONNECTION_PRIORITY_BALANCED:
129 case GATT_INSUFFICIENT_AUTHENTICATION:
130 case GATT_INSUFFICIENT_ENCRYPTION:
131 case GATT_INVALID_ATTRIBUTE_LENGTH:
132 case GATT_INVALID_OFFSET:
133 case GATT_READ_NOT_PERMITTED:
134 case GATT_REQUEST_NOT_SUPPORTED:
135 case GATT_WRITE_NOT_PERMITTED:
142 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
143 CALEScanState_t nextScanningStep)
145 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d, next scan state will be %d",
146 g_scanIntervalTime, intervalTime, nextScanningStep);
148 // previous time should be stored.
149 if (0 < workingCount)
151 g_scanIntervalTimePrev = g_scanIntervalTime;
153 g_scanIntervalTime = intervalTime;
154 g_intervalCount = workingCount;
155 g_nextScanningStep = nextScanningStep;
158 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
159 CALEScanState_t nextScanningStep)
161 if (intervalTime == g_scanIntervalTime
162 && workingCount == g_intervalCount
163 && nextScanningStep == g_nextScanningStep)
165 OIC_LOG(DEBUG, TAG, "setting duplicate interval time");
169 CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
170 oc_cond_signal(g_threadScanIntervalCond);
173 static void CALEScanThread(void* object)
177 bool isAttached = false;
179 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
182 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
186 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
192 oc_mutex_lock(g_threadScanIntervalMutex);
193 while(g_isWorkingScanThread)
195 OIC_LOG(DEBUG, TAG, "scan waiting time out");
196 if (BLE_SCAN_ENABLE == g_curScanningStep)
199 CAResult_t ret = CALEClientStopScan();
200 if (CA_STATUS_OK != ret)
202 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
205 else if (BLE_SCAN_DISABLE == g_curScanningStep)
208 CAResult_t ret = CALEClientStartScan();
209 if (CA_STATUS_OK != ret)
211 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
216 OIC_LOG(DEBUG, TAG, "scan thread is started");
218 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
221 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
222 if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
223 g_threadScanIntervalMutex,
224 g_scanIntervalTime * MICROSECS_PER_SEC))
226 // called signal scan thread will be terminated
227 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
228 if (BLE_SCAN_DISABLE == g_nextScanningStep)
230 g_curScanningStep = BLE_SCAN_ENABLE;
234 g_curScanningStep = BLE_SCAN_DISABLE;
239 if (BLE_SCAN_ENABLE == g_curScanningStep)
241 if (g_intervalCount > 0)
243 if (g_intervalCount == 1)
245 OIC_LOG(DEBUG, TAG, "reset default time");
246 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
249 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
251 g_curScanningStep = BLE_SCAN_DISABLE;
255 g_curScanningStep = BLE_SCAN_ENABLE;
259 oc_mutex_unlock(g_threadScanIntervalMutex);
263 (*g_jvm)->DetachCurrentThread(g_jvm);
267 CAResult_t CALEClientStartScanWithInterval()
269 if (g_isWorkingScanThread)
271 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
275 // initialize scan flags
276 g_curScanningStep = BLE_SCAN_NONE;
277 g_isWorkingScanThread = true;
279 g_scanIntervalTime = g_scanIntervalTimePrev;
280 g_nextScanningStep = BLE_SCAN_ENABLE;
282 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
283 CALEScanThread, NULL))
285 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
286 g_isWorkingScanThread = false;
287 return CA_STATUS_FAILED;
293 void CALEClientStopScanWithInterval()
295 g_isWorkingScanThread = false;
296 oc_cond_signal(g_threadScanIntervalCond);
300 void CALEClientJniInit()
302 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
303 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
306 void CALEClientJNISetContext()
308 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
309 g_context = (jobject) CANativeJNIGetContext();
312 CAResult_t CALECreateJniInterfaceObject()
314 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
318 OIC_LOG(ERROR, TAG, "g_context is null");
319 return CA_STATUS_FAILED;
324 OIC_LOG(ERROR, TAG, "g_jvm is null");
325 return CA_STATUS_FAILED;
328 bool isAttached = false;
330 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
333 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
337 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
338 return CA_STATUS_FAILED;
343 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
344 "getApplicationContext",
345 "()Landroid/content/Context;");
347 if (!mid_getApplicationContext)
349 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
350 return CA_STATUS_FAILED;
353 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
354 mid_getApplicationContext);
355 if (!jApplicationContext)
357 OIC_LOG(ERROR, TAG, "Could not get application context");
361 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
362 if (!jni_LEInterface)
364 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
368 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
369 "(Landroid/content/Context;)V");
370 if (!LeInterfaceConstructorMethod)
372 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
376 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
377 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
381 (*g_jvm)->DetachCurrentThread(g_jvm);
387 CACheckJNIException(env);
390 (*g_jvm)->DetachCurrentThread(g_jvm);
393 return CA_STATUS_FAILED;
396 CAResult_t CALEClientInitialize()
398 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
404 OIC_LOG(ERROR, TAG, "g_jvm is null");
405 return CA_STATUS_FAILED;
408 bool isAttached = false;
410 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
413 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
417 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
418 return CA_STATUS_FAILED;
423 CAResult_t ret = CALECheckPlatformVersion(env, 18);
424 if (CA_STATUS_OK != ret)
426 OIC_LOG(ERROR, TAG, "it is not supported");
430 (*g_jvm)->DetachCurrentThread(g_jvm);
436 ret = CALEClientInitGattMutexVaraibles();
437 if (CA_STATUS_OK != ret)
439 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
440 CALEClientTerminateGattMutexVariables();
444 (*g_jvm)->DetachCurrentThread(g_jvm);
450 g_deviceDescCond = oc_cond_new();
452 // init mutex for send logic
453 g_threadCond = oc_cond_new();
454 g_threadWriteCharacteristicCond = oc_cond_new();
455 g_deviceScanRetryDelayCond = oc_cond_new();
456 g_threadScanIntervalCond = oc_cond_new();
458 CALEClientCreateDeviceList();
459 CALEClientJNISetContext();
461 ret = CALEClientCreateUUIDList();
462 if (CA_STATUS_OK != ret)
464 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
468 (*g_jvm)->DetachCurrentThread(g_jvm);
474 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
475 if (CA_STATUS_OK != ret)
477 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
481 (*g_jvm)->DetachCurrentThread(g_jvm);
486 g_isStartedLEClient = true;
490 (*g_jvm)->DetachCurrentThread(g_jvm);
496 void CALEClientTerminate()
498 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
502 OIC_LOG(ERROR, TAG, "g_jvm is null");
506 bool isAttached = false;
508 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
511 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
515 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
522 CAResult_t ret = CALEClientStopScan();
523 if (CA_STATUS_OK != ret)
525 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
528 if (g_leScanCallback)
530 (*env)->DeleteGlobalRef(env, g_leScanCallback);
531 g_leScanCallback = NULL;
534 if (g_leGattCallback)
536 (*env)->DeleteGlobalRef(env, g_leGattCallback);
537 g_leGattCallback = NULL;
542 (*env)->DeleteGlobalRef(env, g_sendBuffer);
548 (*env)->DeleteGlobalRef(env, g_uuidList);
552 ret = CALERemoveAllDeviceState(g_deviceStateList,
553 g_deviceStateListMutex);
554 if (CA_STATUS_OK != ret)
556 OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
559 ret = CALEClientRemoveAllScanDevices(env);
560 if (CA_STATUS_OK != ret)
562 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
565 ret = CALEClientRemoveAllGattObjs(env);
566 if (CA_STATUS_OK != ret)
568 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
571 CALEClientSetSendFinishFlag(true);
573 CALEClientTerminateGattMutexVariables();
574 CALEClientDestroyJniInterface();
576 oc_cond_free(g_deviceDescCond);
577 oc_cond_free(g_threadCond);
578 oc_cond_free(g_threadWriteCharacteristicCond);
579 oc_cond_free(g_deviceScanRetryDelayCond);
580 oc_cond_free(g_threadScanIntervalCond);
582 g_deviceDescCond = NULL;
584 g_threadWriteCharacteristicCond = NULL;
585 g_deviceScanRetryDelayCond = NULL;
586 g_threadScanIntervalCond = NULL;
588 g_isSignalSetFlag = false;
591 CALEClientStopScanWithInterval();
595 (*g_jvm)->DetachCurrentThread(g_jvm);
599 CAResult_t CALEClientDestroyJniInterface()
601 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
605 OIC_LOG(ERROR, TAG, "g_jvm is null");
606 return CA_STATUS_FAILED;
609 bool isAttached = false;
611 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
614 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
618 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
619 return CA_STATUS_FAILED;
624 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
625 if (!jni_LeInterface)
627 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
631 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
632 "destroyLeInterface",
634 if (!jni_InterfaceDestroyMethod)
636 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
640 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
642 if (CACheckJNIException(env))
644 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
648 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
652 (*g_jvm)->DetachCurrentThread(g_jvm);
658 CACheckJNIException(env);
663 (*g_jvm)->DetachCurrentThread(g_jvm);
666 return CA_STATUS_FAILED;
669 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
671 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
672 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
676 CAResult_t res = CALEClientDisconnect(env, gatt);
677 if (CA_STATUS_OK != res)
679 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
682 CALEClientUpdateSendCnt(env);
685 CAResult_t CALEClientSendNegotiationMessage(const char* address)
687 VERIFY_NON_NULL(address, TAG, "address is null");
689 return CALEClientSendUnicastMessageImpl(address, NULL, 0);
692 CAResult_t CALEClientSendUnicastMessage(const char* address,
694 const uint32_t dataLen)
696 VERIFY_NON_NULL(address, TAG, "address is null");
697 VERIFY_NON_NULL(data, TAG, "data is null");
699 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
702 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
703 const uint32_t dataLen)
705 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
706 VERIFY_NON_NULL(data, TAG, "data is null");
710 OIC_LOG(ERROR, TAG, "g_jvm is null");
711 return CA_STATUS_FAILED;
714 bool isAttached = false;
716 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
719 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
723 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
724 return CA_STATUS_FAILED;
729 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
730 if (CA_STATUS_OK != ret)
732 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
737 (*g_jvm)->DetachCurrentThread(g_jvm);
743 CAResult_t CALEClientStartUnicastServer(const char* address)
748 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
750 return CA_NOT_SUPPORTED;
753 CAResult_t CALEClientStartMulticastServer()
755 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
757 return CA_NOT_SUPPORTED;
760 void CALEClientStopUnicastServer()
762 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
765 void CALEClientStopMulticastServer()
767 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
770 void CALEClientSetCallback(CAPacketReceiveCallback callback)
772 g_packetReceiveCallback = callback;
775 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
777 g_clientErrorCallback = callback;
780 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
782 VERIFY_NON_NULL(env, TAG, "env");
786 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
787 return CA_STATUS_FAILED;
790 if (0 == u_arraylist_length(g_deviceList) // multicast
791 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
793 // Wait for LE peripherals to be discovered.
795 // Number of times to wait for discovery to complete.
796 static size_t const RETRIES = 5;
798 static uint64_t const TIMEOUT =
799 2 * MICROSECS_PER_SEC; // Microseconds
801 // set scan interval and start scan
802 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1, BLE_SCAN_ENABLE);
804 bool devicesDiscovered = false;
805 for (size_t i = 0; i < RETRIES; ++i)
807 OIC_LOG(DEBUG, TAG, "waiting for target device");
808 if (oc_cond_wait_for(g_deviceDescCond,
810 TIMEOUT) == OC_WAIT_SUCCESS)
812 OIC_LOG(DEBUG, TAG, "time out");
813 oc_mutex_lock(g_deviceListMutex);
814 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
815 oc_mutex_unlock(g_deviceListMutex);
817 if (0 < scannedDeviceLen)
819 if (!address // multicast
820 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
822 devicesDiscovered = true;
829 OIC_LOG(INFO, TAG, "waiting..");
831 oc_mutex_lock(g_deviceScanRetryDelayMutex);
832 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
833 g_deviceScanRetryDelayMutex,
834 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
836 OIC_LOG(INFO, TAG, "finish to waiting for target device");
837 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
840 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
843 // checking whether a target device is found while waiting for time-out.
844 if (CALEClientIsDeviceInScanDeviceList(env, address))
846 devicesDiscovered = true;
855 // reset scan interval time after checking scanned devices
856 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
858 // time out for scanning devices
859 if (!devicesDiscovered)
861 return CA_STATUS_FAILED;
866 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
873 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
874 const uint32_t dataLen)
876 OIC_LOG_V(INFO, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
878 VERIFY_NON_NULL(address, TAG, "address is null");
882 OIC_LOG(ERROR, TAG, "g_jvm is null");
883 return CA_STATUS_FAILED;
886 bool isAttached = false;
888 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
891 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
894 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
895 return CA_STATUS_FAILED;
900 oc_mutex_lock(g_threadSendMutex);
902 CALEClientSetSendFinishFlag(false);
904 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
905 if (CA_STATUS_OK != ret)
907 OIC_LOG(INFO, TAG, "there is no scanned device");
911 if (g_context && g_deviceList)
913 uint32_t length = u_arraylist_length(g_deviceList);
914 for (uint32_t index = 0; index < length; index++)
916 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
919 OIC_LOG(ERROR, TAG, "jarrayObj is null");
923 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
926 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
930 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
933 OIC_LOG(ERROR, TAG, "setAddress is null");
934 CACheckJNIException(env);
938 if (!strcmp(setAddress, address))
940 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
941 (*env)->DeleteLocalRef(env, jni_setAddress);
945 (*env)->DeleteGlobalRef(env, g_sendBuffer);
949 if (data && dataLen > 0)
951 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
952 CACheckJNIException(env);
953 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
954 CACheckJNIException(env);
955 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
956 CACheckJNIException(env);
959 // Target device to send message is just one.
962 ret = CALEClientSendData(env, jarrayObj);
963 if (CA_STATUS_OK != ret)
965 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
969 OIC_LOG(INFO, TAG, "wake up");
972 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
973 (*env)->DeleteLocalRef(env, jni_setAddress);
977 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
979 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
980 // if there is no connection state.
981 oc_mutex_lock(g_threadMutex);
982 if (!g_isFinishedSendData)
984 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
985 oc_cond_wait(g_threadCond, g_threadMutex);
986 OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
988 oc_mutex_unlock(g_threadMutex);
992 (*g_jvm)->DetachCurrentThread(g_jvm);
995 oc_mutex_unlock(g_threadSendMutex);
996 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
997 if (CALEIsValidState(address, CA_LE_SEND_STATE,
1000 g_deviceStateListMutex))
1002 OIC_LOG(INFO, TAG, "send success");
1005 else if (CALEIsValidState(address, CA_LE_SEND_STATE,
1006 STATE_SEND_MTU_NEGO_SUCCESS,
1008 g_deviceStateListMutex))
1010 OIC_LOG(INFO, TAG, "mtu nego success");
1015 OIC_LOG(ERROR, TAG, "send failure");
1016 ret = CA_SEND_FAILED;
1020 CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
1023 g_deviceStateListMutex);
1024 if (CA_STATUS_OK != resetRet)
1026 OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
1027 ret = CA_SEND_FAILED;
1036 (*g_jvm)->DetachCurrentThread(g_jvm);
1039 oc_mutex_unlock(g_threadSendMutex);
1040 return CA_SEND_FAILED;
1043 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1044 const uint32_t dataLen)
1046 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1047 VERIFY_NON_NULL(data, TAG, "data is null");
1048 VERIFY_NON_NULL(env, TAG, "env is null");
1052 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1053 return CA_STATUS_FAILED;
1056 oc_mutex_lock(g_threadSendMutex);
1058 CALEClientSetSendFinishFlag(false);
1060 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1063 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1064 g_sendBuffer = NULL;
1067 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1068 if (CA_STATUS_OK != res)
1070 OIC_LOG(INFO, TAG, "there is no scanned device");
1074 uint32_t length = u_arraylist_length(g_deviceList);
1075 g_targetCnt = length;
1077 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1078 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1079 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1081 for (uint32_t index = 0; index < length; index++)
1083 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1086 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1090 res = CALEClientSendData(env, jarrayObj);
1091 if (res != CA_STATUS_OK)
1093 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1097 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1099 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1100 oc_mutex_lock(g_threadMutex);
1101 if (!g_isFinishedSendData)
1103 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1104 oc_cond_wait(g_threadCond, g_threadMutex);
1105 OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
1107 oc_mutex_unlock(g_threadMutex);
1108 oc_mutex_unlock(g_threadSendMutex);
1109 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1110 return CA_STATUS_OK;
1113 oc_mutex_unlock(g_threadSendMutex);
1114 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1115 return CA_SEND_FAILED;
1118 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1120 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1121 VERIFY_NON_NULL(device, TAG, "device is null");
1122 VERIFY_NON_NULL(env, TAG, "env is null");
1124 // get BLE address from bluetooth device object.
1125 char* address = NULL;
1126 CALEState_t* state = NULL;
1127 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1130 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1131 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1134 OIC_LOG(ERROR, TAG, "address is not available");
1135 CACheckJNIException(env);
1136 return CA_STATUS_FAILED;
1138 oc_mutex_lock(g_deviceStateListMutex);
1139 state = CALEGetStateInfo(address, g_deviceStateList);
1140 oc_mutex_unlock(g_deviceStateListMutex);
1143 // Since disconnect event can be caused from BT stack while connection step is running.
1144 // DeviceState has to have current status for processing send failure.
1145 OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
1146 CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
1148 STATE_SEND_PREPARING);
1149 if (CA_STATUS_OK != res)
1151 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
1154 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1156 return CA_STATUS_FAILED;
1161 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1163 // cancel previous connection request before connection
1164 // if there is gatt object in g_gattObjectList.
1167 jobject gatt = CALEClientGetGattObjInList(env, address);
1170 CAResult_t res = CALEClientDisconnect(env, gatt);
1171 if (CA_STATUS_OK != res)
1173 OIC_LOG(INFO, TAG, "there is no gatt object");
1176 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1179 // connection request
1180 jobject newGatt = CALEClientConnect(env, device,
1182 if (NULL == newGatt)
1184 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1185 return CA_STATUS_FAILED;
1190 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1191 STATE_SERVICE_CONNECTED,
1193 g_deviceStateListMutex))
1195 OIC_LOG(INFO, TAG, "GATT has already connected");
1197 jobject gatt = CALEClientGetGattObjInList(env, address);
1200 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1201 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1202 return CA_STATUS_FAILED;
1205 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1206 if (CA_STATUS_OK != ret)
1208 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1209 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1212 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1214 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1217 g_deviceStateListMutex))
1219 OIC_LOG(INFO, TAG, "service connecting...");
1221 else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1224 g_deviceStateListMutex))
1226 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1228 // cancel previous connection request before connection
1229 // if there is gatt object in g_gattObjectList.
1232 jobject gatt = CALEClientGetGattObjInList(env, address);
1235 CAResult_t res = CALEClientDisconnect(env, gatt);
1236 if (CA_STATUS_OK != res)
1238 OIC_LOG(INFO, TAG, "there is no gatt object");
1241 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1244 OIC_LOG(DEBUG, TAG, "start to connect LE");
1245 jobject gatt = CALEClientConnect(env, device,
1246 CALEGetFlagFromState(env, jni_address,
1247 CA_LE_AUTO_CONNECT_FLAG,
1249 g_deviceStateListMutex));
1253 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1254 return CA_STATUS_FAILED;
1259 return CA_STATUS_OK;
1262 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1264 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1265 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1267 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1268 "()Landroid/bluetooth/BluetoothDevice;");
1269 if (!jni_mid_getDevice)
1271 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1275 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1276 if (!jni_obj_device)
1278 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1279 CACheckJNIException(env);
1283 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1286 OIC_LOG(ERROR, TAG, "jni_address is null");
1287 CACheckJNIException(env);
1297 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1300 OIC_LOG(DEBUG, TAG, "Gatt Close");
1301 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1302 VERIFY_NON_NULL(env, TAG, "env is null");
1304 // get BluetoothGatt method
1305 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1306 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1307 if (!jni_mid_closeGatt)
1309 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1310 return CA_STATUS_OK;
1313 // call disconnect gatt method
1314 OIC_LOG(DEBUG, TAG, "request to close GATT");
1315 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1317 if (CACheckJNIException(env))
1319 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1320 return CA_STATUS_FAILED;
1323 return CA_STATUS_OK;
1326 CAResult_t CALEClientStartScan()
1328 if (!g_isStartedLEClient)
1330 OIC_LOG(ERROR, TAG, "LE client is not started");
1331 return CA_STATUS_FAILED;
1336 OIC_LOG(ERROR, TAG, "g_jvm is null");
1337 return CA_STATUS_FAILED;
1340 bool isAttached = false;
1342 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1345 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1348 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1349 return CA_STATUS_FAILED;
1354 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1356 CAResult_t ret = CA_STATUS_OK;
1357 // scan gatt server with UUID
1358 if (g_leScanCallback && g_uuidList)
1361 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1363 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1365 if (CA_STATUS_OK != ret)
1367 if (CA_ADAPTER_NOT_ENABLED == ret)
1369 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1373 OIC_LOG(ERROR, TAG, "start scan has failed");
1380 (*g_jvm)->DetachCurrentThread(g_jvm);
1386 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1388 VERIFY_NON_NULL(callback, TAG, "callback is null");
1389 VERIFY_NON_NULL(env, TAG, "env is null");
1391 if (!CALEIsEnableBTAdapter(env))
1393 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1394 return CA_ADAPTER_NOT_ENABLED;
1397 // get default bt adapter class
1398 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1399 if (!jni_cid_BTAdapter)
1401 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1402 CACheckJNIException(env);
1403 return CA_STATUS_FAILED;
1406 // get remote bt adapter method
1407 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1408 "getDefaultAdapter",
1409 METHODID_OBJECTNONPARAM);
1410 if (!jni_mid_getDefaultAdapter)
1412 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1413 CACheckJNIException(env);
1414 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1415 return CA_STATUS_FAILED;
1418 // get start le scan method
1419 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1420 "(Landroid/bluetooth/BluetoothAdapter$"
1421 "LeScanCallback;)Z");
1422 if (!jni_mid_startLeScan)
1424 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1425 CACheckJNIException(env);
1426 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1427 return CA_STATUS_FAILED;
1430 // gat bt adapter object
1431 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1432 jni_mid_getDefaultAdapter);
1433 if (!jni_obj_BTAdapter)
1435 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1436 CACheckJNIException(env);
1437 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1438 return CA_STATUS_FAILED;
1441 // call start le scan method
1442 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1443 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1444 jni_mid_startLeScan, callback);
1445 if (!jni_obj_startLeScan)
1447 OIC_LOG(INFO, TAG, "startLeScan has failed");
1448 CACheckJNIException(env);
1452 OIC_LOG(DEBUG, TAG, "LeScan has started");
1455 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1456 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1457 return CA_STATUS_OK;
1460 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1462 VERIFY_NON_NULL(callback, TAG, "callback is null");
1463 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1464 VERIFY_NON_NULL(env, TAG, "env is null");
1466 if (!CALEIsEnableBTAdapter(env))
1468 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1469 return CA_ADAPTER_NOT_ENABLED;
1472 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1473 if (!jni_cid_BTAdapter)
1475 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1476 CACheckJNIException(env);
1477 return CA_STATUS_FAILED;
1480 // get remote bt adapter method
1481 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1482 "getDefaultAdapter",
1483 METHODID_OBJECTNONPARAM);
1484 if (!jni_mid_getDefaultAdapter)
1486 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1487 CACheckJNIException(env);
1488 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1489 return CA_STATUS_FAILED;
1492 // get start le scan method
1493 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1494 "([Ljava/util/UUID;Landroid/bluetooth/"
1495 "BluetoothAdapter$LeScanCallback;)Z");
1496 if (!jni_mid_startLeScan)
1498 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1499 CACheckJNIException(env);
1500 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1501 return CA_STATUS_FAILED;
1504 // get bt adapter object
1505 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1506 jni_mid_getDefaultAdapter);
1507 if (!jni_obj_BTAdapter)
1509 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1510 CACheckJNIException(env);
1511 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1512 return CA_STATUS_FAILED;
1515 // call start le scan method
1516 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1517 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1518 jni_mid_startLeScan, uuids, callback);
1519 if (!jni_obj_startLeScan)
1521 OIC_LOG(INFO, TAG, "startLeScan has failed");
1522 CACheckJNIException(env);
1526 OIC_LOG(DEBUG, TAG, "LeScan has started");
1529 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1530 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1531 return CA_STATUS_OK;
1534 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1536 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1537 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1540 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1543 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1547 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1548 "(Ljava/lang/String;)"
1549 "Ljava/util/UUID;");
1550 if (!jni_mid_fromString)
1552 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1556 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1557 CACheckJNIException(env);
1558 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1562 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1566 return jni_obj_uuid;
1569 CACheckJNIException(env);
1573 CAResult_t CALEClientStopScan()
1577 OIC_LOG(ERROR, TAG, "g_jvm is null");
1578 return CA_STATUS_FAILED;
1581 bool isAttached = false;
1583 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1586 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1589 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1590 return CA_STATUS_FAILED;
1595 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1596 if (CA_STATUS_OK != ret)
1598 if (CA_ADAPTER_NOT_ENABLED == ret)
1600 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1604 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1610 (*g_jvm)->DetachCurrentThread(g_jvm);
1616 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1618 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1619 VERIFY_NON_NULL(callback, TAG, "callback is null");
1620 VERIFY_NON_NULL(env, TAG, "env is null");
1622 if (!CALEIsEnableBTAdapter(env))
1624 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1625 return CA_ADAPTER_NOT_ENABLED;
1628 // get default bt adapter class
1629 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1630 if (!jni_cid_BTAdapter)
1632 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1633 CACheckJNIException(env);
1634 return CA_STATUS_FAILED;
1637 // get remote bt adapter method
1638 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1639 "getDefaultAdapter",
1640 METHODID_OBJECTNONPARAM);
1641 if (!jni_mid_getDefaultAdapter)
1643 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1644 CACheckJNIException(env);
1645 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1646 return CA_STATUS_FAILED;
1649 // get start le scan method
1650 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1651 "(Landroid/bluetooth/"
1652 "BluetoothAdapter$LeScanCallback;)V");
1653 if (!jni_mid_stopLeScan)
1655 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1656 CACheckJNIException(env);
1657 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1658 return CA_STATUS_FAILED;
1661 // gat bt adapter object
1662 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1663 jni_mid_getDefaultAdapter);
1664 if (!jni_obj_BTAdapter)
1666 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1667 CACheckJNIException(env);
1668 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1669 return CA_STATUS_FAILED;
1672 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1673 // call start le scan method
1674 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1675 if (CACheckJNIException(env))
1677 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1678 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1679 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1680 return CA_STATUS_FAILED;
1683 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1684 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1685 return CA_STATUS_OK;
1688 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1690 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1691 VERIFY_NON_NULL(env, TAG, "env is null");
1692 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1694 oc_mutex_lock(g_threadSendMutex);
1696 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1699 OIC_LOG(ERROR, TAG, "jni_address is not available");
1700 oc_mutex_unlock(g_threadSendMutex);
1701 return CA_STATUS_FAILED;
1704 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1707 OIC_LOG(ERROR, TAG, "address is not available");
1708 CACheckJNIException(env);
1709 oc_mutex_unlock(g_threadSendMutex);
1710 return CA_STATUS_FAILED;
1713 CAResult_t res = CA_STATUS_OK;
1714 if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1717 g_deviceStateListMutex))
1719 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1720 if (NULL == newGatt)
1722 OIC_LOG(INFO, TAG, "newGatt is not available");
1723 res = CA_STATUS_FAILED;
1726 oc_mutex_unlock(g_threadSendMutex);
1731 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1733 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1734 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1735 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1737 // reset scan interval time after checking scanned devices
1738 CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
1740 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1741 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1744 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1747 OIC_LOG(ERROR, TAG, "address is not available");
1751 // close the gatt service
1752 jobject gatt = CALEClientGetGattObjInList(env, address);
1755 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1756 if (CA_STATUS_OK != res)
1758 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1759 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1763 // clean previous gatt object after close profile service
1764 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1765 if (CA_STATUS_OK != res)
1767 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1768 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1772 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1775 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1778 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1782 // add new gatt object into g_gattObjectList
1783 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1784 if (CA_STATUS_OK != res)
1786 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1793 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1795 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1796 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1797 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1799 if (!g_leGattCallback)
1801 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1805 if (!CALEIsEnableBTAdapter(env))
1807 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1811 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1814 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1818 jobject jni_obj_connectGatt = NULL;
1819 jint jni_int_sdk = CALEGetBuildVersion(env);
1820 OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
1821 if (jni_int_sdk >= 23) // upper than API level 23
1823 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1825 "(Landroid/content/Context;ZLandroid/"
1826 "bluetooth/BluetoothGattCallback;I)"
1827 "Landroid/bluetooth/BluetoothGatt;");
1828 if (!jni_mid_connectGatt)
1830 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1834 jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
1835 OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
1836 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1837 jni_mid_connectGatt, NULL,
1838 autoconnect, g_leGattCallback,
1840 if (!jni_obj_connectGatt)
1842 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1843 CACheckJNIException(env);
1844 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1845 CALEClientUpdateSendCnt(env);
1850 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1853 else // lower than API level 23
1855 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1857 "(Landroid/content/Context;ZLandroid/"
1858 "bluetooth/BluetoothGattCallback;)"
1859 "Landroid/bluetooth/BluetoothGatt;");
1860 if (!jni_mid_connectGatt)
1862 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1866 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1867 jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1868 jni_mid_connectGatt,
1870 autoconnect, g_leGattCallback);
1871 if (!jni_obj_connectGatt)
1873 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1874 CACheckJNIException(env);
1875 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1876 CALEClientUpdateSendCnt(env);
1881 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1885 return jni_obj_connectGatt;
1888 bool CALEClientIsConnected(const char* address)
1890 if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
1891 STATE_SERVICE_CONNECTED,
1893 g_deviceStateListMutex))
1895 OIC_LOG(DEBUG, TAG, "current state is connected");
1898 OIC_LOG(DEBUG, TAG, "current state is not connected");
1902 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1904 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1906 VERIFY_NON_NULL(env, TAG, "env is null");
1907 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1909 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1910 if (!jni_cid_BTAdapter)
1912 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1916 // get remote bt adapter method
1917 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1918 "getDefaultAdapter",
1919 METHODID_OBJECTNONPARAM);
1920 if (!jni_mid_getDefaultAdapter)
1922 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1926 // gat bt adapter object
1927 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1928 jni_mid_getDefaultAdapter);
1929 if (!jni_obj_BTAdapter)
1931 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1935 // get closeProfileProxy method
1936 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1937 "closeProfileProxy",
1938 "(ILandroid/bluetooth/"
1939 "BluetoothProfile;)V");
1940 if (!jni_mid_closeProfileProxy)
1942 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1946 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1947 if (!jni_cid_BTProfile)
1949 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1953 // GATT - Constant value : 7 (0x00000007)
1954 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1958 OIC_LOG(ERROR, TAG, "id_gatt is null");
1962 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1963 CACheckJNIException(env);
1965 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1966 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1967 if (CACheckJNIException(env))
1969 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1970 return CA_STATUS_FAILED;
1973 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1974 return CA_STATUS_OK;
1977 CACheckJNIException(env);
1978 return CA_STATUS_FAILED;
1982 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1984 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1985 VERIFY_NON_NULL(env, TAG, "env is null");
1986 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1988 // get BluetoothGatt method
1989 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1990 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1991 "disconnect", "()V");
1992 if (!jni_mid_disconnectGatt)
1994 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1995 return CA_STATUS_FAILED;
1998 // call disconnect gatt method
1999 OIC_LOG(INFO, TAG, "CALL API - disconnect");
2000 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
2001 if (CACheckJNIException(env))
2003 OIC_LOG(ERROR, TAG, "disconnect has failed");
2004 return CA_STATUS_FAILED;
2007 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
2009 return CA_STATUS_OK;
2012 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
2014 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
2015 VERIFY_NON_NULL(env, TAG, "env is null");
2017 if (!g_gattObjectList)
2019 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2020 return CA_STATUS_OK;
2023 uint32_t length = u_arraylist_length(g_gattObjectList);
2024 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2025 for (uint32_t index = 0; index < length; index++)
2027 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2028 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2031 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2034 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2035 if (CA_STATUS_OK != res)
2037 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2042 return CA_STATUS_OK;
2045 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2047 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2048 VERIFY_NON_NULL(env, TAG, "env is null");
2050 if (!g_gattObjectList)
2052 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2053 return CA_STATUS_OK;
2056 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2059 OIC_LOG(ERROR, TAG, "address is null");
2060 CACheckJNIException(env);
2061 return CA_STATUS_FAILED;
2064 uint32_t length = u_arraylist_length(g_gattObjectList);
2065 for (uint32_t index = 0; index < length; index++)
2067 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2070 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2074 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2075 if (!jni_setAddress)
2077 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2078 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2079 return CA_STATUS_FAILED;
2082 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2085 OIC_LOG(ERROR, TAG, "setAddress is null");
2086 CACheckJNIException(env);
2087 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2088 return CA_STATUS_FAILED;
2091 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2092 if (!strcmp(address, setAddress))
2094 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2095 if (CA_STATUS_OK != res)
2097 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2098 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2099 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2100 return CA_STATUS_FAILED;
2102 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2103 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2104 return CA_STATUS_OK;
2106 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2108 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2110 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2111 return CA_STATUS_OK;
2114 CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
2116 VERIFY_NON_NULL(env, TAG, "env is null");
2117 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2119 if (!CALEIsEnableBTAdapter(env))
2121 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2122 return CA_ADAPTER_NOT_ENABLED;
2125 // get BluetoothGatt.requestMtu method
2126 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
2127 jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2128 "requestMtu", "(I)Z");
2129 if (!jni_mid_requestMtu)
2131 OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
2132 return CA_STATUS_FAILED;
2136 OIC_LOG(INFO, TAG, "CALL API - requestMtu");
2137 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
2140 OIC_LOG(ERROR, TAG, "requestMtu has failed");
2141 CACheckJNIException(env);
2142 return CA_STATUS_FAILED;
2145 return CA_STATUS_OK;
2148 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2150 VERIFY_NON_NULL(env, TAG, "env is null");
2151 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2153 if (!CALEIsEnableBTAdapter(env))
2155 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2156 return CA_ADAPTER_NOT_ENABLED;
2159 // get BluetoothGatt.discoverServices method
2160 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2161 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2162 "discoverServices", "()Z");
2163 if (!jni_mid_discoverServices)
2165 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2166 return CA_STATUS_FAILED;
2169 // call disconnect gatt method
2170 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2171 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2174 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2175 CACheckJNIException(env);
2176 return CA_STATUS_FAILED;
2179 return CA_STATUS_OK;
2182 static void CALEWriteCharacteristicThread(void* object)
2184 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2186 bool isAttached = false;
2188 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2191 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2195 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2201 jobject gatt = (jobject)object;
2202 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2203 if (CA_STATUS_OK != ret)
2205 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2210 (*g_jvm)->DetachCurrentThread(g_jvm);
2214 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2216 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2218 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2219 VERIFY_NON_NULL(env, TAG, "env is null");
2221 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2224 CALEClientSendFinish(env, gatt);
2225 return CA_STATUS_FAILED;
2228 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2231 CACheckJNIException(env);
2232 CALEClientSendFinish(env, gatt);
2233 return CA_STATUS_FAILED;
2236 oc_mutex_lock(g_threadSendStateMutex);
2238 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
2240 g_deviceStateListMutex))
2242 OIC_LOG(INFO, TAG, "current state is SENDING");
2243 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2244 oc_mutex_unlock(g_threadSendStateMutex);
2245 return CA_STATUS_OK;
2248 if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
2251 g_deviceStateListMutex))
2253 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
2254 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2255 CALEClientSendFinish(env, gatt);
2256 oc_mutex_unlock(g_threadSendStateMutex);
2257 return CA_STATUS_FAILED;
2260 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2262 oc_mutex_unlock(g_threadSendStateMutex);
2265 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2266 if (!jni_obj_character)
2268 CALEClientSendFinish(env, gatt);
2269 return CA_STATUS_FAILED;
2272 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2273 if (CA_STATUS_OK != ret)
2275 CALEClientSendFinish(env, gatt);
2276 return CA_STATUS_FAILED;
2279 // wait for callback for write Characteristic with success to sent data
2280 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2281 oc_mutex_lock(g_threadWriteCharacteristicMutex);
2282 if (!g_isSignalSetFlag)
2284 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2285 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
2286 g_threadWriteCharacteristicMutex,
2287 WAIT_TIME_WRITE_CHARACTERISTIC))
2289 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2290 g_isSignalSetFlag = false;
2291 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
2292 return CA_STATUS_FAILED;
2295 // reset flag set by writeCharacteristic Callback
2296 g_isSignalSetFlag = false;
2297 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
2299 CALEClientUpdateSendCnt(env);
2301 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2302 return CA_STATUS_OK;
2305 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2307 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2308 VERIFY_NON_NULL(env, TAG, "env is null");
2309 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2311 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2312 CACheckJNIException(env);
2313 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2314 CALEWriteCharacteristicThread, (void*)gattParam))
2316 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2317 return CA_STATUS_FAILED;
2320 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2321 return CA_STATUS_OK;
2324 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2325 jobject gattCharacteristic)
2327 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2328 VERIFY_NON_NULL(env, TAG, "env is null");
2329 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2330 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2332 if (!CALEIsEnableBTAdapter(env))
2334 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2335 return CA_STATUS_FAILED;
2338 // get BluetoothGatt.write characteristic method
2339 OIC_LOG(DEBUG, TAG, "write characteristic method");
2340 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2341 "writeCharacteristic",
2342 "(Landroid/bluetooth/"
2343 "BluetoothGattCharacteristic;)Z");
2344 if (!jni_mid_writeCharacteristic)
2346 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2347 return CA_STATUS_FAILED;
2350 // call disconnect gatt method
2351 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2352 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2353 jni_mid_writeCharacteristic,
2354 gattCharacteristic);
2357 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2361 CACheckJNIException(env);
2362 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2363 return CA_STATUS_FAILED;
2366 return CA_STATUS_OK;
2369 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2371 VERIFY_NON_NULL(env, TAG, "env is null");
2372 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2374 if (!CALEIsEnableBTAdapter(env))
2376 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2377 return CA_STATUS_FAILED;
2380 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2383 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2384 CACheckJNIException(env);
2385 return CA_STATUS_FAILED;
2388 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2389 if (!jni_obj_GattCharacteristic)
2391 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2392 return CA_STATUS_FAILED;
2395 OIC_LOG(DEBUG, TAG, "read characteristic method");
2396 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2397 "readCharacteristic",
2398 "(Landroid/bluetooth/"
2399 "BluetoothGattCharacteristic;)Z");
2400 if (!jni_mid_readCharacteristic)
2402 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2403 return CA_STATUS_FAILED;
2406 // call disconnect gatt method
2407 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2408 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2409 jni_obj_GattCharacteristic);
2412 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2416 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2417 CACheckJNIException(env);
2418 return CA_STATUS_FAILED;
2421 return CA_STATUS_OK;
2424 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2425 jobject characteristic)
2427 VERIFY_NON_NULL(env, TAG, "env is null");
2428 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2429 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2431 if (!CALEIsEnableBTAdapter(env))
2433 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2434 return CA_ADAPTER_NOT_ENABLED;
2437 // get BluetoothGatt.setCharacteristicNotification method
2438 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2439 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2440 "setCharacteristicNotification",
2441 "(Landroid/bluetooth/"
2442 "BluetoothGattCharacteristic;Z)Z");
2443 if (!jni_mid_setNotification)
2445 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2446 return CA_STATUS_FAILED;
2449 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2450 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2451 characteristic, JNI_TRUE);
2452 if (JNI_TRUE == ret)
2454 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2458 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2459 CACheckJNIException(env);
2460 return CA_STATUS_FAILED;
2463 return CA_STATUS_OK;
2466 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2468 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2469 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2470 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2472 if (!CALEIsEnableBTAdapter(env))
2474 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2478 // get BluetoothGatt.getService method
2479 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2480 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2482 "(Ljava/util/UUID;)Landroid/bluetooth/"
2483 "BluetoothGattService;");
2484 if (!jni_mid_getService)
2486 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2490 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2491 if (!jni_obj_service_uuid)
2493 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2497 // get bluetooth gatt service
2498 OIC_LOG(DEBUG, TAG, "request to get service");
2499 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2500 jni_obj_service_uuid);
2501 if (!jni_obj_gattService)
2503 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2504 CACheckJNIException(env);
2508 // get bluetooth gatt service method
2509 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2510 "BluetoothGattService",
2511 "getCharacteristic",
2512 "(Ljava/util/UUID;)"
2513 "Landroid/bluetooth/"
2514 "BluetoothGattCharacteristic;");
2515 if (!jni_mid_getCharacteristic)
2517 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2521 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2524 OIC_LOG(ERROR, TAG, "uuid is null");
2525 CACheckJNIException(env);
2529 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2530 if (!jni_obj_tx_uuid)
2532 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2533 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2537 OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
2538 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2539 jni_mid_getCharacteristic,
2541 if (!jni_obj_GattCharacteristic)
2543 OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
2544 CACheckJNIException(env);
2548 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2549 return jni_obj_GattCharacteristic;
2552 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2554 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2555 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2556 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2557 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2559 if (!CALEIsEnableBTAdapter(env))
2561 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2565 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2568 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2572 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2573 if (!jni_obj_GattCharacteristic)
2575 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2579 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2580 "/BluetoothGattCharacteristic");
2581 if (!jni_cid_BTGattCharacteristic)
2583 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2587 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2588 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2590 if (!jni_mid_setValue)
2592 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2596 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2598 if (JNI_TRUE == ret)
2600 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2604 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2610 OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
2612 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2613 "setWriteType", "(I)V");
2614 if (!jni_mid_setWriteType)
2616 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2620 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2621 "WRITE_TYPE_NO_RESPONSE", "I");
2622 if (!jni_fid_no_response)
2624 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2628 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2629 jni_fid_no_response);
2630 CACheckJNIException(env);
2632 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2633 if (CACheckJNIException(env))
2635 OIC_LOG(ERROR, TAG, "setWriteType has failed");
2640 OIC_LOG(DEBUG, TAG, "It will run with response property");
2643 return jni_obj_GattCharacteristic;
2646 CACheckJNIException(env);
2650 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2652 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2653 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2655 if (!CALEIsEnableBTAdapter(env))
2657 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2661 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2662 "BluetoothGattCharacteristic",
2663 "getValue", "()[B");
2664 if (!jni_mid_getValue)
2666 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2670 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2672 CACheckJNIException(env);
2673 return jni_obj_data_array;
2676 CAResult_t CALEClientCreateUUIDList()
2680 OIC_LOG(ERROR, TAG, "g_jvm is null");
2681 return CA_STATUS_FAILED;
2684 bool isAttached = false;
2686 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2689 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2693 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2694 return CA_STATUS_FAILED;
2699 // create new object array
2700 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2701 if (!jni_cid_uuid_list)
2703 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2704 CACheckJNIException(env);
2708 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2709 jni_cid_uuid_list, NULL);
2710 if (!jni_obj_uuid_list)
2712 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2713 CACheckJNIException(env);
2718 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2721 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2724 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2726 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2727 CACheckJNIException(env);
2731 (*g_jvm)->DetachCurrentThread(g_jvm);
2734 return CA_STATUS_OK;
2741 (*g_jvm)->DetachCurrentThread(g_jvm);
2743 return CA_STATUS_FAILED;
2746 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2747 jobject characteristic)
2749 VERIFY_NON_NULL(env, TAG, "env is null");
2750 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2751 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2753 if (!CALEIsEnableBTAdapter(env))
2755 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2756 return CA_ADAPTER_NOT_ENABLED;
2759 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2760 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2761 "BluetoothGattCharacteristic",
2763 "(Ljava/util/UUID;)Landroid/bluetooth/"
2764 "BluetoothGattDescriptor;");
2765 if (!jni_mid_getDescriptor)
2767 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2768 return CA_STATUS_FAILED;
2771 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2772 if (!jni_obj_cc_uuid)
2774 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2777 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2778 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2779 jni_mid_getDescriptor, jni_obj_cc_uuid);
2780 if (!jni_obj_descriptor)
2782 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2786 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2787 jclass jni_cid_descriptor = (*env)->FindClass(env,
2788 "android/bluetooth/BluetoothGattDescriptor");
2789 if (!jni_cid_descriptor)
2791 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2795 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2796 if (!jni_mid_setValue)
2798 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2802 jfieldID jni_fid_NotiValue = NULL;
2805 OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
2806 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2807 "ENABLE_INDICATION_VALUE", "[B");
2808 if (!jni_fid_NotiValue)
2810 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2816 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2817 jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2818 "ENABLE_NOTIFICATION_VALUE", "[B");
2819 if (!jni_fid_NotiValue)
2821 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2826 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2827 env, jni_obj_descriptor, jni_mid_setValue,
2828 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2831 OIC_LOG(DEBUG, TAG, "setValue success");
2835 OIC_LOG(ERROR, TAG, "setValue has failed");
2839 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2841 "(Landroid/bluetooth/"
2842 "BluetoothGattDescriptor;)Z");
2843 if (!jni_mid_writeDescriptor)
2845 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2846 return CA_STATUS_FAILED;
2849 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2850 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2851 jni_obj_descriptor);
2854 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2858 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2862 return CA_STATUS_OK;
2865 CACheckJNIException(env);
2866 return CA_STATUS_FAILED;
2869 void CALEClientCreateScanDeviceList(JNIEnv *env)
2871 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2872 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2874 oc_mutex_lock(g_deviceListMutex);
2875 // create new object array
2876 if (g_deviceList == NULL)
2878 OIC_LOG(DEBUG, TAG, "Create device list");
2880 g_deviceList = u_arraylist_create();
2882 oc_mutex_unlock(g_deviceListMutex);
2885 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2887 VERIFY_NON_NULL(device, TAG, "device is null");
2888 VERIFY_NON_NULL(env, TAG, "env is null");
2890 oc_mutex_lock(g_deviceListMutex);
2894 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2895 oc_mutex_unlock(g_deviceListMutex);
2896 return CA_STATUS_FAILED;
2899 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2900 if (!jni_remoteAddress)
2902 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2903 oc_mutex_unlock(g_deviceListMutex);
2904 return CA_STATUS_FAILED;
2907 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2910 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2911 CACheckJNIException(env);
2912 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2913 oc_mutex_unlock(g_deviceListMutex);
2914 return CA_STATUS_FAILED;
2917 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2919 jobject gdevice = (*env)->NewGlobalRef(env, device);
2920 CACheckJNIException(env);
2921 u_arraylist_add(g_deviceList, gdevice);
2922 oc_cond_signal(g_deviceDescCond);
2923 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2925 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2926 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2928 oc_mutex_unlock(g_deviceListMutex);
2930 return CA_STATUS_OK;
2933 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2935 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2936 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2940 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2944 uint32_t length = u_arraylist_length(g_deviceList);
2945 for (uint32_t index = 0; index < length; index++)
2947 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2950 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2954 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2955 if (!jni_setAddress)
2957 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2961 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2964 OIC_LOG(ERROR, TAG, "setAddress is null");
2965 CACheckJNIException(env);
2966 (*env)->DeleteLocalRef(env, jni_setAddress);
2970 if (!strcmp(remoteAddress, setAddress))
2972 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2973 (*env)->DeleteLocalRef(env, jni_setAddress);
2974 OIC_LOG_V(INFO, TAG, "[%s] exist in scanned device list", remoteAddress);
2978 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2979 (*env)->DeleteLocalRef(env, jni_setAddress);
2984 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2986 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2987 VERIFY_NON_NULL(env, TAG, "env is null");
2989 oc_mutex_lock(g_deviceListMutex);
2993 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2994 oc_mutex_unlock(g_deviceListMutex);
2995 return CA_STATUS_FAILED;
2998 uint32_t length = u_arraylist_length(g_deviceList);
2999 for (uint32_t index = 0; index < length; index++)
3001 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3004 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3007 (*env)->DeleteGlobalRef(env, jarrayObj);
3011 OICFree(g_deviceList);
3012 g_deviceList = NULL;
3014 oc_mutex_unlock(g_deviceListMutex);
3015 return CA_STATUS_OK;
3018 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
3020 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
3021 VERIFY_NON_NULL(address, TAG, "address is null");
3022 VERIFY_NON_NULL(env, TAG, "env is null");
3024 oc_mutex_lock(g_deviceListMutex);
3028 OIC_LOG(ERROR, TAG, "g_deviceList is null");
3029 oc_mutex_unlock(g_deviceListMutex);
3030 return CA_STATUS_FAILED;
3033 uint32_t length = u_arraylist_length(g_deviceList);
3034 for (uint32_t index = 0; index < length; index++)
3036 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
3039 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3040 oc_mutex_unlock(g_deviceListMutex);
3041 return CA_STATUS_FAILED;
3044 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
3045 if (!jni_setAddress)
3047 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3048 oc_mutex_unlock(g_deviceListMutex);
3049 return CA_STATUS_FAILED;
3052 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3055 OIC_LOG(ERROR, TAG, "setAddress is null");
3056 CACheckJNIException(env);
3057 oc_mutex_unlock(g_deviceListMutex);
3058 return CA_STATUS_FAILED;
3061 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
3064 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3065 CACheckJNIException(env);
3066 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3067 oc_mutex_unlock(g_deviceListMutex);
3068 return CA_STATUS_FAILED;
3071 if (!strcmp(setAddress, remoteAddress))
3073 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3074 (*env)->DeleteGlobalRef(env, jarrayObj);
3076 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3077 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3079 if (NULL == u_arraylist_remove(g_deviceList, index))
3081 OIC_LOG(ERROR, TAG, "List removal failed.");
3082 oc_mutex_unlock(g_deviceListMutex);
3083 return CA_STATUS_FAILED;
3085 oc_mutex_unlock(g_deviceListMutex);
3086 return CA_STATUS_OK;
3088 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3089 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
3092 oc_mutex_unlock(g_deviceListMutex);
3093 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
3095 return CA_STATUS_OK;
3102 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
3104 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
3105 VERIFY_NON_NULL(env, TAG, "env is null");
3106 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3108 oc_mutex_lock(g_gattObjectMutex);
3110 if (!g_gattObjectList)
3112 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
3113 oc_mutex_unlock(g_gattObjectMutex);
3114 return CA_STATUS_FAILED;
3117 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3118 if (!jni_remoteAddress)
3120 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3121 oc_mutex_unlock(g_gattObjectMutex);
3122 return CA_STATUS_FAILED;
3125 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3128 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3129 CACheckJNIException(env);
3130 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3131 oc_mutex_unlock(g_gattObjectMutex);
3132 return CA_STATUS_FAILED;
3135 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3136 if (!CALEClientIsGattObjInList(env, remoteAddress))
3138 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3139 u_arraylist_add(g_gattObjectList, newGatt);
3140 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3143 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3144 (*env)->DeleteLocalRef(env, jni_remoteAddress);
3145 oc_mutex_unlock(g_gattObjectMutex);
3146 return CA_STATUS_OK;
3149 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3151 VERIFY_NON_NULL(env, TAG, "env is null");
3152 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3154 uint32_t length = u_arraylist_length(g_gattObjectList);
3155 for (uint32_t index = 0; index < length; index++)
3157 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3160 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3164 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3165 if (!jni_setAddress)
3167 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3171 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3174 OIC_LOG(ERROR, TAG, "setAddress is null");
3175 CACheckJNIException(env);
3176 (*env)->DeleteLocalRef(env, jni_setAddress);
3180 if (!strcmp(remoteAddress, setAddress))
3182 OIC_LOG(DEBUG, TAG, "the device is already set");
3183 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3184 (*env)->DeleteLocalRef(env, jni_setAddress);
3187 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3188 (*env)->DeleteLocalRef(env, jni_setAddress);
3191 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3195 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3197 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3198 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3199 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3201 oc_mutex_lock(g_gattObjectMutex);
3202 uint32_t length = u_arraylist_length(g_gattObjectList);
3203 for (uint32_t index = 0; index < length; index++)
3205 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3208 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3209 oc_mutex_unlock(g_gattObjectMutex);
3213 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3214 if (!jni_setAddress)
3216 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3217 oc_mutex_unlock(g_gattObjectMutex);
3221 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3224 OIC_LOG(ERROR, TAG, "setAddress is null");
3225 CACheckJNIException(env);
3226 (*env)->DeleteLocalRef(env, jni_setAddress);
3227 oc_mutex_unlock(g_gattObjectMutex);
3231 if (!strcmp(remoteAddress, setAddress))
3233 OIC_LOG(DEBUG, TAG, "the device is already set");
3234 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3235 oc_mutex_unlock(g_gattObjectMutex);
3238 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3239 (*env)->DeleteLocalRef(env, jni_setAddress);
3242 oc_mutex_unlock(g_gattObjectMutex);
3243 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3247 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3249 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3250 VERIFY_NON_NULL(env, TAG, "env is null");
3252 oc_mutex_lock(g_gattObjectMutex);
3253 if (!g_gattObjectList)
3255 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3256 oc_mutex_unlock(g_gattObjectMutex);
3257 return CA_STATUS_OK;
3260 uint32_t length = u_arraylist_length(g_gattObjectList);
3261 for (uint32_t index = 0; index < length; index++)
3263 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3266 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3269 (*env)->DeleteGlobalRef(env, jarrayObj);
3273 OICFree(g_gattObjectList);
3274 g_gattObjectList = NULL;
3275 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3276 oc_mutex_unlock(g_gattObjectMutex);
3277 return CA_STATUS_OK;
3280 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3282 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3283 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3284 VERIFY_NON_NULL(env, TAG, "env is null");
3286 oc_mutex_lock(g_gattObjectMutex);
3287 if (!g_gattObjectList)
3289 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3290 oc_mutex_unlock(g_gattObjectMutex);
3291 return CA_STATUS_OK;
3294 uint32_t length = u_arraylist_length(g_gattObjectList);
3295 for (uint32_t index = 0; index < length; index++)
3297 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3300 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3301 oc_mutex_unlock(g_gattObjectMutex);
3302 return CA_STATUS_FAILED;
3305 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3306 if (!jni_setAddress)
3308 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3309 oc_mutex_unlock(g_gattObjectMutex);
3310 return CA_STATUS_FAILED;
3313 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3316 OIC_LOG(ERROR, TAG, "setAddress is null");
3317 CACheckJNIException(env);
3318 oc_mutex_unlock(g_gattObjectMutex);
3319 return CA_STATUS_FAILED;
3322 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3323 if (!jni_remoteAddress)
3325 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3326 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3327 oc_mutex_unlock(g_gattObjectMutex);
3328 return CA_STATUS_FAILED;
3331 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3334 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3335 CACheckJNIException(env);
3336 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3337 oc_mutex_unlock(g_gattObjectMutex);
3338 return CA_STATUS_FAILED;
3341 if (!strcmp(setAddress, remoteAddress))
3343 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3344 (*env)->DeleteGlobalRef(env, jarrayObj);
3346 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3347 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3349 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3351 OIC_LOG(ERROR, TAG, "List removal failed.");
3352 oc_mutex_unlock(g_gattObjectMutex);
3353 return CA_STATUS_FAILED;
3355 oc_mutex_unlock(g_gattObjectMutex);
3356 return CA_STATUS_OK;
3358 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3359 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3362 oc_mutex_unlock(g_gattObjectMutex);
3363 OIC_LOG(DEBUG, TAG, "there are no target object");
3364 return CA_STATUS_OK;
3367 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3369 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3370 VERIFY_NON_NULL(addr, TAG, "addr is null");
3371 VERIFY_NON_NULL(env, TAG, "env is null");
3373 oc_mutex_lock(g_gattObjectMutex);
3374 if (!g_gattObjectList)
3376 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3377 oc_mutex_unlock(g_gattObjectMutex);
3378 return CA_STATUS_OK;
3381 uint32_t length = u_arraylist_length(g_gattObjectList);
3382 for (uint32_t index = 0; index < length; index++)
3384 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3387 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3388 oc_mutex_unlock(g_gattObjectMutex);
3389 return CA_STATUS_FAILED;
3392 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3393 if (!jni_setAddress)
3395 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3396 oc_mutex_unlock(g_gattObjectMutex);
3397 return CA_STATUS_FAILED;
3400 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3403 OIC_LOG(ERROR, TAG, "setAddress is null");
3404 CACheckJNIException(env);
3405 oc_mutex_unlock(g_gattObjectMutex);
3406 return CA_STATUS_FAILED;
3409 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3412 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3413 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3414 oc_mutex_unlock(g_gattObjectMutex);
3415 return CA_STATUS_FAILED;
3418 if (!strcmp(setAddress, remoteAddress))
3420 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3421 (*env)->DeleteGlobalRef(env, jarrayObj);
3423 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3424 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3425 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3427 OIC_LOG(ERROR, TAG, "List removal failed.");
3428 oc_mutex_unlock(g_gattObjectMutex);
3429 return CA_STATUS_FAILED;
3431 oc_mutex_unlock(g_gattObjectMutex);
3432 return CA_STATUS_OK;
3434 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3435 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3438 oc_mutex_unlock(g_gattObjectMutex);
3439 OIC_LOG(DEBUG, TAG, "there are no target object");
3440 return CA_STATUS_FAILED;
3443 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3445 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3446 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3448 // get Bluetooth Address
3449 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3450 if (!jni_btTargetAddress)
3452 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3456 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3459 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3460 CACheckJNIException(env);
3464 // get method ID of getDevice()
3465 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3466 "getDevice", METHODID_BT_DEVICE);
3467 if (!jni_mid_getDevice)
3469 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3470 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3474 oc_mutex_lock(g_gattObjectMutex);
3476 size_t length = u_arraylist_length(g_gattObjectList);
3477 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3478 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3480 for (size_t index = 0; index < length; index++)
3482 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3485 oc_mutex_unlock(g_gattObjectMutex);
3486 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3487 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3491 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3492 if (!jni_obj_device)
3494 CACheckJNIException(env);
3495 oc_mutex_unlock(g_gattObjectMutex);
3496 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3497 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3501 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3504 oc_mutex_unlock(g_gattObjectMutex);
3505 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3506 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3507 (*env)->DeleteLocalRef(env, jni_obj_device);
3511 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3514 CACheckJNIException(env);
3515 oc_mutex_unlock(g_gattObjectMutex);
3516 OIC_LOG(ERROR, TAG, "btAddress is not available");
3517 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3518 (*env)->DeleteLocalRef(env, jni_btAddress);
3519 (*env)->DeleteLocalRef(env, jni_obj_device);
3523 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3524 if (!strcmp(targetAddress, btAddress))
3526 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3529 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3532 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3534 oc_mutex_unlock(g_gattObjectMutex);
3535 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3536 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3537 (*env)->DeleteLocalRef(env, jni_btAddress);
3538 (*env)->DeleteLocalRef(env, jni_obj_device);
3539 return jni_LEAddress;
3541 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3542 (*env)->DeleteLocalRef(env, jni_btAddress);
3543 (*env)->DeleteLocalRef(env, jni_obj_device);
3545 oc_mutex_unlock(g_gattObjectMutex);
3547 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3548 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3555 CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
3557 uint16_t state_type,
3558 uint16_t target_state)
3560 VERIFY_NON_NULL(device, TAG, "device is null");
3562 // get Bluetooth Address
3563 jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
3566 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3567 return CA_STATUS_FAILED;
3570 const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
3573 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3574 CACheckJNIException(env);
3575 (*env)->DeleteLocalRef(env, jni_Address);
3576 return CA_STATUS_FAILED;
3579 if (CALEIsValidState(address, state_type, target_state,
3581 g_deviceStateListMutex))
3583 (*env)->DeleteLocalRef(env, jni_Address);
3584 return CA_STATUS_OK;
3587 CAResult_t res = CALEUpdateDeviceState(address, state_type,
3590 g_deviceStateListMutex);
3591 if (CA_STATUS_OK != res)
3593 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
3595 (*env)->ReleaseStringUTFChars(env, jni_Address, address);
3596 (*env)->DeleteLocalRef(env, jni_Address);
3601 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
3602 jint state_idx, jboolean flag)
3604 return CALESetFlagToState(env, jni_address, state_idx, flag,
3605 g_deviceStateList, g_deviceStateListMutex);
3608 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
3610 return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
3611 g_deviceStateListMutex);
3614 uint16_t CALEClientGetMtuSize(const char* address)
3616 return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
3619 void CALEClientCreateDeviceList()
3621 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3623 // create new object array
3624 if (!g_gattObjectList)
3626 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3628 g_gattObjectList = u_arraylist_create();
3631 if (!g_deviceStateList)
3633 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3635 g_deviceStateList = u_arraylist_create();
3640 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3642 g_deviceList = u_arraylist_create();
3646 CAResult_t CALEClientResetDeviceStateForAll()
3648 return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
3652 * Check Sent Count for remove g_sendBuffer
3654 void CALEClientUpdateSendCnt(JNIEnv *env)
3656 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3658 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3660 oc_mutex_lock(g_threadMutex);
3664 if (g_targetCnt <= g_currentSentCnt)
3667 g_currentSentCnt = 0;
3671 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3672 g_sendBuffer = NULL;
3674 // notity the thread
3675 oc_cond_signal(g_threadCond);
3677 CALEClientSetSendFinishFlag(true);
3678 OIC_LOG(DEBUG, TAG, "set signal for send data");
3681 #ifdef SCAN_INTERVAL
3682 // reset interval scan logic
3683 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
3687 oc_mutex_unlock(g_threadMutex);
3690 CAResult_t CALEClientInitGattMutexVaraibles()
3692 if (NULL == g_bleReqRespClientCbMutex)
3694 g_bleReqRespClientCbMutex = oc_mutex_new();
3695 if (NULL == g_bleReqRespClientCbMutex)
3697 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3698 return CA_STATUS_FAILED;
3702 if (NULL == g_bleServerBDAddressMutex)
3704 g_bleServerBDAddressMutex = oc_mutex_new();
3705 if (NULL == g_bleServerBDAddressMutex)
3707 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3708 return CA_STATUS_FAILED;
3712 if (NULL == g_threadMutex)
3714 g_threadMutex = oc_mutex_new();
3715 if (NULL == g_threadMutex)
3717 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3718 return CA_STATUS_FAILED;
3722 if (NULL == g_threadSendMutex)
3724 g_threadSendMutex = oc_mutex_new();
3725 if (NULL == g_threadSendMutex)
3727 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3728 return CA_STATUS_FAILED;
3732 if (NULL == g_deviceListMutex)
3734 g_deviceListMutex = oc_mutex_new();
3735 if (NULL == g_deviceListMutex)
3737 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3738 return CA_STATUS_FAILED;
3742 if (NULL == g_gattObjectMutex)
3744 g_gattObjectMutex = oc_mutex_new();
3745 if (NULL == g_gattObjectMutex)
3747 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3748 return CA_STATUS_FAILED;
3752 if (NULL == g_deviceStateListMutex)
3754 g_deviceStateListMutex = oc_mutex_new();
3755 if (NULL == g_deviceStateListMutex)
3757 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3758 return CA_STATUS_FAILED;
3762 if (NULL == g_SendFinishMutex)
3764 g_SendFinishMutex = oc_mutex_new();
3765 if (NULL == g_SendFinishMutex)
3767 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3768 return CA_STATUS_FAILED;
3772 if (NULL == g_threadWriteCharacteristicMutex)
3774 g_threadWriteCharacteristicMutex = oc_mutex_new();
3775 if (NULL == g_threadWriteCharacteristicMutex)
3777 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3778 return CA_STATUS_FAILED;
3782 if (NULL == g_deviceScanRetryDelayMutex)
3784 g_deviceScanRetryDelayMutex = oc_mutex_new();
3785 if (NULL == g_deviceScanRetryDelayMutex)
3787 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3788 return CA_STATUS_FAILED;
3792 if (NULL == g_threadSendStateMutex)
3794 g_threadSendStateMutex = oc_mutex_new();
3795 if (NULL == g_threadSendStateMutex)
3797 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3798 return CA_STATUS_FAILED;
3802 if (NULL == g_threadScanIntervalMutex)
3804 g_threadScanIntervalMutex = oc_mutex_new();
3805 if (NULL == g_threadScanIntervalMutex)
3807 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
3808 return CA_STATUS_FAILED;
3812 return CA_STATUS_OK;
3815 void CALEClientTerminateGattMutexVariables()
3817 oc_mutex_free(g_bleReqRespClientCbMutex);
3818 g_bleReqRespClientCbMutex = NULL;
3820 oc_mutex_free(g_bleServerBDAddressMutex);
3821 g_bleServerBDAddressMutex = NULL;
3823 oc_mutex_free(g_threadMutex);
3824 g_threadMutex = NULL;
3826 oc_mutex_free(g_threadSendMutex);
3827 g_threadSendMutex = NULL;
3829 oc_mutex_free(g_deviceListMutex);
3830 g_deviceListMutex = NULL;
3832 oc_mutex_free(g_SendFinishMutex);
3833 g_SendFinishMutex = NULL;
3835 oc_mutex_free(g_threadWriteCharacteristicMutex);
3836 g_threadWriteCharacteristicMutex = NULL;
3838 oc_mutex_free(g_deviceScanRetryDelayMutex);
3839 g_deviceScanRetryDelayMutex = NULL;
3841 oc_mutex_free(g_threadSendStateMutex);
3842 g_threadSendStateMutex = NULL;
3844 oc_mutex_free(g_threadScanIntervalMutex);
3845 g_threadScanIntervalMutex = NULL;
3848 void CALEClientSetSendFinishFlag(bool flag)
3850 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3852 oc_mutex_lock(g_SendFinishMutex);
3853 g_isFinishedSendData = flag;
3854 oc_mutex_unlock(g_SendFinishMutex);
3861 CAResult_t CAStartLEGattClient()
3863 // init mutex for send logic
3864 if (!g_deviceDescCond)
3866 g_deviceDescCond = oc_cond_new();
3871 g_threadCond = oc_cond_new();
3874 if (!g_threadWriteCharacteristicCond)
3876 g_threadWriteCharacteristicCond = oc_cond_new();
3879 if (!g_threadScanIntervalCond)
3881 g_threadScanIntervalCond = oc_cond_new();
3884 CAResult_t ret = CALEClientStartScanWithInterval();
3885 if (CA_STATUS_OK != ret)
3887 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
3891 g_isStartedLEClient = true;
3892 return CA_STATUS_OK;
3895 void CAStopLEGattClient()
3897 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3901 OIC_LOG(ERROR, TAG, "g_jvm is null");
3905 bool isAttached = false;
3907 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3910 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3914 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3920 CAResult_t ret = CALEClientDisconnectAll(env);
3921 if (CA_STATUS_OK != ret)
3923 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3926 CALEClientStopScanWithInterval();
3928 oc_mutex_lock(g_threadWriteCharacteristicMutex);
3929 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3930 oc_cond_signal(g_threadWriteCharacteristicCond);
3931 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
3933 CALEClientSetSendFinishFlag(true);
3934 oc_mutex_lock(g_threadMutex);
3935 OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
3936 oc_cond_signal(g_threadCond);
3937 oc_mutex_unlock(g_threadMutex);
3939 oc_mutex_lock(g_deviceScanRetryDelayMutex);
3940 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3941 oc_cond_signal(g_deviceScanRetryDelayCond);
3942 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
3944 oc_mutex_lock(g_threadScanIntervalMutex);
3945 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3946 oc_cond_signal(g_threadScanIntervalCond);
3947 oc_mutex_unlock(g_threadScanIntervalMutex);
3949 oc_mutex_lock(g_threadSendMutex);
3950 OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
3951 oc_cond_signal(g_deviceDescCond);
3952 oc_mutex_unlock(g_threadSendMutex);
3954 oc_cond_free(g_deviceDescCond);
3955 oc_cond_free(g_threadCond);
3956 oc_cond_free(g_threadWriteCharacteristicCond);
3957 oc_cond_free(g_deviceScanRetryDelayCond);
3958 oc_cond_free(g_threadScanIntervalCond);
3960 g_deviceDescCond = NULL;
3961 g_threadCond = NULL;
3962 g_threadWriteCharacteristicCond = NULL;
3963 g_deviceScanRetryDelayCond = NULL;
3964 g_threadScanIntervalCond = NULL;
3968 (*g_jvm)->DetachCurrentThread(g_jvm);
3973 CAResult_t CAInitializeLEGattClient()
3975 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3976 CALEClientInitialize();
3977 return CA_STATUS_OK;
3980 void CATerminateLEGattClient()
3982 OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
3983 CAStopLEGattClient();
3984 CALEClientTerminate();
3985 OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
3988 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3989 uint32_t dataLen, CALETransferType_t type,
3992 OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
3993 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3995 if (LE_UNICAST != type || position < 0)
3997 OIC_LOG(ERROR, TAG, "this request is not unicast");
3998 return CA_STATUS_INVALID_PARAM;
4001 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4004 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4006 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4007 VERIFY_NON_NULL(data, TAG, "data is null");
4009 return CALEClientSendMulticastMessage(data, dataLen);
4012 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4014 oc_mutex_lock(g_bleReqRespClientCbMutex);
4015 g_CABLEClientDataReceivedCallback = callback;
4016 oc_mutex_unlock(g_bleReqRespClientCbMutex);
4019 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4021 g_threadPoolHandle = handle;
4024 CAResult_t CAGetLEAddress(char **local_address)
4026 VERIFY_NON_NULL(local_address, TAG, "local_address");
4027 return CA_NOT_SUPPORTED;
4030 JNIEXPORT void JNICALL
4031 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4034 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4035 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4036 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4037 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4039 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4040 CACheckJNIException(env);
4043 JNIEXPORT void JNICALL
4044 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4047 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4048 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4049 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4050 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4052 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4053 CACheckJNIException(env);
4056 JNIEXPORT void JNICALL
4057 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4060 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4061 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4062 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4064 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4065 if (CA_STATUS_OK != res)
4067 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4072 * Class: org_iotivity_ca_jar_caleinterface
4073 * Method: CALeGattConnectionStateChangeCallback
4074 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4076 JNIEXPORT void JNICALL
4077 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4083 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4085 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4086 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4087 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4089 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4091 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4094 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4098 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4101 OIC_LOG(ERROR, TAG, "address is null");
4102 CACheckJNIException(env);
4105 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4107 if (state_connected == newstate)
4109 OIC_LOG(DEBUG, TAG, "LE is connected");
4110 if (GATT_SUCCESS == status)
4112 CAResult_t res = CALEUpdateDeviceState(address,
4113 CA_LE_CONNECTION_STATE,
4116 g_deviceStateListMutex);
4117 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4118 if (CA_STATUS_OK != res)
4120 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4124 res = CALEClientAddGattobjToList(env, gatt);
4125 if (CA_STATUS_OK != res)
4127 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4131 res = CALEClientDiscoverServices(env, gatt);
4132 if (CA_STATUS_OK != res)
4134 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4140 OIC_LOG(INFO, TAG, "unknown status");
4141 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4144 else // STATE_DISCONNECTED == newstate
4146 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4148 if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
4149 g_deviceStateList, g_deviceStateListMutex))
4151 OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
4152 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4155 g_deviceStateListMutex);
4156 if (CA_STATUS_OK != res)
4158 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4162 CAResult_t res = CALEUpdateDeviceState(address,
4163 CA_LE_CONNECTION_STATE,
4166 g_deviceStateListMutex);
4167 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4168 if (CA_STATUS_OK != res)
4170 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4174 res = CALEClientGattClose(env, gatt);
4175 if (CA_STATUS_OK != res)
4177 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4180 if (CALECheckConnectionStateValue(status))
4182 // this state is unexpected reason to disconnect
4183 // if the reason is suitable, connection logic of the device will be destroyed.
4184 OIC_LOG(INFO, TAG, "connection logic destroy");
4189 // other reason except for gatt_success is expected to running
4190 // background connection in BT platform.
4191 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4192 CALEClientUpdateSendCnt(env);
4200 CALEClientSendFinish(env, gatt);
4205 * Class: org_iotivity_ca_jar_caleinterface
4206 * Method: CALeGattServicesDiscoveredCallback
4207 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4209 JNIEXPORT void JNICALL
4210 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4215 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4216 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4217 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4218 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4220 if (GATT_SUCCESS != status) // discovery error
4222 CALEClientSendFinish(env, gatt);
4226 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4229 CALEClientSendFinish(env, gatt);
4233 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4236 CACheckJNIException(env);
4237 CALEClientSendFinish(env, gatt);
4241 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4244 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4248 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4249 if (!jni_obj_GattCharacteristic)
4251 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4255 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4256 jni_obj_GattCharacteristic);
4257 if (CA_STATUS_OK != res)
4259 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4263 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4264 if (CA_STATUS_OK != res)
4266 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4268 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
4269 g_deviceStateList, g_deviceStateListMutex);
4270 if (CA_STATUS_OK != res)
4272 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
4276 res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4277 STATE_SERVICE_CONNECTED,
4279 g_deviceStateListMutex);
4280 if (CA_STATUS_OK != res)
4282 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4286 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
4287 if (CA_STATUS_OK != res)
4289 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
4295 res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
4296 g_deviceStateList, g_deviceStateListMutex);
4297 if (CA_STATUS_OK != res)
4299 OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
4304 #ifdef SCAN_INTERVAL
4305 // reset interval scan logic
4306 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
4309 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4310 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4315 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4316 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4317 CALEClientSendFinish(env, gatt);
4322 * Class: org_iotivity_ca_jar_caleinterface
4323 * Method: CALeGattCharacteristicWritjclasseCallback
4324 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4326 JNIEXPORT void JNICALL
4327 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4328 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4330 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4331 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4332 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4333 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4335 // send success & signal
4336 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4342 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4345 CACheckJNIException(env);
4349 if (GATT_SUCCESS != status) // error case
4351 OIC_LOG(ERROR, TAG, "send failure");
4354 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4355 if (CA_STATUS_OK != res)
4357 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4358 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4359 g_isSignalSetFlag = true;
4360 oc_cond_signal(g_threadWriteCharacteristicCond);
4361 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4363 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4366 g_deviceStateListMutex);
4367 if (CA_STATUS_OK != res)
4369 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4372 if (g_clientErrorCallback)
4374 jint length = (*env)->GetArrayLength(env, data);
4375 CACheckJNIException(env);
4376 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4377 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
4378 false, "writeChar failure");
4381 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4387 OIC_LOG(DEBUG, TAG, "send success");
4388 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4391 g_deviceStateListMutex);
4392 if (CA_STATUS_OK != res)
4394 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4397 oc_mutex_lock(g_threadWriteCharacteristicMutex);
4398 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4399 g_isSignalSetFlag = true;
4400 oc_cond_signal(g_threadWriteCharacteristicCond);
4401 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
4403 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
4404 (*env)->GetArrayLength(env, data),
4405 true, "writeChar success");
4408 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4414 CALEClientSendFinish(env, gatt);
4419 * Class: org_iotivity_ca_jar_caleinterface
4420 * Method: CALeGattCharacteristicChangedCallback
4421 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4423 JNIEXPORT void JNICALL
4424 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4425 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4427 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4428 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4429 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4430 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4431 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4433 // get Byte Array and convert to uint8_t*
4434 jint length = (*env)->GetArrayLength(env, data);
4437 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4438 CACheckJNIException(env);
4440 uint8_t* receivedData = OICMalloc(length);
4443 OIC_LOG(ERROR, TAG, "receivedData is null");
4447 memcpy(receivedData, jni_byte_responseData, length);
4448 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4450 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4453 OIC_LOG(ERROR, TAG, "jni_address is null");
4454 OICFree(receivedData);
4458 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4461 OIC_LOG(ERROR, TAG, "address is null");
4462 CACheckJNIException(env);
4463 OICFree(receivedData);
4467 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4468 receivedData, length);
4470 uint32_t sentLength = 0;
4471 oc_mutex_lock(g_bleServerBDAddressMutex);
4472 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4473 oc_mutex_unlock(g_bleServerBDAddressMutex);
4475 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4479 * Class: org_iotivity_ca_jar_caleinterface
4480 * Method: CALeGattDescriptorWriteCallback
4481 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4483 JNIEXPORT void JNICALL
4484 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4488 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4489 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4490 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4491 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4493 if (GATT_SUCCESS != status) // error
4498 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4504 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4507 CACheckJNIException(env);
4511 CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4512 STATE_SERVICE_CONNECTED,
4514 g_deviceStateListMutex);
4515 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4516 if (CA_STATUS_OK != res)
4518 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4522 res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
4523 if (CA_STATUS_OK != res)
4525 OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
4533 CALEClientSendFinish(env, gatt);
4537 JNIEXPORT void JNICALL
4538 Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
4544 OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
4545 "mtu[%d-including Header size 3 byte]", mtu, status);
4553 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4554 if (CA_STATUS_OK != res)
4556 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4561 OIC_LOG(INFO, TAG, "mtu nego is done");
4562 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4565 CALEClientSendFinish(env, gatt);
4569 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4572 CACheckJNIException(env);
4573 (*env)->DeleteLocalRef(env, jni_address);
4574 CALEClientSendFinish(env, gatt);
4579 CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
4580 g_deviceStateList, g_deviceStateListMutex);
4581 if (CA_STATUS_OK != res)
4583 OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
4586 res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
4587 STATE_SEND_MTU_NEGO_SUCCESS,
4589 g_deviceStateListMutex);
4590 if (CA_STATUS_OK != res)
4592 OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
4594 CALEClientUpdateSendCnt(env);
4595 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4596 (*env)->DeleteLocalRef(env, jni_address);