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 "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
44 #define WAIT_TIME_SCAN_INTERVAL_DEFAULT 10
45 #define WAIT_TIME_SCANNED_CHECKING 30
47 #define GATT_CONNECTION_PRIORITY_BALANCED 0
48 #define GATT_FAILURE 257
49 #define GATT_INSUFFICIENT_AUTHENTICATION 5
50 #define GATT_INSUFFICIENT_ENCRYPTION 15
51 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
52 #define GATT_INVALID_OFFSET 7
53 #define GATT_READ_NOT_PERMITTED 2
54 #define GATT_REQUEST_NOT_SUPPORTED 6
55 #define GATT_WRITE_NOT_PERMITTED 3
57 static ca_thread_pool_t g_threadPoolHandle = NULL;
60 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
61 static u_arraylist_t *g_gattObjectList = NULL;
62 static u_arraylist_t *g_deviceStateList = NULL;
64 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
65 static CABLEErrorHandleCallback g_clientErrorCallback;
66 static jobject g_leScanCallback = NULL;
67 static jobject g_leGattCallback = NULL;
68 static jobject g_context = NULL;
69 static jobjectArray g_uuidList = NULL;
71 // it will be prevent to start send logic when adapter has stopped.
72 static bool g_isStartedLEClient = false;
74 static jbyteArray g_sendBuffer = NULL;
75 static uint32_t g_targetCnt = 0;
76 static uint32_t g_currentSentCnt = 0;
77 static bool g_isFinishedSendData = false;
78 static ca_mutex g_SendFinishMutex = NULL;
79 static ca_mutex g_threadMutex = NULL;
80 static ca_cond g_threadCond = NULL;
81 static ca_cond g_deviceDescCond = NULL;
83 static ca_mutex g_threadSendMutex = NULL;
84 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
85 static ca_cond g_threadWriteCharacteristicCond = NULL;
86 static bool g_isSignalSetFlag = false;
88 static ca_mutex g_bleReqRespClientCbMutex = NULL;
89 static ca_mutex g_bleServerBDAddressMutex = NULL;
91 static ca_mutex g_deviceListMutex = NULL;
92 static ca_mutex g_gattObjectMutex = NULL;
93 static ca_mutex g_deviceStateListMutex = NULL;
95 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
96 static ca_cond g_deviceScanRetryDelayCond = NULL;
98 static ca_mutex g_threadScanIntervalMutex = NULL;
99 static ca_cond g_threadScanIntervalCond = NULL;
101 static ca_mutex g_threadSendStateMutex = NULL;
103 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
104 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
105 static int32_t g_intervalCount = 0;
106 static bool g_isWorkingScanThread = false;
107 static CALEScanState_t g_scanningStep = BLE_SCAN_DISABLE;
109 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
112 * check if retry logic for connection routine has to be stopped or not.
113 * in case of error value including this method, connection routine has to be stopped.
114 * since there is no retry logic for this error reason in this client.
115 * @param state constant value of bluetoothgatt.
116 * @return true - waiting for background connection in BT platform.
117 * false - connection routine has to be stopped.
119 static bool CALECheckConnectionStateValue(jint state)
123 case GATT_CONNECTION_PRIORITY_BALANCED:
125 case GATT_INSUFFICIENT_AUTHENTICATION:
126 case GATT_INSUFFICIENT_ENCRYPTION:
127 case GATT_INVALID_ATTRIBUTE_LENGTH:
128 case GATT_INVALID_OFFSET:
129 case GATT_READ_NOT_PERMITTED:
130 case GATT_REQUEST_NOT_SUPPORTED:
131 case GATT_WRITE_NOT_PERMITTED:
137 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount)
139 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d",
140 g_scanIntervalTime, intervalTime);
142 // previous time should be stored.
143 if (0 < workingCount)
145 g_scanIntervalTimePrev = g_scanIntervalTime;
147 g_scanIntervalTime = intervalTime;
148 g_intervalCount = workingCount;
151 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount)
153 // restart scan with interval
154 CALEClientSetScanInterval(intervalTime, workingCount);
155 ca_cond_signal(g_threadScanIntervalCond);
158 static void CALEScanThread(void* object)
162 bool isAttached = false;
164 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
167 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
168 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
172 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
178 ca_mutex_lock(g_threadScanIntervalMutex);
179 while(g_isWorkingScanThread)
181 OIC_LOG(DEBUG, TAG, "scan waiting time out");
182 if (BLE_SCAN_ENABLE == g_scanningStep)
185 CAResult_t ret = CALEClientStopScan();
186 if (CA_STATUS_OK != ret)
188 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
194 CAResult_t ret = CALEClientStartScan();
195 if (CA_STATUS_OK != ret)
197 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
201 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
202 if (CA_WAIT_SUCCESS == ca_cond_wait_for(g_threadScanIntervalCond,
203 g_threadScanIntervalMutex,
204 g_scanIntervalTime * MICROSECS_PER_SEC))
206 // called signal scan thread will be terminated
207 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
208 g_scanningStep = BLE_SCAN_DISABLE;
212 if (BLE_SCAN_ENABLE == g_scanningStep)
214 if (g_intervalCount > 0)
216 if (g_intervalCount == 1)
218 OIC_LOG(DEBUG, TAG, "reset default time");
219 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0);
222 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
224 g_scanningStep = BLE_SCAN_DISABLE;
228 g_scanningStep = BLE_SCAN_ENABLE;
232 ca_mutex_unlock(g_threadScanIntervalMutex);
236 (*g_jvm)->DetachCurrentThread(g_jvm);
240 CAResult_t CALEClientStartScanWithInterval()
242 OIC_LOG(DEBUG, TAG, "IN - CALEClientStartScanWithInterval");
244 if (g_isWorkingScanThread)
246 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
250 // initialize scan flags
251 g_scanningStep = BLE_SCAN_DISABLE;
252 g_isWorkingScanThread = true;
254 g_scanIntervalTime = g_scanIntervalTimePrev;
256 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
257 CALEScanThread, NULL))
259 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
260 g_isWorkingScanThread = false;
261 return CA_STATUS_FAILED;
264 OIC_LOG(DEBUG, TAG, "OUT - CALEClientStartScanWithInterval");
268 void CALEClientStopScanWithInterval()
270 g_isWorkingScanThread = false;
271 ca_cond_signal(g_threadScanIntervalCond);
275 void CALEClientJniInit()
277 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
278 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
281 void CALEClientJNISetContext()
283 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
284 g_context = (jobject) CANativeJNIGetContext();
287 CAResult_t CALECreateJniInterfaceObject()
289 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
293 OIC_LOG(ERROR, TAG, "g_context is null");
294 return CA_STATUS_FAILED;
299 OIC_LOG(ERROR, TAG, "g_jvm is null");
300 return CA_STATUS_FAILED;
303 bool isAttached = false;
305 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
308 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
309 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
313 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
314 return CA_STATUS_FAILED;
319 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
320 "getApplicationContext",
321 "()Landroid/content/Context;");
323 if (!mid_getApplicationContext)
325 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
326 return CA_STATUS_FAILED;
329 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
330 mid_getApplicationContext);
331 if (!jApplicationContext)
333 OIC_LOG(ERROR, TAG, "Could not get application context");
334 return CA_STATUS_FAILED;
337 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
338 if (!jni_LEInterface)
340 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
344 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
345 "(Landroid/content/Context;)V");
346 if (!LeInterfaceConstructorMethod)
348 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
352 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
353 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
357 (*g_jvm)->DetachCurrentThread(g_jvm);
366 (*g_jvm)->DetachCurrentThread(g_jvm);
369 return CA_STATUS_FAILED;
372 CAResult_t CALEClientInitialize()
374 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
380 OIC_LOG(ERROR, TAG, "g_jvm is null");
381 return CA_STATUS_FAILED;
384 bool isAttached = false;
386 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
389 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
390 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
394 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
395 return CA_STATUS_FAILED;
400 CAResult_t ret = CALECheckPlatformVersion(env, 18);
401 if (CA_STATUS_OK != ret)
403 OIC_LOG(ERROR, TAG, "it is not supported");
407 (*g_jvm)->DetachCurrentThread(g_jvm);
413 ret = CALEClientInitGattMutexVaraibles();
414 if (CA_STATUS_OK != ret)
416 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
417 CALEClientTerminateGattMutexVariables();
421 (*g_jvm)->DetachCurrentThread(g_jvm);
427 g_deviceDescCond = ca_cond_new();
429 // init mutex for send logic
430 g_threadCond = ca_cond_new();
431 g_threadWriteCharacteristicCond = ca_cond_new();
432 g_deviceScanRetryDelayCond = ca_cond_new();
433 g_threadScanIntervalCond = ca_cond_new();
435 CALEClientCreateDeviceList();
436 CALEClientJNISetContext();
438 ret = CALEClientCreateUUIDList();
439 if (CA_STATUS_OK != ret)
441 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
445 (*g_jvm)->DetachCurrentThread(g_jvm);
451 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
452 if (CA_STATUS_OK != ret)
454 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
458 (*g_jvm)->DetachCurrentThread(g_jvm);
463 g_isStartedLEClient = true;
467 (*g_jvm)->DetachCurrentThread(g_jvm);
473 void CALEClientTerminate()
475 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
479 OIC_LOG(ERROR, TAG, "g_jvm is null");
483 bool isAttached = false;
485 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
488 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
489 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
493 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
499 if (g_leScanCallback)
501 (*env)->DeleteGlobalRef(env, g_leScanCallback);
502 g_leScanCallback = NULL;
505 if (g_leGattCallback)
507 (*env)->DeleteGlobalRef(env, g_leGattCallback);
508 g_leGattCallback = NULL;
513 (*env)->DeleteGlobalRef(env, g_sendBuffer);
519 (*env)->DeleteGlobalRef(env, g_uuidList);
523 CAResult_t ret = CALEClientRemoveAllDeviceState();
524 if (CA_STATUS_OK != ret)
526 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
529 ret = CALEClientRemoveAllScanDevices(env);
530 if (CA_STATUS_OK != ret)
532 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
535 ret = CALEClientRemoveAllGattObjs(env);
536 if (CA_STATUS_OK != ret)
538 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
541 CALEClientSetSendFinishFlag(true);
543 CALEClientTerminateGattMutexVariables();
544 CALEClientDestroyJniInterface();
546 ca_cond_free(g_deviceDescCond);
547 ca_cond_free(g_threadCond);
548 ca_cond_free(g_threadWriteCharacteristicCond);
549 ca_cond_free(g_deviceScanRetryDelayCond);
550 ca_cond_free(g_threadScanIntervalCond);
552 g_deviceDescCond = NULL;
554 g_threadWriteCharacteristicCond = NULL;
555 g_deviceScanRetryDelayCond = NULL;
556 g_threadScanIntervalCond = NULL;
558 g_isSignalSetFlag = false;
561 CALEClientStopScanWithInterval();
565 (*g_jvm)->DetachCurrentThread(g_jvm);
569 CAResult_t CALEClientDestroyJniInterface()
571 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
575 OIC_LOG(ERROR, TAG, "g_jvm is null");
576 return CA_STATUS_FAILED;
579 bool isAttached = false;
581 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
584 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
585 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
589 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
590 return CA_STATUS_FAILED;
595 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
596 if (!jni_LeInterface)
598 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
602 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
603 "destroyLeInterface",
605 if (!jni_InterfaceDestroyMethod)
607 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
611 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
613 if ((*env)->ExceptionCheck(env))
615 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
616 (*env)->ExceptionDescribe(env);
617 (*env)->ExceptionClear(env);
621 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
625 (*g_jvm)->DetachCurrentThread(g_jvm);
634 (*g_jvm)->DetachCurrentThread(g_jvm);
637 return CA_STATUS_FAILED;
640 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
642 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
643 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
647 CAResult_t res = CALEClientDisconnect(env, gatt);
648 if (CA_STATUS_OK != res)
650 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
653 CALEClientUpdateSendCnt(env);
656 CAResult_t CALEClientSendUnicastMessage(const char* address,
658 const uint32_t dataLen)
660 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
661 VERIFY_NON_NULL(address, TAG, "address is null");
662 VERIFY_NON_NULL(data, TAG, "data is null");
664 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
667 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
668 const uint32_t dataLen)
670 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
671 VERIFY_NON_NULL(data, TAG, "data is null");
675 OIC_LOG(ERROR, TAG, "g_jvm is null");
676 return CA_STATUS_FAILED;
679 bool isAttached = false;
681 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
684 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
685 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
689 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
690 return CA_STATUS_FAILED;
695 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
696 if (CA_STATUS_OK != ret)
698 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
703 (*g_jvm)->DetachCurrentThread(g_jvm);
709 CAResult_t CALEClientStartUnicastServer(const char* address)
714 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
716 return CA_NOT_SUPPORTED;
719 CAResult_t CALEClientStartMulticastServer()
721 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
723 return CA_NOT_SUPPORTED;
726 void CALEClientStopUnicastServer()
728 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
731 void CALEClientStopMulticastServer()
733 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
736 void CALEClientSetCallback(CAPacketReceiveCallback callback)
738 g_packetReceiveCallback = callback;
741 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
743 g_clientErrorCallback = callback;
746 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
748 VERIFY_NON_NULL(env, TAG, "env");
752 return CA_STATUS_FAILED;
755 if (0 == u_arraylist_length(g_deviceList) // multicast
756 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
758 // Wait for LE peripherals to be discovered.
760 // Number of times to wait for discovery to complete.
761 static size_t const RETRIES = 5;
763 static uint64_t const TIMEOUT =
764 2 * MICROSECS_PER_SEC; // Microseconds
766 // set scan interval and start scan
767 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1);
769 bool devicesDiscovered = false;
770 for (size_t i = 0; i < RETRIES; ++i)
772 OIC_LOG(DEBUG, TAG, "waiting for target device");
773 if (ca_cond_wait_for(g_deviceDescCond,
775 TIMEOUT) == CA_WAIT_SUCCESS)
777 ca_mutex_lock(g_deviceListMutex);
778 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
779 ca_mutex_unlock(g_deviceListMutex);
781 if (0 < scannedDeviceLen)
783 if (!address // multicast
784 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
786 devicesDiscovered = true;
793 OIC_LOG(INFO, TAG, "waiting..");
795 ca_mutex_lock(g_deviceScanRetryDelayMutex);
796 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
797 g_deviceScanRetryDelayMutex,
798 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
800 OIC_LOG(INFO, TAG, "finish to waiting for target device");
801 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
804 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
807 // checking whether a target device is found while waiting for time-out.
808 if (CALEClientIsDeviceInScanDeviceList(env, address))
810 devicesDiscovered = true;
819 // reset scan interval time after checking scanned devices
820 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0);
822 // time out for scanning devices
823 if (!devicesDiscovered)
825 return CA_STATUS_FAILED;
833 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
834 const uint32_t dataLen)
836 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
838 VERIFY_NON_NULL(address, TAG, "address is null");
839 VERIFY_NON_NULL(data, TAG, "data is null");
843 OIC_LOG(ERROR, TAG, "g_jvm is null");
844 return CA_STATUS_FAILED;
847 bool isAttached = false;
849 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
852 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
853 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
856 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
857 return CA_STATUS_FAILED;
862 ca_mutex_lock(g_threadSendMutex);
864 CALEClientSetSendFinishFlag(false);
866 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
867 if (CA_STATUS_OK != ret)
869 OIC_LOG(INFO, TAG, "there is no scanned device");
873 if (g_context && g_deviceList)
875 uint32_t length = u_arraylist_length(g_deviceList);
876 for (uint32_t index = 0; index < length; index++)
878 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
881 OIC_LOG(ERROR, TAG, "jarrayObj is null");
885 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
888 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
892 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
895 OIC_LOG(ERROR, TAG, "setAddress is null");
899 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
901 if (!strcmp(setAddress, address))
903 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
904 (*env)->DeleteLocalRef(env, jni_setAddress);
906 // stop scan while sending
907 CALEClientStopScanWithInterval();
911 (*env)->DeleteGlobalRef(env, g_sendBuffer);
914 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
915 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
916 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
918 // Target device to send message is just one.
921 ret = CALEClientSendData(env, jarrayObj);
922 if (CA_STATUS_OK != ret)
924 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
928 OIC_LOG(INFO, TAG, "wake up");
931 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
932 (*env)->DeleteLocalRef(env, jni_setAddress);
936 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
938 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
939 // if there is no connection state.
940 ca_mutex_lock(g_threadMutex);
941 if (!g_isFinishedSendData)
943 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
944 ca_cond_wait(g_threadCond, g_threadMutex);
945 OIC_LOG(DEBUG, TAG, "the data was sent");
947 ca_mutex_unlock(g_threadMutex);
951 (*g_jvm)->DetachCurrentThread(g_jvm);
954 // start LE Scan again
955 ret = CALEClientStartScanWithInterval();
956 if (CA_STATUS_OK != ret)
958 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
959 ca_mutex_unlock(g_threadSendMutex);
963 ca_mutex_unlock(g_threadSendMutex);
964 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
965 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
972 ret = CA_SEND_FAILED;
976 CAResult_t resetRet = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
978 if (CA_STATUS_OK != resetRet)
980 OIC_LOG_V(ERROR, TAG, "CALEClientUpdateDeviceState has failed (%d)", resetRet);
981 ret = CA_SEND_FAILED;
989 // start LE Scan again
990 ret = CALEClientStartScanWithInterval();
991 if (CA_STATUS_OK != ret)
993 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
994 ca_mutex_unlock(g_threadSendMutex);
997 (*g_jvm)->DetachCurrentThread(g_jvm);
1004 (*g_jvm)->DetachCurrentThread(g_jvm);
1007 ca_mutex_unlock(g_threadSendMutex);
1008 return CA_SEND_FAILED;
1011 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1012 const uint32_t dataLen)
1014 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1015 VERIFY_NON_NULL(data, TAG, "data is null");
1016 VERIFY_NON_NULL(env, TAG, "env is null");
1020 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1021 return CA_STATUS_FAILED;
1024 ca_mutex_lock(g_threadSendMutex);
1026 CALEClientSetSendFinishFlag(false);
1028 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1031 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1032 g_sendBuffer = NULL;
1035 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1036 if (CA_STATUS_OK != res)
1038 OIC_LOG(INFO, TAG, "there is no scanned device");
1042 // stop scan while sending
1043 CALEClientStopScanWithInterval();
1045 uint32_t length = u_arraylist_length(g_deviceList);
1046 g_targetCnt = length;
1048 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1049 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1050 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1052 for (uint32_t index = 0; index < length; index++)
1054 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1057 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1061 res = CALEClientSendData(env, jarrayObj);
1062 if (res != CA_STATUS_OK)
1064 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1068 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1070 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1071 ca_mutex_lock(g_threadMutex);
1072 if (!g_isFinishedSendData)
1074 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1075 ca_cond_wait(g_threadCond, g_threadMutex);
1076 OIC_LOG(DEBUG, TAG, "the data was sent");
1078 ca_mutex_unlock(g_threadMutex);
1080 // start LE Scan again
1081 res = CALEClientStartScanWithInterval();
1082 if (CA_STATUS_OK != res)
1084 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
1085 ca_mutex_unlock(g_threadSendMutex);
1089 ca_mutex_unlock(g_threadSendMutex);
1090 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1091 return CA_STATUS_OK;
1094 res = CALEClientStartScanWithInterval();
1095 if (CA_STATUS_OK != res)
1097 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
1098 ca_mutex_unlock(g_threadSendMutex);
1102 ca_mutex_unlock(g_threadSendMutex);
1103 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1104 return CA_SEND_FAILED;
1107 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1109 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1110 VERIFY_NON_NULL(device, TAG, "device is null");
1111 VERIFY_NON_NULL(env, TAG, "env is null");
1113 // get BLE address from bluetooth device object.
1114 char* address = NULL;
1115 CALEState_t* state = NULL;
1116 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1119 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1120 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1123 OIC_LOG(ERROR, TAG, "address is not available");
1124 return CA_STATUS_FAILED;
1126 ca_mutex_lock(g_deviceStateListMutex);
1127 state = CALEClientGetStateInfo(address);
1128 ca_mutex_unlock(g_deviceStateListMutex);
1133 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1135 // cancel previous connection request before connection
1136 // if there is gatt object in g_gattObjectList.
1139 jobject gatt = CALEClientGetGattObjInList(env, address);
1142 CAResult_t res = CALEClientDisconnect(env, gatt);
1143 if (CA_STATUS_OK != res)
1145 OIC_LOG(INFO, TAG, "there is no gatt object");
1148 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1151 // connection request
1152 jobject newGatt = CALEClientConnect(env, device,
1154 if (NULL == newGatt)
1156 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1157 return CA_STATUS_FAILED;
1162 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1163 STATE_SERVICE_CONNECTED))
1165 OIC_LOG(INFO, TAG, "GATT has already connected");
1167 jobject gatt = CALEClientGetGattObjInList(env, address);
1170 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1171 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1172 return CA_STATUS_FAILED;
1175 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1176 if (CA_STATUS_OK != ret)
1178 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1179 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1182 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1184 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1187 OIC_LOG(INFO, TAG, "service connecting...");
1189 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1190 STATE_DISCONNECTED))
1192 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1194 // cancel previous connection request before connection
1195 // if there is gatt object in g_gattObjectList.
1198 jobject gatt = CALEClientGetGattObjInList(env, address);
1201 CAResult_t res = CALEClientDisconnect(env, gatt);
1202 if (CA_STATUS_OK != res)
1204 OIC_LOG(INFO, TAG, "there is no gatt object");
1207 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1210 OIC_LOG(DEBUG, TAG, "start to connect LE");
1211 jobject gatt = CALEClientConnect(env, device,
1212 CALEClientGetFlagFromState(env, jni_address,
1213 CA_LE_AUTO_CONNECT_FLAG));
1217 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1218 return CA_STATUS_FAILED;
1223 return CA_STATUS_OK;
1226 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1228 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1229 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1231 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1232 "()Landroid/bluetooth/BluetoothDevice;");
1233 if (!jni_mid_getDevice)
1235 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1239 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1240 if (!jni_obj_device)
1242 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1246 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1249 OIC_LOG(ERROR, TAG, "jni_address is null");
1259 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1262 OIC_LOG(DEBUG, TAG, "Gatt Close");
1263 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1264 VERIFY_NON_NULL(env, TAG, "env is null");
1266 // get BluetoothGatt method
1267 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1268 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1269 if (!jni_mid_closeGatt)
1271 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1272 return CA_STATUS_OK;
1275 // call disconnect gatt method
1276 OIC_LOG(DEBUG, TAG, "request to close GATT");
1277 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1279 if ((*env)->ExceptionCheck(env))
1281 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1282 (*env)->ExceptionDescribe(env);
1283 (*env)->ExceptionClear(env);
1284 return CA_STATUS_FAILED;
1287 return CA_STATUS_OK;
1290 CAResult_t CALEClientStartScan()
1292 if (!g_isStartedLEClient)
1294 OIC_LOG(ERROR, TAG, "LE client is not started");
1295 return CA_STATUS_FAILED;
1300 OIC_LOG(ERROR, TAG, "g_jvm is null");
1301 return CA_STATUS_FAILED;
1304 bool isAttached = false;
1306 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1309 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1311 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1314 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1315 return CA_STATUS_FAILED;
1320 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1322 CAResult_t ret = CA_STATUS_OK;
1323 // scan gatt server with UUID
1324 if (g_leScanCallback && g_uuidList)
1327 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1329 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1331 if (CA_STATUS_OK != ret)
1333 if (CA_ADAPTER_NOT_ENABLED == ret)
1335 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1339 OIC_LOG(ERROR, TAG, "start scan has failed");
1346 (*g_jvm)->DetachCurrentThread(g_jvm);
1352 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1354 VERIFY_NON_NULL(callback, TAG, "callback is null");
1355 VERIFY_NON_NULL(env, TAG, "env is null");
1357 if (!CALEIsEnableBTAdapter(env))
1359 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1360 return CA_ADAPTER_NOT_ENABLED;
1363 // get default bt adapter class
1364 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1365 if (!jni_cid_BTAdapter)
1367 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1368 return CA_STATUS_FAILED;
1371 // get remote bt adapter method
1372 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1373 "getDefaultAdapter",
1374 METHODID_OBJECTNONPARAM);
1375 if (!jni_mid_getDefaultAdapter)
1377 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1378 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1379 return CA_STATUS_FAILED;
1382 // get start le scan method
1383 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1384 "(Landroid/bluetooth/BluetoothAdapter$"
1385 "LeScanCallback;)Z");
1386 if (!jni_mid_startLeScan)
1388 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1389 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1390 return CA_STATUS_FAILED;
1393 // gat bt adapter object
1394 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1395 jni_mid_getDefaultAdapter);
1396 if (!jni_obj_BTAdapter)
1398 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1399 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1400 return CA_STATUS_FAILED;
1403 // call start le scan method
1404 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1405 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1406 jni_mid_startLeScan, callback);
1407 if (!jni_obj_startLeScan)
1409 OIC_LOG(INFO, TAG, "startLeScan has failed");
1413 OIC_LOG(DEBUG, TAG, "LeScan has started");
1416 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1417 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1418 return CA_STATUS_OK;
1421 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1423 VERIFY_NON_NULL(callback, TAG, "callback is null");
1424 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1425 VERIFY_NON_NULL(env, TAG, "env is null");
1427 if (!CALEIsEnableBTAdapter(env))
1429 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1430 return CA_ADAPTER_NOT_ENABLED;
1433 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1434 if (!jni_cid_BTAdapter)
1436 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1437 return CA_STATUS_FAILED;
1440 // get remote bt adapter method
1441 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1442 "getDefaultAdapter",
1443 METHODID_OBJECTNONPARAM);
1444 if (!jni_mid_getDefaultAdapter)
1446 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1447 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1448 return CA_STATUS_FAILED;
1451 // get start le scan method
1452 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1453 "([Ljava/util/UUID;Landroid/bluetooth/"
1454 "BluetoothAdapter$LeScanCallback;)Z");
1455 if (!jni_mid_startLeScan)
1457 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1458 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1459 return CA_STATUS_FAILED;
1462 // get bt adapter object
1463 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1464 jni_mid_getDefaultAdapter);
1465 if (!jni_obj_BTAdapter)
1467 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1468 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1469 return CA_STATUS_FAILED;
1472 // call start le scan method
1473 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1474 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1475 jni_mid_startLeScan, uuids, callback);
1476 if (!jni_obj_startLeScan)
1478 OIC_LOG(INFO, TAG, "startLeScan has failed");
1482 OIC_LOG(DEBUG, TAG, "LeScan has started");
1485 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1486 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1487 return CA_STATUS_OK;
1490 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1492 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1493 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1496 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1499 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1503 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1504 "(Ljava/lang/String;)"
1505 "Ljava/util/UUID;");
1506 if (!jni_mid_fromString)
1508 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1512 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1513 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1517 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1521 return jni_obj_uuid;
1524 CAResult_t CALEClientStopScan()
1528 OIC_LOG(ERROR, TAG, "g_jvm is null");
1529 return CA_STATUS_FAILED;
1532 bool isAttached = false;
1534 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1537 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1538 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1541 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1542 return CA_STATUS_FAILED;
1547 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1548 if (CA_STATUS_OK != ret)
1550 if (CA_ADAPTER_NOT_ENABLED == ret)
1552 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1556 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1562 (*g_jvm)->DetachCurrentThread(g_jvm);
1568 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1570 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1571 VERIFY_NON_NULL(callback, TAG, "callback is null");
1572 VERIFY_NON_NULL(env, TAG, "env is null");
1574 if (!CALEIsEnableBTAdapter(env))
1576 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1577 return CA_ADAPTER_NOT_ENABLED;
1580 // get default bt adapter class
1581 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1582 if (!jni_cid_BTAdapter)
1584 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1585 return CA_STATUS_FAILED;
1588 // get remote bt adapter method
1589 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1590 "getDefaultAdapter",
1591 METHODID_OBJECTNONPARAM);
1592 if (!jni_mid_getDefaultAdapter)
1594 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1595 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1596 return CA_STATUS_FAILED;
1599 // get start le scan method
1600 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1601 "(Landroid/bluetooth/"
1602 "BluetoothAdapter$LeScanCallback;)V");
1603 if (!jni_mid_stopLeScan)
1605 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1606 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1607 return CA_STATUS_FAILED;
1610 // gat bt adapter object
1611 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1612 jni_mid_getDefaultAdapter);
1613 if (!jni_obj_BTAdapter)
1615 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1616 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1617 return CA_STATUS_FAILED;
1620 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1621 // call start le scan method
1622 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1623 if ((*env)->ExceptionCheck(env))
1625 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1626 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1627 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1628 (*env)->ExceptionDescribe(env);
1629 (*env)->ExceptionClear(env);
1630 return CA_STATUS_FAILED;
1633 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1634 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1635 return CA_STATUS_OK;
1638 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1640 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1641 VERIFY_NON_NULL(env, TAG, "env");
1642 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1644 ca_mutex_lock(g_deviceStateListMutex);
1646 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1649 OIC_LOG(ERROR, TAG, "address is not available");
1650 return CA_STATUS_FAILED;
1653 if (CALEClientIsDeviceInList(address))
1655 CALEState_t* curState = CALEClientGetStateInfo(address);
1658 OIC_LOG(ERROR, TAG, "curState is null");
1659 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1660 ca_mutex_unlock(g_deviceStateListMutex);
1661 return CA_STATUS_FAILED;
1663 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1667 case CA_LE_AUTO_CONNECT_FLAG:
1668 curState->autoConnectFlag = flag;
1670 case CA_LE_DESCRIPTOR_FOUND:
1671 curState->isDescriptorFound = flag;
1678 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1679 ca_mutex_unlock(g_deviceStateListMutex);
1680 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1681 return CA_STATUS_OK;
1684 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1686 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1687 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1688 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1690 ca_mutex_lock(g_deviceStateListMutex);
1692 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1695 OIC_LOG(ERROR, TAG, "address is not available");
1696 ca_mutex_unlock(g_deviceStateListMutex);
1700 CALEState_t* curState = CALEClientGetStateInfo(address);
1701 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1704 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1705 ca_mutex_unlock(g_deviceStateListMutex);
1709 jboolean ret = JNI_FALSE;
1712 case CA_LE_AUTO_CONNECT_FLAG:
1713 ret = curState->autoConnectFlag;
1715 case CA_LE_DESCRIPTOR_FOUND:
1716 ret = curState->isDescriptorFound;
1721 ca_mutex_unlock(g_deviceStateListMutex);
1723 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1724 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1728 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1730 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1731 VERIFY_NON_NULL(env, TAG, "env is null");
1732 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1734 ca_mutex_lock(g_threadSendMutex);
1736 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1739 OIC_LOG(ERROR, TAG, "jni_address is not available");
1740 ca_mutex_unlock(g_threadSendMutex);
1741 return CA_STATUS_FAILED;
1744 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1747 OIC_LOG(ERROR, TAG, "address is not available");
1748 ca_mutex_unlock(g_threadSendMutex);
1749 return CA_STATUS_FAILED;
1752 CAResult_t res = CA_STATUS_OK;
1753 if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1754 STATE_DISCONNECTED))
1756 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1757 if (NULL == newGatt)
1759 OIC_LOG(INFO, TAG, "newGatt is not available");
1760 res = CA_STATUS_FAILED;
1763 ca_mutex_unlock(g_threadSendMutex);
1768 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1770 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1771 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1772 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1774 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1775 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1778 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1781 OIC_LOG(ERROR, TAG, "address is not available");
1785 // close the gatt service
1786 jobject gatt = CALEClientGetGattObjInList(env, address);
1789 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1790 if (CA_STATUS_OK != res)
1792 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1793 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1797 // clean previous gatt object after close profile service
1798 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1799 if (CA_STATUS_OK != res)
1801 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1802 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1806 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1809 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1812 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1816 // add new gatt object into g_gattObjectList
1817 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1818 if (CA_STATUS_OK != res)
1820 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1827 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1829 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1830 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1831 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1833 if (!g_leGattCallback)
1835 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1839 if (!CALEIsEnableBTAdapter(env))
1841 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1845 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1848 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1852 // get BluetoothDevice method
1853 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1854 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1856 "(Landroid/content/Context;ZLandroid/"
1857 "bluetooth/BluetoothGattCallback;)"
1858 "Landroid/bluetooth/BluetoothGatt;");
1859 if (!jni_mid_connectGatt)
1861 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1865 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1866 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1867 jni_mid_connectGatt,
1869 autoconnect, g_leGattCallback);
1870 if (!jni_obj_connectGatt)
1872 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1873 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1874 CALEClientUpdateSendCnt(env);
1879 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1881 return jni_obj_connectGatt;
1884 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1886 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1888 VERIFY_NON_NULL(env, TAG, "env is null");
1889 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1891 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1892 if (!jni_cid_BTAdapter)
1894 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1895 return CA_STATUS_FAILED;
1898 // get remote bt adapter method
1899 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1900 "getDefaultAdapter",
1901 METHODID_OBJECTNONPARAM);
1902 if (!jni_mid_getDefaultAdapter)
1904 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1905 return CA_STATUS_FAILED;
1908 // gat bt adapter object
1909 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1910 jni_mid_getDefaultAdapter);
1911 if (!jni_obj_BTAdapter)
1913 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1914 return CA_STATUS_FAILED;
1917 // get closeProfileProxy method
1918 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1919 "closeProfileProxy",
1920 "(ILandroid/bluetooth/"
1921 "BluetoothProfile;)V");
1922 if (!jni_mid_closeProfileProxy)
1924 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1925 return CA_STATUS_FAILED;
1928 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1929 if (!jni_cid_BTProfile)
1931 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1932 return CA_STATUS_FAILED;
1935 // GATT - Constant value : 7 (0x00000007)
1936 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1940 OIC_LOG(ERROR, TAG, "id_gatt is null");
1941 return CA_STATUS_FAILED;
1944 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1946 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1947 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1948 if ((*env)->ExceptionCheck(env))
1950 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1951 (*env)->ExceptionDescribe(env);
1952 (*env)->ExceptionClear(env);
1953 return CA_STATUS_FAILED;
1956 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1957 return CA_STATUS_OK;
1961 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1963 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1964 VERIFY_NON_NULL(env, TAG, "env is null");
1965 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1967 // get BluetoothGatt method
1968 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1969 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1970 "disconnect", "()V");
1971 if (!jni_mid_disconnectGatt)
1973 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1974 return CA_STATUS_FAILED;
1977 // call disconnect gatt method
1978 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1979 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1980 if ((*env)->ExceptionCheck(env))
1982 OIC_LOG(ERROR, TAG, "disconnect has failed");
1983 (*env)->ExceptionDescribe(env);
1984 (*env)->ExceptionClear(env);
1985 return CA_STATUS_FAILED;
1988 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1990 return CA_STATUS_OK;
1993 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1995 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1996 VERIFY_NON_NULL(env, TAG, "env is null");
1998 if (!g_gattObjectList)
2000 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2001 return CA_STATUS_OK;
2004 uint32_t length = u_arraylist_length(g_gattObjectList);
2005 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2006 for (uint32_t index = 0; index < length; index++)
2008 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2009 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2012 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2015 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2016 if (CA_STATUS_OK != res)
2018 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2023 return CA_STATUS_OK;
2026 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2028 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2029 VERIFY_NON_NULL(env, TAG, "env is null");
2031 if (!g_gattObjectList)
2033 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2034 return CA_STATUS_OK;
2037 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2040 OIC_LOG(ERROR, TAG, "address is null");
2041 return CA_STATUS_FAILED;
2044 uint32_t length = u_arraylist_length(g_gattObjectList);
2045 for (uint32_t index = 0; index < length; index++)
2047 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2050 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2054 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2055 if (!jni_setAddress)
2057 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2058 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2059 return CA_STATUS_FAILED;
2062 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2065 OIC_LOG(ERROR, TAG, "setAddress is null");
2066 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2067 return CA_STATUS_FAILED;
2070 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2071 if (!strcmp(address, setAddress))
2073 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2074 if (CA_STATUS_OK != res)
2076 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2077 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2078 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2079 return CA_STATUS_FAILED;
2081 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2082 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2083 return CA_STATUS_OK;
2085 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2087 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2089 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2090 return CA_STATUS_OK;
2093 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2095 VERIFY_NON_NULL(env, TAG, "env is null");
2096 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2098 if (!CALEIsEnableBTAdapter(env))
2100 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2101 return CA_ADAPTER_NOT_ENABLED;
2104 // get BluetoothGatt.discoverServices method
2105 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2106 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2107 "discoverServices", "()Z");
2108 if (!jni_mid_discoverServices)
2110 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2111 return CA_STATUS_FAILED;
2114 // call disconnect gatt method
2115 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2116 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2119 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2120 return CA_STATUS_FAILED;
2123 return CA_STATUS_OK;
2126 static void CALEWriteCharacteristicThread(void* object)
2128 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2130 bool isAttached = false;
2132 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2135 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2136 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2140 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2146 jobject gatt = (jobject)object;
2147 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2148 if (CA_STATUS_OK != ret)
2150 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2155 (*g_jvm)->DetachCurrentThread(g_jvm);
2159 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2161 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2163 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2164 VERIFY_NON_NULL(env, TAG, "env is null");
2166 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2169 CALEClientSendFinish(env, gatt);
2170 return CA_STATUS_FAILED;
2173 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2176 CALEClientSendFinish(env, gatt);
2177 return CA_STATUS_FAILED;
2180 ca_mutex_lock(g_threadSendStateMutex);
2182 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2184 OIC_LOG(INFO, TAG, "current state is SENDING");
2185 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2186 ca_mutex_unlock(g_threadSendStateMutex);
2187 return CA_STATUS_OK;
2190 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2193 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2194 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2195 CALEClientSendFinish(env, gatt);
2196 ca_mutex_unlock(g_threadSendStateMutex);
2197 return CA_STATUS_FAILED;
2200 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2202 ca_mutex_unlock(g_threadSendStateMutex);
2205 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2206 if (!jni_obj_character)
2208 CALEClientSendFinish(env, gatt);
2209 return CA_STATUS_FAILED;
2212 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2213 if (CA_STATUS_OK != ret)
2215 CALEClientSendFinish(env, gatt);
2216 return CA_STATUS_FAILED;
2219 // wait for callback for write Characteristic with success to sent data
2220 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2221 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2222 if (!g_isSignalSetFlag)
2224 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2225 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2226 g_threadWriteCharacteristicMutex,
2227 WAIT_TIME_WRITE_CHARACTERISTIC))
2229 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2230 g_isSignalSetFlag = false;
2231 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2232 return CA_STATUS_FAILED;
2235 // reset flag set by writeCharacteristic Callback
2236 g_isSignalSetFlag = false;
2237 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2239 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2240 return CA_STATUS_OK;
2243 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2245 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2246 VERIFY_NON_NULL(env, TAG, "env is null");
2247 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2249 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2250 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2251 CALEWriteCharacteristicThread, (void*)gattParam))
2253 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2254 return CA_STATUS_FAILED;
2257 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2258 return CA_STATUS_OK;
2261 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2262 jobject gattCharacteristic)
2264 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2265 VERIFY_NON_NULL(env, TAG, "env is null");
2266 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2267 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2269 if (!CALEIsEnableBTAdapter(env))
2271 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2272 return CA_STATUS_FAILED;
2275 // get BluetoothGatt.write characteristic method
2276 OIC_LOG(DEBUG, TAG, "write characteristic method");
2277 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2278 "writeCharacteristic",
2279 "(Landroid/bluetooth/"
2280 "BluetoothGattCharacteristic;)Z");
2281 if (!jni_mid_writeCharacteristic)
2283 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2284 return CA_STATUS_FAILED;
2287 // call disconnect gatt method
2288 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2289 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2290 jni_mid_writeCharacteristic,
2291 gattCharacteristic);
2294 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2298 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2299 return CA_STATUS_FAILED;
2302 return CA_STATUS_OK;
2305 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2307 VERIFY_NON_NULL(env, TAG, "env is null");
2308 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2310 if (!CALEIsEnableBTAdapter(env))
2312 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2313 return CA_STATUS_FAILED;
2316 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2319 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2320 return CA_STATUS_FAILED;
2323 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2324 if (!jni_obj_GattCharacteristic)
2326 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2327 return CA_STATUS_FAILED;
2330 OIC_LOG(DEBUG, TAG, "read characteristic method");
2331 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2332 "readCharacteristic",
2333 "(Landroid/bluetooth/"
2334 "BluetoothGattCharacteristic;)Z");
2335 if (!jni_mid_readCharacteristic)
2337 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2338 return CA_STATUS_FAILED;
2341 // call disconnect gatt method
2342 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2343 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2344 jni_obj_GattCharacteristic);
2347 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2351 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2352 return CA_STATUS_FAILED;
2355 return CA_STATUS_OK;
2358 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2359 jobject characteristic)
2361 VERIFY_NON_NULL(env, TAG, "env is null");
2362 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2363 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2365 if (!CALEIsEnableBTAdapter(env))
2367 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2368 return CA_ADAPTER_NOT_ENABLED;
2371 // get BluetoothGatt.setCharacteristicNotification method
2372 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2373 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2374 "setCharacteristicNotification",
2375 "(Landroid/bluetooth/"
2376 "BluetoothGattCharacteristic;Z)Z");
2377 if (!jni_mid_setNotification)
2379 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2380 return CA_STATUS_FAILED;
2383 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2384 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2385 characteristic, JNI_TRUE);
2386 if (JNI_TRUE == ret)
2388 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2392 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2393 return CA_STATUS_FAILED;
2396 return CA_STATUS_OK;
2399 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2401 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2402 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2403 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2405 if (!CALEIsEnableBTAdapter(env))
2407 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2411 // get BluetoothGatt.getService method
2412 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2413 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2415 "(Ljava/util/UUID;)Landroid/bluetooth/"
2416 "BluetoothGattService;");
2417 if (!jni_mid_getService)
2419 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2423 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2424 if (!jni_obj_service_uuid)
2426 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2430 // get bluetooth gatt service
2431 OIC_LOG(DEBUG, TAG, "request to get service");
2432 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2433 jni_obj_service_uuid);
2434 if (!jni_obj_gattService)
2436 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2440 // get bluetooth gatt service method
2441 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2442 "BluetoothGattService",
2443 "getCharacteristic",
2444 "(Ljava/util/UUID;)"
2445 "Landroid/bluetooth/"
2446 "BluetoothGattCharacteristic;");
2447 if (!jni_mid_getCharacteristic)
2449 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2453 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2456 OIC_LOG(ERROR, TAG, "uuid is null");
2460 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2461 if (!jni_obj_tx_uuid)
2463 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2464 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2468 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2469 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2470 jni_mid_getCharacteristic,
2473 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2474 return jni_obj_GattCharacteristic;
2477 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2479 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2480 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2481 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2482 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2484 if (!CALEIsEnableBTAdapter(env))
2486 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2490 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2493 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2497 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2498 if (!jni_obj_GattCharacteristic)
2500 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2504 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2505 "/BluetoothGattCharacteristic");
2506 if (!jni_cid_BTGattCharacteristic)
2508 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2512 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2513 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2515 if (!jni_mid_setValue)
2517 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2521 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2523 if (JNI_TRUE == ret)
2525 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2529 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2534 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2535 "setWriteType", "(I)V");
2536 if (!jni_mid_setWriteType)
2538 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2542 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2543 "WRITE_TYPE_NO_RESPONSE", "I");
2544 if (!jni_fid_no_response)
2546 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2550 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2551 jni_fid_no_response);
2553 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2555 return jni_obj_GattCharacteristic;
2558 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2560 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2561 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2563 if (!CALEIsEnableBTAdapter(env))
2565 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2569 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2570 "BluetoothGattCharacteristic",
2571 "getValue", "()[B");
2572 if (!jni_mid_getValue)
2574 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2578 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2580 return jni_obj_data_array;
2583 CAResult_t CALEClientCreateUUIDList()
2587 OIC_LOG(ERROR, TAG, "g_jvm is null");
2588 return CA_STATUS_FAILED;
2591 bool isAttached = false;
2593 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2596 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2597 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2601 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2602 return CA_STATUS_FAILED;
2607 // create new object array
2608 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2609 if (!jni_cid_uuid_list)
2611 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2615 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2616 jni_cid_uuid_list, NULL);
2617 if (!jni_obj_uuid_list)
2619 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2624 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2627 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2630 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2632 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2636 (*g_jvm)->DetachCurrentThread(g_jvm);
2639 return CA_STATUS_OK;
2646 (*g_jvm)->DetachCurrentThread(g_jvm);
2648 return CA_STATUS_FAILED;
2651 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2652 jobject characteristic)
2654 VERIFY_NON_NULL(env, TAG, "env is null");
2655 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2656 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2658 if (!CALEIsEnableBTAdapter(env))
2660 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2661 return CA_ADAPTER_NOT_ENABLED;
2664 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2665 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2666 "BluetoothGattCharacteristic",
2668 "(Ljava/util/UUID;)Landroid/bluetooth/"
2669 "BluetoothGattDescriptor;");
2670 if (!jni_mid_getDescriptor)
2672 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2673 return CA_STATUS_FAILED;
2676 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2677 if (!jni_obj_cc_uuid)
2679 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2680 return CA_STATUS_FAILED;
2683 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2684 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2685 jni_mid_getDescriptor, jni_obj_cc_uuid);
2686 if (!jni_obj_descriptor)
2688 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2689 return CA_NOT_SUPPORTED;
2692 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2693 jclass jni_cid_descriptor = (*env)->FindClass(env,
2694 "android/bluetooth/BluetoothGattDescriptor");
2695 if (!jni_cid_descriptor)
2697 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2698 return CA_STATUS_FAILED;
2701 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2702 if (!jni_mid_setValue)
2704 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2705 return CA_STATUS_FAILED;
2708 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2709 "ENABLE_NOTIFICATION_VALUE", "[B");
2710 if (!jni_fid_NotiValue)
2712 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2713 return CA_STATUS_FAILED;
2716 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2718 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2719 env, jni_obj_descriptor, jni_mid_setValue,
2720 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2723 OIC_LOG(DEBUG, TAG, "setValue success");
2727 OIC_LOG(ERROR, TAG, "setValue has failed");
2728 return CA_STATUS_FAILED;
2731 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2733 "(Landroid/bluetooth/"
2734 "BluetoothGattDescriptor;)Z");
2735 if (!jni_mid_writeDescriptor)
2737 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2738 return CA_STATUS_FAILED;
2741 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2742 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2743 jni_obj_descriptor);
2746 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2750 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2751 return CA_STATUS_FAILED;
2754 return CA_STATUS_OK;
2757 void CALEClientCreateScanDeviceList(JNIEnv *env)
2759 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2760 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2762 ca_mutex_lock(g_deviceListMutex);
2763 // create new object array
2764 if (g_deviceList == NULL)
2766 OIC_LOG(DEBUG, TAG, "Create device list");
2768 g_deviceList = u_arraylist_create();
2770 ca_mutex_unlock(g_deviceListMutex);
2773 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2775 VERIFY_NON_NULL(device, TAG, "device is null");
2776 VERIFY_NON_NULL(env, TAG, "env is null");
2778 ca_mutex_lock(g_deviceListMutex);
2782 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2783 CALEClientStopScanWithInterval();
2785 ca_mutex_unlock(g_deviceListMutex);
2786 return CA_STATUS_FAILED;
2789 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2790 if (!jni_remoteAddress)
2792 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2793 ca_mutex_unlock(g_deviceListMutex);
2794 return CA_STATUS_FAILED;
2797 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2800 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2801 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2802 ca_mutex_unlock(g_deviceListMutex);
2803 return CA_STATUS_FAILED;
2806 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2808 jobject gdevice = (*env)->NewGlobalRef(env, device);
2809 u_arraylist_add(g_deviceList, gdevice);
2810 ca_cond_signal(g_deviceDescCond);
2811 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2813 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2814 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2816 ca_mutex_unlock(g_deviceListMutex);
2818 return CA_STATUS_OK;
2821 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2823 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2824 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2828 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2832 uint32_t length = u_arraylist_length(g_deviceList);
2833 for (uint32_t index = 0; index < length; index++)
2835 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2838 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2842 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2843 if (!jni_setAddress)
2845 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2849 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2852 OIC_LOG(ERROR, TAG, "setAddress is null");
2853 (*env)->DeleteLocalRef(env, jni_setAddress);
2857 if (!strcmp(remoteAddress, setAddress))
2859 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2860 (*env)->DeleteLocalRef(env, jni_setAddress);
2864 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2865 (*env)->DeleteLocalRef(env, jni_setAddress);
2868 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2873 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2875 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2876 VERIFY_NON_NULL(env, TAG, "env is null");
2878 ca_mutex_lock(g_deviceListMutex);
2882 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2883 ca_mutex_unlock(g_deviceListMutex);
2884 return CA_STATUS_FAILED;
2887 uint32_t length = u_arraylist_length(g_deviceList);
2888 for (uint32_t index = 0; index < length; index++)
2890 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2893 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2896 (*env)->DeleteGlobalRef(env, jarrayObj);
2900 OICFree(g_deviceList);
2901 g_deviceList = NULL;
2903 ca_mutex_unlock(g_deviceListMutex);
2904 return CA_STATUS_OK;
2907 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2909 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2910 VERIFY_NON_NULL(address, TAG, "address is null");
2911 VERIFY_NON_NULL(env, TAG, "env is null");
2913 ca_mutex_lock(g_deviceListMutex);
2917 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2918 ca_mutex_unlock(g_deviceListMutex);
2919 return CA_STATUS_FAILED;
2922 uint32_t length = u_arraylist_length(g_deviceList);
2923 for (uint32_t index = 0; index < length; index++)
2925 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2928 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2929 ca_mutex_unlock(g_deviceListMutex);
2930 return CA_STATUS_FAILED;
2933 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2934 if (!jni_setAddress)
2936 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2937 ca_mutex_unlock(g_deviceListMutex);
2938 return CA_STATUS_FAILED;
2941 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2944 OIC_LOG(ERROR, TAG, "setAddress is null");
2945 ca_mutex_unlock(g_deviceListMutex);
2946 return CA_STATUS_FAILED;
2949 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2952 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2953 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2954 ca_mutex_unlock(g_deviceListMutex);
2955 return CA_STATUS_FAILED;
2958 if (!strcmp(setAddress, remoteAddress))
2960 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2961 (*env)->DeleteGlobalRef(env, jarrayObj);
2963 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2964 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2966 if (NULL == u_arraylist_remove(g_deviceList, index))
2968 OIC_LOG(ERROR, TAG, "List removal failed.");
2969 ca_mutex_unlock(g_deviceListMutex);
2970 return CA_STATUS_FAILED;
2972 ca_mutex_unlock(g_deviceListMutex);
2973 return CA_STATUS_OK;
2975 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2976 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2979 ca_mutex_unlock(g_deviceListMutex);
2980 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2982 return CA_STATUS_OK;
2989 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2991 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2992 VERIFY_NON_NULL(env, TAG, "env is null");
2993 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2995 ca_mutex_lock(g_gattObjectMutex);
2997 if (!g_gattObjectList)
2999 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
3000 ca_mutex_unlock(g_gattObjectMutex);
3001 return CA_STATUS_FAILED;
3004 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3005 if (!jni_remoteAddress)
3007 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3008 ca_mutex_unlock(g_gattObjectMutex);
3009 return CA_STATUS_FAILED;
3012 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3015 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3016 ca_mutex_unlock(g_gattObjectMutex);
3017 return CA_STATUS_FAILED;
3020 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3021 if (!CALEClientIsGattObjInList(env, remoteAddress))
3023 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3024 u_arraylist_add(g_gattObjectList, newGatt);
3025 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3028 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3029 ca_mutex_unlock(g_gattObjectMutex);
3030 return CA_STATUS_OK;
3033 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3035 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
3036 VERIFY_NON_NULL(env, TAG, "env is null");
3037 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3039 uint32_t length = u_arraylist_length(g_gattObjectList);
3040 for (uint32_t index = 0; index < length; index++)
3043 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3046 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3050 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3051 if (!jni_setAddress)
3053 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3057 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3060 OIC_LOG(ERROR, TAG, "setAddress is null");
3064 if (!strcmp(remoteAddress, setAddress))
3066 OIC_LOG(DEBUG, TAG, "the device is already set");
3067 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3072 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3077 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3081 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3083 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3084 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3085 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3087 ca_mutex_lock(g_gattObjectMutex);
3088 uint32_t length = u_arraylist_length(g_gattObjectList);
3089 for (uint32_t index = 0; index < length; index++)
3091 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3094 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3095 ca_mutex_unlock(g_gattObjectMutex);
3099 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3100 if (!jni_setAddress)
3102 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3103 ca_mutex_unlock(g_gattObjectMutex);
3107 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3110 OIC_LOG(ERROR, TAG, "setAddress is null");
3111 ca_mutex_unlock(g_gattObjectMutex);
3115 if (!strcmp(remoteAddress, setAddress))
3117 OIC_LOG(DEBUG, TAG, "the device is already set");
3118 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3119 ca_mutex_unlock(g_gattObjectMutex);
3122 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3125 ca_mutex_unlock(g_gattObjectMutex);
3126 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3130 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3132 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3133 VERIFY_NON_NULL(env, TAG, "env is null");
3135 ca_mutex_lock(g_gattObjectMutex);
3136 if (!g_gattObjectList)
3138 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3139 ca_mutex_unlock(g_gattObjectMutex);
3140 return CA_STATUS_OK;
3143 uint32_t length = u_arraylist_length(g_gattObjectList);
3144 for (uint32_t index = 0; index < length; index++)
3146 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3149 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3152 (*env)->DeleteGlobalRef(env, jarrayObj);
3156 OICFree(g_gattObjectList);
3157 g_gattObjectList = NULL;
3158 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3159 ca_mutex_unlock(g_gattObjectMutex);
3160 return CA_STATUS_OK;
3163 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3165 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3166 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3167 VERIFY_NON_NULL(env, TAG, "env is null");
3169 ca_mutex_lock(g_gattObjectMutex);
3170 if (!g_gattObjectList)
3172 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3173 ca_mutex_unlock(g_gattObjectMutex);
3174 return CA_STATUS_OK;
3177 uint32_t length = u_arraylist_length(g_gattObjectList);
3178 for (uint32_t index = 0; index < length; index++)
3180 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3183 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3184 ca_mutex_unlock(g_gattObjectMutex);
3185 return CA_STATUS_FAILED;
3188 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3189 if (!jni_setAddress)
3191 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3192 ca_mutex_unlock(g_gattObjectMutex);
3193 return CA_STATUS_FAILED;
3196 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3199 OIC_LOG(ERROR, TAG, "setAddress is null");
3200 ca_mutex_unlock(g_gattObjectMutex);
3201 return CA_STATUS_FAILED;
3204 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3205 if (!jni_remoteAddress)
3207 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3208 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3209 ca_mutex_unlock(g_gattObjectMutex);
3210 return CA_STATUS_FAILED;
3213 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3216 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3217 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3218 ca_mutex_unlock(g_gattObjectMutex);
3219 return CA_STATUS_FAILED;
3222 if (!strcmp(setAddress, remoteAddress))
3224 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3225 (*env)->DeleteGlobalRef(env, jarrayObj);
3227 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3228 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3230 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3232 OIC_LOG(ERROR, TAG, "List removal failed.");
3233 ca_mutex_unlock(g_gattObjectMutex);
3234 return CA_STATUS_FAILED;
3236 ca_mutex_unlock(g_gattObjectMutex);
3237 return CA_STATUS_OK;
3239 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3240 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3243 ca_mutex_unlock(g_gattObjectMutex);
3244 OIC_LOG(DEBUG, TAG, "there are no target object");
3245 return CA_STATUS_OK;
3248 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3250 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3251 VERIFY_NON_NULL(addr, TAG, "addr is null");
3252 VERIFY_NON_NULL(env, TAG, "env is null");
3254 ca_mutex_lock(g_gattObjectMutex);
3255 if (!g_gattObjectList)
3257 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3258 ca_mutex_unlock(g_gattObjectMutex);
3259 return CA_STATUS_OK;
3262 uint32_t length = u_arraylist_length(g_gattObjectList);
3263 for (uint32_t index = 0; index < length; index++)
3265 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3268 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3269 ca_mutex_unlock(g_gattObjectMutex);
3270 return CA_STATUS_FAILED;
3273 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3274 if (!jni_setAddress)
3276 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3277 ca_mutex_unlock(g_gattObjectMutex);
3278 return CA_STATUS_FAILED;
3281 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3284 OIC_LOG(ERROR, TAG, "setAddress is null");
3285 ca_mutex_unlock(g_gattObjectMutex);
3286 return CA_STATUS_FAILED;
3289 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3292 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3293 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3294 ca_mutex_unlock(g_gattObjectMutex);
3295 return CA_STATUS_FAILED;
3298 if (!strcmp(setAddress, remoteAddress))
3300 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3301 (*env)->DeleteGlobalRef(env, jarrayObj);
3303 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3304 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3305 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3307 OIC_LOG(ERROR, TAG, "List removal failed.");
3308 ca_mutex_unlock(g_gattObjectMutex);
3309 return CA_STATUS_FAILED;
3311 ca_mutex_unlock(g_gattObjectMutex);
3312 return CA_STATUS_OK;
3314 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3315 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3318 ca_mutex_unlock(g_gattObjectMutex);
3319 OIC_LOG(DEBUG, TAG, "there are no target object");
3320 return CA_STATUS_FAILED;
3323 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3325 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3327 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3328 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3330 // get Bluetooth Address
3331 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3332 if (!jni_btTargetAddress)
3334 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3338 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3341 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3345 // get method ID of getDevice()
3346 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3347 "getDevice", METHODID_BT_DEVICE);
3348 if (!jni_mid_getDevice)
3350 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3351 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3355 ca_mutex_lock(g_gattObjectMutex);
3357 size_t length = u_arraylist_length(g_gattObjectList);
3358 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3359 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3361 for (size_t index = 0; index < length; index++)
3363 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3366 ca_mutex_unlock(g_gattObjectMutex);
3367 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3368 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3372 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3373 if (!jni_obj_device)
3375 ca_mutex_unlock(g_gattObjectMutex);
3376 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3377 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3381 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3384 ca_mutex_unlock(g_gattObjectMutex);
3385 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3386 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3390 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3393 ca_mutex_unlock(g_gattObjectMutex);
3394 OIC_LOG(ERROR, TAG, "btAddress is not available");
3395 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3399 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3400 if (!strcmp(targetAddress, btAddress))
3402 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3405 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3408 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3410 ca_mutex_unlock(g_gattObjectMutex);
3411 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3412 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3413 (*env)->DeleteLocalRef(env, jni_btAddress);
3414 (*env)->DeleteLocalRef(env, jni_obj_device);
3415 return jni_LEAddress;
3417 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3418 (*env)->DeleteLocalRef(env, jni_btAddress);
3419 (*env)->DeleteLocalRef(env, jni_obj_device);
3421 ca_mutex_unlock(g_gattObjectMutex);
3423 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3424 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3432 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3433 uint16_t target_state)
3435 VERIFY_NON_NULL(address, TAG, "address is null");
3436 VERIFY_NON_NULL(address, TAG, "state_type is null");
3437 VERIFY_NON_NULL(address, TAG, "target_state is null");
3439 if (!g_deviceStateList)
3441 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3442 return CA_STATUS_FAILED;
3445 ca_mutex_lock(g_deviceStateListMutex);
3447 if (CALEClientIsDeviceInList(address))
3449 CALEState_t* curState = CALEClientGetStateInfo(address);
3452 OIC_LOG(ERROR, TAG, "curState is null");
3453 ca_mutex_unlock(g_deviceStateListMutex);
3454 return CA_STATUS_FAILED;
3459 case CA_LE_CONNECTION_STATE:
3460 curState->connectedState = target_state;
3462 case CA_LE_SEND_STATE:
3463 curState->sendState = target_state;
3468 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3469 curState->address, curState->connectedState, curState->sendState,
3470 curState->autoConnectFlag);
3472 else /** state is added newly **/
3474 if (strlen(address) > CA_MACADDR_SIZE)
3476 OIC_LOG(ERROR, TAG, "address is not proper");
3477 ca_mutex_unlock(g_deviceStateListMutex);
3478 return CA_STATUS_INVALID_PARAM;
3481 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3484 OIC_LOG(ERROR, TAG, "out of memory");
3485 ca_mutex_unlock(g_deviceStateListMutex);
3486 return CA_MEMORY_ALLOC_FAILED;
3489 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3493 case CA_LE_CONNECTION_STATE:
3494 newstate->connectedState = target_state;
3495 newstate->sendState = STATE_SEND_NONE;
3497 case CA_LE_SEND_STATE:
3498 newstate->connectedState = STATE_DISCONNECTED;
3499 newstate->sendState = target_state;
3504 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3505 "conn : %d, send : %d, ACFlag : %d",
3506 newstate->address, newstate->connectedState, newstate->sendState,
3507 newstate->autoConnectFlag);
3508 u_arraylist_add(g_deviceStateList, newstate); // update new state
3510 ca_mutex_unlock(g_deviceStateListMutex);
3512 return CA_STATUS_OK;
3515 bool CALEClientIsDeviceInList(const char* remoteAddress)
3517 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3519 if (!g_deviceStateList)
3521 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3525 uint32_t length = u_arraylist_length(g_deviceStateList);
3526 for (uint32_t index = 0; index < length; index++)
3528 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3531 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3535 if (!strcmp(remoteAddress, state->address))
3537 OIC_LOG(DEBUG, TAG, "the device is already set");
3546 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3550 CAResult_t CALEClientRemoveAllDeviceState()
3552 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3554 ca_mutex_lock(g_deviceStateListMutex);
3555 if (!g_deviceStateList)
3557 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3558 ca_mutex_unlock(g_deviceStateListMutex);
3559 return CA_STATUS_FAILED;
3562 uint32_t length = u_arraylist_length(g_deviceStateList);
3563 for (uint32_t index = 0; index < length; index++)
3565 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3568 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3574 OICFree(g_deviceStateList);
3575 g_deviceStateList = NULL;
3576 ca_mutex_unlock(g_deviceStateListMutex);
3578 return CA_STATUS_OK;
3581 CAResult_t CALEClientResetDeviceStateForAll()
3583 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3585 ca_mutex_lock(g_deviceStateListMutex);
3586 if (!g_deviceStateList)
3588 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3589 ca_mutex_unlock(g_deviceStateListMutex);
3590 return CA_STATUS_FAILED;
3593 size_t length = u_arraylist_length(g_deviceStateList);
3594 for (size_t index = 0; index < length; index++)
3596 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3599 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3603 // autoConnectFlag value will be not changed,
3604 // since it has reset only termination case.
3605 state->connectedState = STATE_DISCONNECTED;
3606 state->sendState = STATE_SEND_NONE;
3608 ca_mutex_unlock(g_deviceStateListMutex);
3610 return CA_STATUS_OK;
3613 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3615 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3616 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3618 if (!g_deviceStateList)
3620 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3621 return CA_STATUS_FAILED;
3624 uint32_t length = u_arraylist_length(g_deviceStateList);
3625 for (uint32_t index = 0; index < length; index++)
3627 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3630 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3634 if (!strcmp(state->address, remoteAddress))
3636 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3638 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3640 if (NULL == targetState)
3642 OIC_LOG(ERROR, TAG, "List removal failed.");
3643 return CA_STATUS_FAILED;
3646 OICFree(targetState);
3647 return CA_STATUS_OK;
3651 return CA_STATUS_OK;
3654 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3656 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3658 if (!g_deviceStateList)
3660 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3664 uint32_t length = u_arraylist_length(g_deviceStateList);
3665 OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
3666 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3668 for (uint32_t index = 0; index < length; index++)
3670 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3673 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3677 OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
3679 if (!strcmp(state->address, remoteAddress))
3681 OIC_LOG(DEBUG, TAG, "found state");
3686 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
3690 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3691 uint16_t target_state)
3693 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3694 state_type, target_state);
3695 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3697 ca_mutex_lock(g_deviceStateListMutex);
3698 if (!g_deviceStateList)
3700 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3701 ca_mutex_unlock(g_deviceStateListMutex);
3705 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3708 OIC_LOG(ERROR, TAG, "state is null");
3709 ca_mutex_unlock(g_deviceStateListMutex);
3713 uint16_t curValue = 0;
3716 case CA_LE_CONNECTION_STATE:
3717 curValue = state->connectedState;
3719 case CA_LE_SEND_STATE:
3720 curValue = state->sendState;
3726 if (target_state == curValue)
3728 ca_mutex_unlock(g_deviceStateListMutex);
3733 ca_mutex_unlock(g_deviceStateListMutex);
3737 ca_mutex_unlock(g_deviceStateListMutex);
3741 void CALEClientCreateDeviceList()
3743 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3745 // create new object array
3746 if (!g_gattObjectList)
3748 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3750 g_gattObjectList = u_arraylist_create();
3753 if (!g_deviceStateList)
3755 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3757 g_deviceStateList = u_arraylist_create();
3762 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3764 g_deviceList = u_arraylist_create();
3769 * Check Sent Count for remove g_sendBuffer
3771 void CALEClientUpdateSendCnt(JNIEnv *env)
3773 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3775 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3777 ca_mutex_lock(g_threadMutex);
3781 if (g_targetCnt <= g_currentSentCnt)
3784 g_currentSentCnt = 0;
3788 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3789 g_sendBuffer = NULL;
3791 // notity the thread
3792 ca_cond_signal(g_threadCond);
3794 CALEClientSetSendFinishFlag(true);
3795 OIC_LOG(DEBUG, TAG, "set signal for send data");
3798 ca_mutex_unlock(g_threadMutex);
3801 CAResult_t CALEClientInitGattMutexVaraibles()
3803 if (NULL == g_bleReqRespClientCbMutex)
3805 g_bleReqRespClientCbMutex = ca_mutex_new();
3806 if (NULL == g_bleReqRespClientCbMutex)
3808 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3809 return CA_STATUS_FAILED;
3813 if (NULL == g_bleServerBDAddressMutex)
3815 g_bleServerBDAddressMutex = ca_mutex_new();
3816 if (NULL == g_bleServerBDAddressMutex)
3818 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3819 return CA_STATUS_FAILED;
3823 if (NULL == g_threadMutex)
3825 g_threadMutex = ca_mutex_new();
3826 if (NULL == g_threadMutex)
3828 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3829 return CA_STATUS_FAILED;
3833 if (NULL == g_threadSendMutex)
3835 g_threadSendMutex = ca_mutex_new();
3836 if (NULL == g_threadSendMutex)
3838 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3839 return CA_STATUS_FAILED;
3843 if (NULL == g_deviceListMutex)
3845 g_deviceListMutex = ca_mutex_new();
3846 if (NULL == g_deviceListMutex)
3848 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3849 return CA_STATUS_FAILED;
3853 if (NULL == g_gattObjectMutex)
3855 g_gattObjectMutex = ca_mutex_new();
3856 if (NULL == g_gattObjectMutex)
3858 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3859 return CA_STATUS_FAILED;
3863 if (NULL == g_deviceStateListMutex)
3865 g_deviceStateListMutex = ca_mutex_new();
3866 if (NULL == g_deviceStateListMutex)
3868 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3869 return CA_STATUS_FAILED;
3873 if (NULL == g_SendFinishMutex)
3875 g_SendFinishMutex = ca_mutex_new();
3876 if (NULL == g_SendFinishMutex)
3878 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3879 return CA_STATUS_FAILED;
3883 if (NULL == g_threadWriteCharacteristicMutex)
3885 g_threadWriteCharacteristicMutex = ca_mutex_new();
3886 if (NULL == g_threadWriteCharacteristicMutex)
3888 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3889 return CA_STATUS_FAILED;
3893 if (NULL == g_deviceScanRetryDelayMutex)
3895 g_deviceScanRetryDelayMutex = ca_mutex_new();
3896 if (NULL == g_deviceScanRetryDelayMutex)
3898 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3899 return CA_STATUS_FAILED;
3903 if (NULL == g_threadSendStateMutex)
3905 g_threadSendStateMutex = ca_mutex_new();
3906 if (NULL == g_threadSendStateMutex)
3908 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3909 return CA_STATUS_FAILED;
3913 if (NULL == g_threadScanIntervalMutex)
3915 g_threadScanIntervalMutex = ca_mutex_new();
3916 if (NULL == g_threadScanIntervalMutex)
3918 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3919 return CA_STATUS_FAILED;
3923 return CA_STATUS_OK;
3926 void CALEClientTerminateGattMutexVariables()
3928 ca_mutex_free(g_bleReqRespClientCbMutex);
3929 g_bleReqRespClientCbMutex = NULL;
3931 ca_mutex_free(g_bleServerBDAddressMutex);
3932 g_bleServerBDAddressMutex = NULL;
3934 ca_mutex_free(g_threadMutex);
3935 g_threadMutex = NULL;
3937 ca_mutex_free(g_threadSendMutex);
3938 g_threadSendMutex = NULL;
3940 ca_mutex_free(g_deviceListMutex);
3941 g_deviceListMutex = NULL;
3943 ca_mutex_free(g_SendFinishMutex);
3944 g_SendFinishMutex = NULL;
3946 ca_mutex_free(g_threadWriteCharacteristicMutex);
3947 g_threadWriteCharacteristicMutex = NULL;
3949 ca_mutex_free(g_deviceScanRetryDelayMutex);
3950 g_deviceScanRetryDelayMutex = NULL;
3952 ca_mutex_free(g_threadSendStateMutex);
3953 g_threadSendStateMutex = NULL;
3955 ca_mutex_free(g_threadScanIntervalMutex);
3956 g_threadScanIntervalMutex = NULL;
3959 void CALEClientSetSendFinishFlag(bool flag)
3961 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3963 ca_mutex_lock(g_SendFinishMutex);
3964 g_isFinishedSendData = flag;
3965 ca_mutex_unlock(g_SendFinishMutex);
3972 CAResult_t CAStartLEGattClient()
3974 // init mutex for send logic
3975 if (!g_deviceDescCond)
3977 g_deviceDescCond = ca_cond_new();
3982 g_threadCond = ca_cond_new();
3985 if (!g_threadWriteCharacteristicCond)
3987 g_threadWriteCharacteristicCond = ca_cond_new();
3990 if (!g_threadScanIntervalCond)
3992 g_threadScanIntervalCond = ca_cond_new();
3995 CAResult_t ret = CALEClientStartScanWithInterval();
3996 if (CA_STATUS_OK != ret)
3998 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
4002 g_isStartedLEClient = true;
4003 return CA_STATUS_OK;
4006 void CAStopLEGattClient()
4008 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4012 OIC_LOG(ERROR, TAG, "g_jvm is null");
4016 bool isAttached = false;
4018 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4021 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
4022 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4026 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4032 CAResult_t ret = CALEClientDisconnectAll(env);
4033 if (CA_STATUS_OK != ret)
4035 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4038 CALEClientStopScanWithInterval();
4040 ca_mutex_lock(g_threadMutex);
4041 OIC_LOG(DEBUG, TAG, "signal - connection cond");
4042 ca_cond_signal(g_threadCond);
4043 CALEClientSetSendFinishFlag(true);
4044 ca_mutex_unlock(g_threadMutex);
4046 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4047 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4048 ca_cond_signal(g_threadWriteCharacteristicCond);
4049 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4051 ca_mutex_lock(g_deviceScanRetryDelayMutex);
4052 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4053 ca_cond_signal(g_deviceScanRetryDelayCond);
4054 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
4056 ca_mutex_lock(g_threadScanIntervalMutex);
4057 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4058 ca_cond_signal(g_threadScanIntervalCond);
4059 ca_mutex_unlock(g_threadScanIntervalMutex);
4061 ca_cond_free(g_deviceDescCond);
4062 ca_cond_free(g_threadCond);
4063 ca_cond_free(g_threadWriteCharacteristicCond);
4064 ca_cond_free(g_deviceScanRetryDelayCond);
4065 ca_cond_free(g_threadScanIntervalCond);
4067 g_deviceDescCond = NULL;
4068 g_threadCond = NULL;
4069 g_threadWriteCharacteristicCond = NULL;
4070 g_deviceScanRetryDelayCond = NULL;
4071 g_threadScanIntervalCond = NULL;
4075 (*g_jvm)->DetachCurrentThread(g_jvm);
4080 CAResult_t CAInitializeLEGattClient()
4082 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4083 CALEClientInitialize();
4084 return CA_STATUS_OK;
4087 void CATerminateLEGattClient()
4089 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4090 CAStopLEGattClient();
4091 CALEClientTerminate();
4094 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4095 uint32_t dataLen, CALETransferType_t type,
4098 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4099 VERIFY_NON_NULL(data, TAG, "data is null");
4100 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4102 if (LE_UNICAST != type || position < 0)
4104 OIC_LOG(ERROR, TAG, "this request is not unicast");
4105 return CA_STATUS_INVALID_PARAM;
4108 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4111 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4113 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4114 VERIFY_NON_NULL(data, TAG, "data is null");
4116 return CALEClientSendMulticastMessage(data, dataLen);
4119 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4121 ca_mutex_lock(g_bleReqRespClientCbMutex);
4122 g_CABLEClientDataReceivedCallback = callback;
4123 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4126 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4128 g_threadPoolHandle = handle;
4131 CAResult_t CAGetLEAddress(char **local_address)
4133 VERIFY_NON_NULL(local_address, TAG, "local_address");
4134 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4135 return CA_NOT_SUPPORTED;
4138 JNIEXPORT void JNICALL
4139 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4142 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4143 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4144 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4145 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4147 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4150 JNIEXPORT void JNICALL
4151 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4154 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4155 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4156 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4157 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4159 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4162 JNIEXPORT void JNICALL
4163 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4166 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4167 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4168 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4170 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4171 if (CA_STATUS_OK != res)
4173 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4178 * Class: org_iotivity_ca_jar_caleinterface
4179 * Method: CALeGattConnectionStateChangeCallback
4180 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4182 JNIEXPORT void JNICALL
4183 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4189 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4191 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4192 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4193 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4195 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4197 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4200 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4204 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4207 OIC_LOG(ERROR, TAG, "address is null");
4210 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4212 if (state_connected == newstate)
4214 OIC_LOG(DEBUG, TAG, "LE is connected");
4215 if (GATT_SUCCESS == status)
4217 CAResult_t res = CALEClientUpdateDeviceState(address,
4218 CA_LE_CONNECTION_STATE,
4220 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4221 if (CA_STATUS_OK != res)
4223 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4227 res = CALEClientAddGattobjToList(env, gatt);
4228 if (CA_STATUS_OK != res)
4230 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4234 res = CALEClientDiscoverServices(env, gatt);
4235 if (CA_STATUS_OK != res)
4237 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4243 OIC_LOG(INFO, TAG, "unknown status");
4244 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4247 else // STATE_DISCONNECTED == newstate
4249 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4251 CAResult_t res = CALEClientUpdateDeviceState(address,
4252 CA_LE_CONNECTION_STATE,
4253 STATE_DISCONNECTED);
4254 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4255 if (CA_STATUS_OK != res)
4257 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4261 res = CALEClientGattClose(env, gatt);
4262 if (CA_STATUS_OK != res)
4264 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4267 if (CALECheckConnectionStateValue(status))
4269 // this state is unexpected reason to disconnect
4270 // if the reason is suitable, connection logic of the device will be destroyed.
4271 OIC_LOG(INFO, TAG, "connection logic destroy");
4276 // other reason except for gatt_success is expected to running
4277 // background connection in BT platform.
4278 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4279 CALEClientUpdateSendCnt(env);
4285 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4286 g_sendBuffer = NULL;
4293 CALEClientSendFinish(env, gatt);
4298 * Class: org_iotivity_ca_jar_caleinterface
4299 * Method: CALeGattServicesDiscoveredCallback
4300 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4302 JNIEXPORT void JNICALL
4303 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4308 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4309 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4310 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4311 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4313 if (GATT_SUCCESS != status) // discovery error
4315 CALEClientSendFinish(env, gatt);
4319 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4322 CALEClientSendFinish(env, gatt);
4326 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4329 CALEClientSendFinish(env, gatt);
4333 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4336 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4340 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4341 if (!jni_obj_GattCharacteristic)
4343 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4347 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4348 jni_obj_GattCharacteristic);
4349 if (CA_STATUS_OK != res)
4351 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4355 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4356 if (CA_STATUS_OK != res)
4358 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4360 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
4361 if (CA_STATUS_OK != res)
4363 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4367 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4368 STATE_SERVICE_CONNECTED);
4369 if (CA_STATUS_OK != res)
4371 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4377 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4378 if (CA_STATUS_OK != res)
4380 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4387 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
4388 if (CA_STATUS_OK != res)
4390 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4395 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4396 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4401 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4402 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4403 CALEClientSendFinish(env, gatt);
4408 * Class: org_iotivity_ca_jar_caleinterface
4409 * Method: CALeGattCharacteristicWritjclasseCallback
4410 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4412 JNIEXPORT void JNICALL
4413 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4414 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4416 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4417 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4418 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4419 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4421 // send success & signal
4422 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4428 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4434 if (GATT_SUCCESS != status) // error case
4436 OIC_LOG(ERROR, TAG, "send failure");
4439 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4440 if (CA_STATUS_OK != res)
4442 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4443 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4444 g_isSignalSetFlag = true;
4445 ca_cond_signal(g_threadWriteCharacteristicCond);
4446 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4448 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4450 if (CA_STATUS_OK != res)
4452 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4455 if (g_clientErrorCallback)
4457 jint length = (*env)->GetArrayLength(env, data);
4458 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4461 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4467 OIC_LOG(DEBUG, TAG, "send success");
4468 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4469 STATE_SEND_SUCCESS);
4470 if (CA_STATUS_OK != res)
4472 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4475 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4476 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4477 g_isSignalSetFlag = true;
4478 ca_cond_signal(g_threadWriteCharacteristicCond);
4479 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4481 CALEClientUpdateSendCnt(env);
4484 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4490 CALEClientSendFinish(env, gatt);
4495 * Class: org_iotivity_ca_jar_caleinterface
4496 * Method: CALeGattCharacteristicChangedCallback
4497 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4499 JNIEXPORT void JNICALL
4500 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4501 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4503 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4504 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4505 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4506 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4507 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4509 // get Byte Array and convert to uint8_t*
4510 jint length = (*env)->GetArrayLength(env, data);
4513 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4515 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4516 jni_byte_responseData);
4518 uint8_t* receivedData = OICMalloc(length);
4521 OIC_LOG(ERROR, TAG, "receivedData is null");
4525 memcpy(receivedData, jni_byte_responseData, length);
4526 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4528 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4531 OIC_LOG(ERROR, TAG, "jni_address is null");
4532 OICFree(receivedData);
4536 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4539 OIC_LOG(ERROR, TAG, "address is null");
4540 OICFree(receivedData);
4544 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4545 receivedData, length);
4547 uint32_t sentLength = 0;
4548 ca_mutex_lock(g_bleServerBDAddressMutex);
4549 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4550 ca_mutex_unlock(g_bleServerBDAddressMutex);
4552 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4556 * Class: org_iotivity_ca_jar_caleinterface
4557 * Method: CALeGattDescriptorWriteCallback
4558 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4560 JNIEXPORT void JNICALL
4561 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4565 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4566 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4567 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4568 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4570 if (GATT_SUCCESS != status) // error
4575 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4581 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4587 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4588 STATE_SERVICE_CONNECTED);
4589 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4590 if (CA_STATUS_OK != res)
4592 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4598 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4599 if (CA_STATUS_OK != res)
4601 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4610 CALEClientSendFinish(env, gatt);