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)
711 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
713 return CA_NOT_SUPPORTED;
716 CAResult_t CALEClientStartMulticastServer()
718 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
720 return CA_NOT_SUPPORTED;
723 void CALEClientStopUnicastServer()
725 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
728 void CALEClientStopMulticastServer()
730 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
733 void CALEClientSetCallback(CAPacketReceiveCallback callback)
735 g_packetReceiveCallback = callback;
738 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
740 g_clientErrorCallback = callback;
743 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
745 VERIFY_NON_NULL(env, TAG, "env");
749 return CA_STATUS_FAILED;
752 if (0 == u_arraylist_length(g_deviceList) // multicast
753 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
755 // Wait for LE peripherals to be discovered.
757 // Number of times to wait for discovery to complete.
758 static size_t const RETRIES = 5;
760 static uint64_t const TIMEOUT =
761 2 * MICROSECS_PER_SEC; // Microseconds
763 // set scan interval and start scan
764 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1);
766 bool devicesDiscovered = false;
767 for (size_t i = 0; i < RETRIES; ++i)
769 OIC_LOG(DEBUG, TAG, "waiting for target device");
770 if (ca_cond_wait_for(g_deviceDescCond,
772 TIMEOUT) == CA_WAIT_SUCCESS)
774 ca_mutex_lock(g_deviceListMutex);
775 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
776 ca_mutex_unlock(g_deviceListMutex);
778 if (0 < scannedDeviceLen)
780 if (!address // multicast
781 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
783 devicesDiscovered = true;
790 OIC_LOG(INFO, TAG, "waiting..");
792 ca_mutex_lock(g_deviceScanRetryDelayMutex);
793 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
794 g_deviceScanRetryDelayMutex,
795 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
797 OIC_LOG(INFO, TAG, "finish to waiting for target device");
798 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
801 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
804 // checking whether a target device is found while waiting for time-out.
805 if (CALEClientIsDeviceInScanDeviceList(env, address))
807 devicesDiscovered = true;
816 // reset scan interval time after checking scanned devices
817 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0);
819 // time out for scanning devices
820 if (!devicesDiscovered)
822 return CA_STATUS_FAILED;
830 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
831 const uint32_t dataLen)
833 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
835 VERIFY_NON_NULL(address, TAG, "address is null");
836 VERIFY_NON_NULL(data, TAG, "data is null");
840 OIC_LOG(ERROR, TAG, "g_jvm is null");
841 return CA_STATUS_FAILED;
844 bool isAttached = false;
846 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
849 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
850 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
853 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
854 return CA_STATUS_FAILED;
859 ca_mutex_lock(g_threadSendMutex);
861 CALEClientSetSendFinishFlag(false);
863 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
864 if (CA_STATUS_OK != ret)
866 OIC_LOG(INFO, TAG, "there is no scanned device");
870 if (g_context && g_deviceList)
872 uint32_t length = u_arraylist_length(g_deviceList);
873 for (uint32_t index = 0; index < length; index++)
875 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
878 OIC_LOG(ERROR, TAG, "jarrayObj is null");
882 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
885 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
889 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
892 OIC_LOG(ERROR, TAG, "setAddress is null");
896 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
898 if (!strcmp(setAddress, address))
900 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
901 (*env)->DeleteLocalRef(env, jni_setAddress);
903 // stop scan while sending
904 CALEClientStopScanWithInterval();
908 (*env)->DeleteGlobalRef(env, g_sendBuffer);
911 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
912 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
913 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
915 // Target device to send message is just one.
918 ret = CALEClientSendData(env, jarrayObj);
919 if (CA_STATUS_OK != ret)
921 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
925 OIC_LOG(INFO, TAG, "wake up");
928 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
929 (*env)->DeleteLocalRef(env, jni_setAddress);
933 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
935 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
936 // if there is no connection state.
937 ca_mutex_lock(g_threadMutex);
938 if (!g_isFinishedSendData)
940 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
941 ca_cond_wait(g_threadCond, g_threadMutex);
942 OIC_LOG(DEBUG, TAG, "the data was sent");
944 ca_mutex_unlock(g_threadMutex);
948 (*g_jvm)->DetachCurrentThread(g_jvm);
951 // start LE Scan again
952 ret = CALEClientStartScanWithInterval();
953 if (CA_STATUS_OK != ret)
955 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
956 ca_mutex_unlock(g_threadSendMutex);
960 ca_mutex_unlock(g_threadSendMutex);
961 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
962 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
969 ret = CA_SEND_FAILED;
973 CAResult_t resetRet = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
975 if (CA_STATUS_OK != resetRet)
977 OIC_LOG_V(ERROR, TAG, "CALEClientUpdateDeviceState has failed (%d)", resetRet);
978 ret = CA_SEND_FAILED;
986 // start LE Scan again
987 ret = CALEClientStartScanWithInterval();
988 if (CA_STATUS_OK != ret)
990 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
991 ca_mutex_unlock(g_threadSendMutex);
994 (*g_jvm)->DetachCurrentThread(g_jvm);
1001 (*g_jvm)->DetachCurrentThread(g_jvm);
1004 ca_mutex_unlock(g_threadSendMutex);
1005 return CA_SEND_FAILED;
1008 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1009 const uint32_t dataLen)
1011 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1012 VERIFY_NON_NULL(data, TAG, "data is null");
1013 VERIFY_NON_NULL(env, TAG, "env is null");
1017 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1018 return CA_STATUS_FAILED;
1021 ca_mutex_lock(g_threadSendMutex);
1023 CALEClientSetSendFinishFlag(false);
1025 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1028 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1029 g_sendBuffer = NULL;
1032 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1033 if (CA_STATUS_OK != res)
1035 OIC_LOG(INFO, TAG, "there is no scanned device");
1039 // stop scan while sending
1040 CALEClientStopScanWithInterval();
1042 uint32_t length = u_arraylist_length(g_deviceList);
1043 g_targetCnt = length;
1045 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1046 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1047 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1049 for (uint32_t index = 0; index < length; index++)
1051 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1054 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1058 res = CALEClientSendData(env, jarrayObj);
1059 if (res != CA_STATUS_OK)
1061 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1065 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1067 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1068 ca_mutex_lock(g_threadMutex);
1069 if (!g_isFinishedSendData)
1071 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1072 ca_cond_wait(g_threadCond, g_threadMutex);
1073 OIC_LOG(DEBUG, TAG, "the data was sent");
1075 ca_mutex_unlock(g_threadMutex);
1077 // start LE Scan again
1078 res = CALEClientStartScanWithInterval();
1079 if (CA_STATUS_OK != res)
1081 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
1082 ca_mutex_unlock(g_threadSendMutex);
1086 ca_mutex_unlock(g_threadSendMutex);
1087 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1088 return CA_STATUS_OK;
1091 res = CALEClientStartScanWithInterval();
1092 if (CA_STATUS_OK != res)
1094 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
1095 ca_mutex_unlock(g_threadSendMutex);
1099 ca_mutex_unlock(g_threadSendMutex);
1100 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1101 return CA_SEND_FAILED;
1104 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1106 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1107 VERIFY_NON_NULL(device, TAG, "device is null");
1108 VERIFY_NON_NULL(env, TAG, "env is null");
1110 // get BLE address from bluetooth device object.
1111 char* address = NULL;
1112 CALEState_t* state = NULL;
1113 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1116 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1117 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1120 OIC_LOG(ERROR, TAG, "address is not available");
1121 return CA_STATUS_FAILED;
1123 ca_mutex_lock(g_deviceStateListMutex);
1124 state = CALEClientGetStateInfo(address);
1125 ca_mutex_unlock(g_deviceStateListMutex);
1130 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1132 // cancel previous connection request before connection
1133 // if there is gatt object in g_gattObjectList.
1136 jobject gatt = CALEClientGetGattObjInList(env, address);
1139 CAResult_t res = CALEClientDisconnect(env, gatt);
1140 if (CA_STATUS_OK != res)
1142 OIC_LOG(INFO, TAG, "there is no gatt object");
1145 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1148 // connection request
1149 jobject newGatt = CALEClientConnect(env, device,
1151 if (NULL == newGatt)
1153 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1154 return CA_STATUS_FAILED;
1159 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1160 STATE_SERVICE_CONNECTED))
1162 OIC_LOG(INFO, TAG, "GATT has already connected");
1164 jobject gatt = CALEClientGetGattObjInList(env, address);
1167 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1168 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1169 return CA_STATUS_FAILED;
1172 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1173 if (CA_STATUS_OK != ret)
1175 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1176 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1179 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1181 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1184 OIC_LOG(INFO, TAG, "service connecting...");
1186 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1187 STATE_DISCONNECTED))
1189 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1191 // cancel previous connection request before connection
1192 // if there is gatt object in g_gattObjectList.
1195 jobject gatt = CALEClientGetGattObjInList(env, address);
1198 CAResult_t res = CALEClientDisconnect(env, gatt);
1199 if (CA_STATUS_OK != res)
1201 OIC_LOG(INFO, TAG, "there is no gatt object");
1204 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1207 OIC_LOG(DEBUG, TAG, "start to connect LE");
1208 jobject gatt = CALEClientConnect(env, device,
1209 CALEClientGetFlagFromState(env, jni_address,
1210 CA_LE_AUTO_CONNECT_FLAG));
1214 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1215 return CA_STATUS_FAILED;
1220 return CA_STATUS_OK;
1223 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1225 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1226 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1228 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1229 "()Landroid/bluetooth/BluetoothDevice;");
1230 if (!jni_mid_getDevice)
1232 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1236 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1237 if (!jni_obj_device)
1239 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1243 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1246 OIC_LOG(ERROR, TAG, "jni_address is null");
1256 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1259 OIC_LOG(DEBUG, TAG, "Gatt Close");
1260 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1261 VERIFY_NON_NULL(env, TAG, "env is null");
1263 // get BluetoothGatt method
1264 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1265 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1266 if (!jni_mid_closeGatt)
1268 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1269 return CA_STATUS_OK;
1272 // call disconnect gatt method
1273 OIC_LOG(DEBUG, TAG, "request to close GATT");
1274 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1276 if ((*env)->ExceptionCheck(env))
1278 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1279 (*env)->ExceptionDescribe(env);
1280 (*env)->ExceptionClear(env);
1281 return CA_STATUS_FAILED;
1284 return CA_STATUS_OK;
1287 CAResult_t CALEClientStartScan()
1289 if (!g_isStartedLEClient)
1291 OIC_LOG(ERROR, TAG, "LE client is not started");
1292 return CA_STATUS_FAILED;
1297 OIC_LOG(ERROR, TAG, "g_jvm is null");
1298 return CA_STATUS_FAILED;
1301 bool isAttached = false;
1303 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1306 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1308 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1311 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1312 return CA_STATUS_FAILED;
1317 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1319 CAResult_t ret = CA_STATUS_OK;
1320 // scan gatt server with UUID
1321 if (g_leScanCallback && g_uuidList)
1324 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1326 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1328 if (CA_STATUS_OK != ret)
1330 if (CA_ADAPTER_NOT_ENABLED == ret)
1332 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1336 OIC_LOG(ERROR, TAG, "start scan has failed");
1343 (*g_jvm)->DetachCurrentThread(g_jvm);
1349 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1351 VERIFY_NON_NULL(callback, TAG, "callback is null");
1352 VERIFY_NON_NULL(env, TAG, "env is null");
1354 if (!CALEIsEnableBTAdapter(env))
1356 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1357 return CA_ADAPTER_NOT_ENABLED;
1360 // get default bt adapter class
1361 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1362 if (!jni_cid_BTAdapter)
1364 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1365 return CA_STATUS_FAILED;
1368 // get remote bt adapter method
1369 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1370 "getDefaultAdapter",
1371 METHODID_OBJECTNONPARAM);
1372 if (!jni_mid_getDefaultAdapter)
1374 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1375 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1376 return CA_STATUS_FAILED;
1379 // get start le scan method
1380 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1381 "(Landroid/bluetooth/BluetoothAdapter$"
1382 "LeScanCallback;)Z");
1383 if (!jni_mid_startLeScan)
1385 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1386 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1387 return CA_STATUS_FAILED;
1390 // gat bt adapter object
1391 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1392 jni_mid_getDefaultAdapter);
1393 if (!jni_obj_BTAdapter)
1395 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1396 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1397 return CA_STATUS_FAILED;
1400 // call start le scan method
1401 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1402 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1403 jni_mid_startLeScan, callback);
1404 if (!jni_obj_startLeScan)
1406 OIC_LOG(INFO, TAG, "startLeScan has failed");
1410 OIC_LOG(DEBUG, TAG, "LeScan has started");
1413 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1414 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1415 return CA_STATUS_OK;
1418 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1420 VERIFY_NON_NULL(callback, TAG, "callback is null");
1421 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1422 VERIFY_NON_NULL(env, TAG, "env is null");
1424 if (!CALEIsEnableBTAdapter(env))
1426 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1427 return CA_ADAPTER_NOT_ENABLED;
1430 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1431 if (!jni_cid_BTAdapter)
1433 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1434 return CA_STATUS_FAILED;
1437 // get remote bt adapter method
1438 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1439 "getDefaultAdapter",
1440 METHODID_OBJECTNONPARAM);
1441 if (!jni_mid_getDefaultAdapter)
1443 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1444 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1445 return CA_STATUS_FAILED;
1448 // get start le scan method
1449 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1450 "([Ljava/util/UUID;Landroid/bluetooth/"
1451 "BluetoothAdapter$LeScanCallback;)Z");
1452 if (!jni_mid_startLeScan)
1454 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1455 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1456 return CA_STATUS_FAILED;
1459 // get bt adapter object
1460 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1461 jni_mid_getDefaultAdapter);
1462 if (!jni_obj_BTAdapter)
1464 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1465 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1466 return CA_STATUS_FAILED;
1469 // call start le scan method
1470 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1471 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1472 jni_mid_startLeScan, uuids, callback);
1473 if (!jni_obj_startLeScan)
1475 OIC_LOG(INFO, TAG, "startLeScan has failed");
1479 OIC_LOG(DEBUG, TAG, "LeScan has started");
1482 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1483 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1484 return CA_STATUS_OK;
1487 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1489 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1490 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1493 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1496 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1500 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1501 "(Ljava/lang/String;)"
1502 "Ljava/util/UUID;");
1503 if (!jni_mid_fromString)
1505 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1509 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1510 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1514 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1518 return jni_obj_uuid;
1521 CAResult_t CALEClientStopScan()
1525 OIC_LOG(ERROR, TAG, "g_jvm is null");
1526 return CA_STATUS_FAILED;
1529 bool isAttached = false;
1531 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1534 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1535 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1538 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1539 return CA_STATUS_FAILED;
1544 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1545 if (CA_STATUS_OK != ret)
1547 if (CA_ADAPTER_NOT_ENABLED == ret)
1549 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1553 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1559 (*g_jvm)->DetachCurrentThread(g_jvm);
1565 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1567 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1568 VERIFY_NON_NULL(callback, TAG, "callback is null");
1569 VERIFY_NON_NULL(env, TAG, "env is null");
1571 if (!CALEIsEnableBTAdapter(env))
1573 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1574 return CA_ADAPTER_NOT_ENABLED;
1577 // get default bt adapter class
1578 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1579 if (!jni_cid_BTAdapter)
1581 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1582 return CA_STATUS_FAILED;
1585 // get remote bt adapter method
1586 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1587 "getDefaultAdapter",
1588 METHODID_OBJECTNONPARAM);
1589 if (!jni_mid_getDefaultAdapter)
1591 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1592 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1593 return CA_STATUS_FAILED;
1596 // get start le scan method
1597 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1598 "(Landroid/bluetooth/"
1599 "BluetoothAdapter$LeScanCallback;)V");
1600 if (!jni_mid_stopLeScan)
1602 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1603 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1604 return CA_STATUS_FAILED;
1607 // gat bt adapter object
1608 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1609 jni_mid_getDefaultAdapter);
1610 if (!jni_obj_BTAdapter)
1612 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1613 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1614 return CA_STATUS_FAILED;
1617 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1618 // call start le scan method
1619 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1620 if ((*env)->ExceptionCheck(env))
1622 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1623 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1624 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1625 (*env)->ExceptionDescribe(env);
1626 (*env)->ExceptionClear(env);
1627 return CA_STATUS_FAILED;
1630 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1631 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1632 return CA_STATUS_OK;
1635 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1637 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1638 VERIFY_NON_NULL(env, TAG, "env");
1639 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1641 ca_mutex_lock(g_deviceStateListMutex);
1643 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1646 OIC_LOG(ERROR, TAG, "address is not available");
1647 return CA_STATUS_FAILED;
1650 if (CALEClientIsDeviceInList(address))
1652 CALEState_t* curState = CALEClientGetStateInfo(address);
1655 OIC_LOG(ERROR, TAG, "curState is null");
1656 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1657 ca_mutex_unlock(g_deviceStateListMutex);
1658 return CA_STATUS_FAILED;
1660 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1664 case CA_LE_AUTO_CONNECT_FLAG:
1665 curState->autoConnectFlag = flag;
1667 case CA_LE_DESCRIPTOR_FOUND:
1668 curState->isDescriptorFound = flag;
1675 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1676 ca_mutex_unlock(g_deviceStateListMutex);
1677 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1678 return CA_STATUS_OK;
1681 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1683 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1684 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1685 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1687 ca_mutex_lock(g_deviceStateListMutex);
1689 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1692 OIC_LOG(ERROR, TAG, "address is not available");
1693 ca_mutex_unlock(g_deviceStateListMutex);
1697 CALEState_t* curState = CALEClientGetStateInfo(address);
1698 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1701 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1702 ca_mutex_unlock(g_deviceStateListMutex);
1706 jboolean ret = JNI_FALSE;
1709 case CA_LE_AUTO_CONNECT_FLAG:
1710 ret = curState->autoConnectFlag;
1712 case CA_LE_DESCRIPTOR_FOUND:
1713 ret = curState->isDescriptorFound;
1718 ca_mutex_unlock(g_deviceStateListMutex);
1720 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1721 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1725 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1727 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1728 VERIFY_NON_NULL(env, TAG, "env is null");
1729 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1731 ca_mutex_lock(g_threadSendMutex);
1733 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1736 OIC_LOG(ERROR, TAG, "jni_address is not available");
1737 ca_mutex_unlock(g_threadSendMutex);
1738 return CA_STATUS_FAILED;
1741 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1744 OIC_LOG(ERROR, TAG, "address is not available");
1745 ca_mutex_unlock(g_threadSendMutex);
1746 return CA_STATUS_FAILED;
1749 CAResult_t res = CA_STATUS_OK;
1750 if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1751 STATE_DISCONNECTED))
1753 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1754 if (NULL == newGatt)
1756 OIC_LOG(INFO, TAG, "newGatt is not available");
1757 res = CA_STATUS_FAILED;
1760 ca_mutex_unlock(g_threadSendMutex);
1765 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1767 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1768 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1769 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1771 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1772 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1775 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1778 OIC_LOG(ERROR, TAG, "address is not available");
1782 // close the gatt service
1783 jobject gatt = CALEClientGetGattObjInList(env, address);
1786 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1787 if (CA_STATUS_OK != res)
1789 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1790 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1794 // clean previous gatt object after close profile service
1795 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1796 if (CA_STATUS_OK != res)
1798 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1799 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1803 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1806 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1809 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1813 // add new gatt object into g_gattObjectList
1814 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1815 if (CA_STATUS_OK != res)
1817 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1824 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1826 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1827 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1828 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1830 if (!g_leGattCallback)
1832 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1836 if (!CALEIsEnableBTAdapter(env))
1838 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1842 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1845 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1849 // get BluetoothDevice method
1850 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1851 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1853 "(Landroid/content/Context;ZLandroid/"
1854 "bluetooth/BluetoothGattCallback;)"
1855 "Landroid/bluetooth/BluetoothGatt;");
1856 if (!jni_mid_connectGatt)
1858 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1862 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1863 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1864 jni_mid_connectGatt,
1866 autoconnect, g_leGattCallback);
1867 if (!jni_obj_connectGatt)
1869 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1870 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1871 CALEClientUpdateSendCnt(env);
1876 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1878 return jni_obj_connectGatt;
1881 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1883 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1885 VERIFY_NON_NULL(env, TAG, "env is null");
1886 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1888 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1889 if (!jni_cid_BTAdapter)
1891 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1892 return CA_STATUS_FAILED;
1895 // get remote bt adapter method
1896 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1897 "getDefaultAdapter",
1898 METHODID_OBJECTNONPARAM);
1899 if (!jni_mid_getDefaultAdapter)
1901 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1902 return CA_STATUS_FAILED;
1905 // gat bt adapter object
1906 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1907 jni_mid_getDefaultAdapter);
1908 if (!jni_obj_BTAdapter)
1910 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1911 return CA_STATUS_FAILED;
1914 // get closeProfileProxy method
1915 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1916 "closeProfileProxy",
1917 "(ILandroid/bluetooth/"
1918 "BluetoothProfile;)V");
1919 if (!jni_mid_closeProfileProxy)
1921 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1922 return CA_STATUS_FAILED;
1925 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1926 if (!jni_cid_BTProfile)
1928 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1929 return CA_STATUS_FAILED;
1932 // GATT - Constant value : 7 (0x00000007)
1933 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1937 OIC_LOG(ERROR, TAG, "id_gatt is null");
1938 return CA_STATUS_FAILED;
1941 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1943 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1944 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1945 if ((*env)->ExceptionCheck(env))
1947 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1948 (*env)->ExceptionDescribe(env);
1949 (*env)->ExceptionClear(env);
1950 return CA_STATUS_FAILED;
1953 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1954 return CA_STATUS_OK;
1958 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1960 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1961 VERIFY_NON_NULL(env, TAG, "env is null");
1962 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1964 // get BluetoothGatt method
1965 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1966 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1967 "disconnect", "()V");
1968 if (!jni_mid_disconnectGatt)
1970 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1971 return CA_STATUS_FAILED;
1974 // call disconnect gatt method
1975 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1976 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1977 if ((*env)->ExceptionCheck(env))
1979 OIC_LOG(ERROR, TAG, "disconnect has failed");
1980 (*env)->ExceptionDescribe(env);
1981 (*env)->ExceptionClear(env);
1982 return CA_STATUS_FAILED;
1985 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1987 return CA_STATUS_OK;
1990 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1992 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1993 VERIFY_NON_NULL(env, TAG, "env is null");
1995 if (!g_gattObjectList)
1997 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1998 return CA_STATUS_OK;
2001 uint32_t length = u_arraylist_length(g_gattObjectList);
2002 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2003 for (uint32_t index = 0; index < length; index++)
2005 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2006 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2009 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2012 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2013 if (CA_STATUS_OK != res)
2015 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2020 return CA_STATUS_OK;
2023 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2025 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2026 VERIFY_NON_NULL(env, TAG, "env is null");
2028 if (!g_gattObjectList)
2030 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2031 return CA_STATUS_OK;
2034 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2037 OIC_LOG(ERROR, TAG, "address is null");
2038 return CA_STATUS_FAILED;
2041 uint32_t length = u_arraylist_length(g_gattObjectList);
2042 for (uint32_t index = 0; index < length; index++)
2044 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2047 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2051 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2052 if (!jni_setAddress)
2054 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2055 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2056 return CA_STATUS_FAILED;
2059 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2062 OIC_LOG(ERROR, TAG, "setAddress is null");
2063 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2064 return CA_STATUS_FAILED;
2067 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2068 if (!strcmp(address, setAddress))
2070 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2071 if (CA_STATUS_OK != res)
2073 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2074 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2075 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2076 return CA_STATUS_FAILED;
2078 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2079 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2080 return CA_STATUS_OK;
2082 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2084 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2086 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2087 return CA_STATUS_OK;
2090 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2092 VERIFY_NON_NULL(env, TAG, "env is null");
2093 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2095 if (!CALEIsEnableBTAdapter(env))
2097 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2098 return CA_ADAPTER_NOT_ENABLED;
2101 // get BluetoothGatt.discoverServices method
2102 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2103 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2104 "discoverServices", "()Z");
2105 if (!jni_mid_discoverServices)
2107 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2108 return CA_STATUS_FAILED;
2111 // call disconnect gatt method
2112 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2113 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2116 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2117 return CA_STATUS_FAILED;
2120 return CA_STATUS_OK;
2123 static void CALEWriteCharacteristicThread(void* object)
2125 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2127 bool isAttached = false;
2129 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2132 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2133 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2137 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2143 jobject gatt = (jobject)object;
2144 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2145 if (CA_STATUS_OK != ret)
2147 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2152 (*g_jvm)->DetachCurrentThread(g_jvm);
2156 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2158 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2160 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2161 VERIFY_NON_NULL(env, TAG, "env is null");
2163 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2166 CALEClientSendFinish(env, gatt);
2167 return CA_STATUS_FAILED;
2170 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2173 CALEClientSendFinish(env, gatt);
2174 return CA_STATUS_FAILED;
2177 ca_mutex_lock(g_threadSendStateMutex);
2179 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2181 OIC_LOG(INFO, TAG, "current state is SENDING");
2182 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2183 ca_mutex_unlock(g_threadSendStateMutex);
2184 return CA_STATUS_OK;
2187 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2190 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2191 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2192 CALEClientSendFinish(env, gatt);
2193 ca_mutex_unlock(g_threadSendStateMutex);
2194 return CA_STATUS_FAILED;
2197 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2199 ca_mutex_unlock(g_threadSendStateMutex);
2202 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2203 if (!jni_obj_character)
2205 CALEClientSendFinish(env, gatt);
2206 return CA_STATUS_FAILED;
2209 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2210 if (CA_STATUS_OK != ret)
2212 CALEClientSendFinish(env, gatt);
2213 return CA_STATUS_FAILED;
2216 // wait for callback for write Characteristic with success to sent data
2217 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2218 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2219 if (!g_isSignalSetFlag)
2221 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2222 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2223 g_threadWriteCharacteristicMutex,
2224 WAIT_TIME_WRITE_CHARACTERISTIC))
2226 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2227 g_isSignalSetFlag = false;
2228 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2229 return CA_STATUS_FAILED;
2232 // reset flag set by writeCharacteristic Callback
2233 g_isSignalSetFlag = false;
2234 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2236 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2237 return CA_STATUS_OK;
2240 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2242 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2243 VERIFY_NON_NULL(env, TAG, "env is null");
2244 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2246 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2247 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2248 CALEWriteCharacteristicThread, (void*)gattParam))
2250 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2251 return CA_STATUS_FAILED;
2254 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2255 return CA_STATUS_OK;
2258 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2259 jobject gattCharacteristic)
2261 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2262 VERIFY_NON_NULL(env, TAG, "env is null");
2263 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2264 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2266 if (!CALEIsEnableBTAdapter(env))
2268 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2269 return CA_STATUS_FAILED;
2272 // get BluetoothGatt.write characteristic method
2273 OIC_LOG(DEBUG, TAG, "write characteristic method");
2274 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2275 "writeCharacteristic",
2276 "(Landroid/bluetooth/"
2277 "BluetoothGattCharacteristic;)Z");
2278 if (!jni_mid_writeCharacteristic)
2280 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2281 return CA_STATUS_FAILED;
2284 // call disconnect gatt method
2285 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2286 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2287 jni_mid_writeCharacteristic,
2288 gattCharacteristic);
2291 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2295 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2296 return CA_STATUS_FAILED;
2299 return CA_STATUS_OK;
2302 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2304 VERIFY_NON_NULL(env, TAG, "env is null");
2305 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2307 if (!CALEIsEnableBTAdapter(env))
2309 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2310 return CA_STATUS_FAILED;
2313 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2316 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2317 return CA_STATUS_FAILED;
2320 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2321 if (!jni_obj_GattCharacteristic)
2323 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2324 return CA_STATUS_FAILED;
2327 OIC_LOG(DEBUG, TAG, "read characteristic method");
2328 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2329 "readCharacteristic",
2330 "(Landroid/bluetooth/"
2331 "BluetoothGattCharacteristic;)Z");
2332 if (!jni_mid_readCharacteristic)
2334 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2335 return CA_STATUS_FAILED;
2338 // call disconnect gatt method
2339 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2340 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2341 jni_obj_GattCharacteristic);
2344 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2348 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2349 return CA_STATUS_FAILED;
2352 return CA_STATUS_OK;
2355 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2356 jobject characteristic)
2358 VERIFY_NON_NULL(env, TAG, "env is null");
2359 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2360 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2362 if (!CALEIsEnableBTAdapter(env))
2364 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2365 return CA_ADAPTER_NOT_ENABLED;
2368 // get BluetoothGatt.setCharacteristicNotification method
2369 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2370 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2371 "setCharacteristicNotification",
2372 "(Landroid/bluetooth/"
2373 "BluetoothGattCharacteristic;Z)Z");
2374 if (!jni_mid_setNotification)
2376 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2377 return CA_STATUS_FAILED;
2380 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2381 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2382 characteristic, JNI_TRUE);
2383 if (JNI_TRUE == ret)
2385 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2389 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2390 return CA_STATUS_FAILED;
2393 return CA_STATUS_OK;
2396 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2398 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2399 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2400 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2402 if (!CALEIsEnableBTAdapter(env))
2404 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2408 // get BluetoothGatt.getService method
2409 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2410 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2412 "(Ljava/util/UUID;)Landroid/bluetooth/"
2413 "BluetoothGattService;");
2414 if (!jni_mid_getService)
2416 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2420 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2421 if (!jni_obj_service_uuid)
2423 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2427 // get bluetooth gatt service
2428 OIC_LOG(DEBUG, TAG, "request to get service");
2429 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2430 jni_obj_service_uuid);
2431 if (!jni_obj_gattService)
2433 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2437 // get bluetooth gatt service method
2438 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2439 "BluetoothGattService",
2440 "getCharacteristic",
2441 "(Ljava/util/UUID;)"
2442 "Landroid/bluetooth/"
2443 "BluetoothGattCharacteristic;");
2444 if (!jni_mid_getCharacteristic)
2446 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2450 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2453 OIC_LOG(ERROR, TAG, "uuid is null");
2457 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2458 if (!jni_obj_tx_uuid)
2460 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2461 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2465 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2466 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2467 jni_mid_getCharacteristic,
2470 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2471 return jni_obj_GattCharacteristic;
2474 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2476 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2477 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2478 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2479 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2481 if (!CALEIsEnableBTAdapter(env))
2483 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2487 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2490 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2494 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2495 if (!jni_obj_GattCharacteristic)
2497 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2501 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2502 "/BluetoothGattCharacteristic");
2503 if (!jni_cid_BTGattCharacteristic)
2505 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2509 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2510 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2512 if (!jni_mid_setValue)
2514 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2518 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2520 if (JNI_TRUE == ret)
2522 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2526 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2531 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2532 "setWriteType", "(I)V");
2533 if (!jni_mid_setWriteType)
2535 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2539 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2540 "WRITE_TYPE_NO_RESPONSE", "I");
2541 if (!jni_fid_no_response)
2543 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2547 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2548 jni_fid_no_response);
2550 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2552 return jni_obj_GattCharacteristic;
2555 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2557 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2558 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2560 if (!CALEIsEnableBTAdapter(env))
2562 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2566 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2567 "BluetoothGattCharacteristic",
2568 "getValue", "()[B");
2569 if (!jni_mid_getValue)
2571 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2575 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2577 return jni_obj_data_array;
2580 CAResult_t CALEClientCreateUUIDList()
2584 OIC_LOG(ERROR, TAG, "g_jvm is null");
2585 return CA_STATUS_FAILED;
2588 bool isAttached = false;
2590 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2593 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2594 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2598 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2599 return CA_STATUS_FAILED;
2604 // create new object array
2605 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2606 if (!jni_cid_uuid_list)
2608 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2612 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2613 jni_cid_uuid_list, NULL);
2614 if (!jni_obj_uuid_list)
2616 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2621 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2624 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2627 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2629 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2633 (*g_jvm)->DetachCurrentThread(g_jvm);
2636 return CA_STATUS_OK;
2643 (*g_jvm)->DetachCurrentThread(g_jvm);
2645 return CA_STATUS_FAILED;
2648 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2649 jobject characteristic)
2651 VERIFY_NON_NULL(env, TAG, "env is null");
2652 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2653 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2655 if (!CALEIsEnableBTAdapter(env))
2657 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2658 return CA_ADAPTER_NOT_ENABLED;
2661 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2662 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2663 "BluetoothGattCharacteristic",
2665 "(Ljava/util/UUID;)Landroid/bluetooth/"
2666 "BluetoothGattDescriptor;");
2667 if (!jni_mid_getDescriptor)
2669 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2670 return CA_STATUS_FAILED;
2673 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2674 if (!jni_obj_cc_uuid)
2676 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2677 return CA_STATUS_FAILED;
2680 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2681 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2682 jni_mid_getDescriptor, jni_obj_cc_uuid);
2683 if (!jni_obj_descriptor)
2685 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2686 return CA_NOT_SUPPORTED;
2689 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2690 jclass jni_cid_descriptor = (*env)->FindClass(env,
2691 "android/bluetooth/BluetoothGattDescriptor");
2692 if (!jni_cid_descriptor)
2694 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2695 return CA_STATUS_FAILED;
2698 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2699 if (!jni_mid_setValue)
2701 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2702 return CA_STATUS_FAILED;
2705 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2706 "ENABLE_NOTIFICATION_VALUE", "[B");
2707 if (!jni_fid_NotiValue)
2709 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2710 return CA_STATUS_FAILED;
2713 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2715 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2716 env, jni_obj_descriptor, jni_mid_setValue,
2717 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2720 OIC_LOG(DEBUG, TAG, "setValue success");
2724 OIC_LOG(ERROR, TAG, "setValue has failed");
2725 return CA_STATUS_FAILED;
2728 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2730 "(Landroid/bluetooth/"
2731 "BluetoothGattDescriptor;)Z");
2732 if (!jni_mid_writeDescriptor)
2734 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2735 return CA_STATUS_FAILED;
2738 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2739 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2740 jni_obj_descriptor);
2743 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2747 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2748 return CA_STATUS_FAILED;
2751 return CA_STATUS_OK;
2754 void CALEClientCreateScanDeviceList(JNIEnv *env)
2756 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2757 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2759 ca_mutex_lock(g_deviceListMutex);
2760 // create new object array
2761 if (g_deviceList == NULL)
2763 OIC_LOG(DEBUG, TAG, "Create device list");
2765 g_deviceList = u_arraylist_create();
2767 ca_mutex_unlock(g_deviceListMutex);
2770 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2772 VERIFY_NON_NULL(device, TAG, "device is null");
2773 VERIFY_NON_NULL(env, TAG, "env is null");
2775 ca_mutex_lock(g_deviceListMutex);
2779 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2780 CALEClientStopScanWithInterval();
2782 ca_mutex_unlock(g_deviceListMutex);
2783 return CA_STATUS_FAILED;
2786 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2787 if (!jni_remoteAddress)
2789 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2790 ca_mutex_unlock(g_deviceListMutex);
2791 return CA_STATUS_FAILED;
2794 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2797 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2798 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2799 ca_mutex_unlock(g_deviceListMutex);
2800 return CA_STATUS_FAILED;
2803 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2805 jobject gdevice = (*env)->NewGlobalRef(env, device);
2806 u_arraylist_add(g_deviceList, gdevice);
2807 ca_cond_signal(g_deviceDescCond);
2808 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2810 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2811 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2813 ca_mutex_unlock(g_deviceListMutex);
2815 return CA_STATUS_OK;
2818 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2820 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2821 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2825 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2829 uint32_t length = u_arraylist_length(g_deviceList);
2830 for (uint32_t index = 0; index < length; index++)
2832 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2835 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2839 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2840 if (!jni_setAddress)
2842 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2846 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2849 OIC_LOG(ERROR, TAG, "setAddress is null");
2850 (*env)->DeleteLocalRef(env, jni_setAddress);
2854 if (!strcmp(remoteAddress, setAddress))
2856 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2857 (*env)->DeleteLocalRef(env, jni_setAddress);
2861 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2862 (*env)->DeleteLocalRef(env, jni_setAddress);
2865 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2870 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2872 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2873 VERIFY_NON_NULL(env, TAG, "env is null");
2875 ca_mutex_lock(g_deviceListMutex);
2879 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2880 ca_mutex_unlock(g_deviceListMutex);
2881 return CA_STATUS_FAILED;
2884 uint32_t length = u_arraylist_length(g_deviceList);
2885 for (uint32_t index = 0; index < length; index++)
2887 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2890 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2893 (*env)->DeleteGlobalRef(env, jarrayObj);
2897 OICFree(g_deviceList);
2898 g_deviceList = NULL;
2900 ca_mutex_unlock(g_deviceListMutex);
2901 return CA_STATUS_OK;
2904 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2906 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2907 VERIFY_NON_NULL(address, TAG, "address is null");
2908 VERIFY_NON_NULL(env, TAG, "env is null");
2910 ca_mutex_lock(g_deviceListMutex);
2914 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2915 ca_mutex_unlock(g_deviceListMutex);
2916 return CA_STATUS_FAILED;
2919 uint32_t length = u_arraylist_length(g_deviceList);
2920 for (uint32_t index = 0; index < length; index++)
2922 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2925 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2926 ca_mutex_unlock(g_deviceListMutex);
2927 return CA_STATUS_FAILED;
2930 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2931 if (!jni_setAddress)
2933 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2934 ca_mutex_unlock(g_deviceListMutex);
2935 return CA_STATUS_FAILED;
2938 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2941 OIC_LOG(ERROR, TAG, "setAddress is null");
2942 ca_mutex_unlock(g_deviceListMutex);
2943 return CA_STATUS_FAILED;
2946 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2949 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2950 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2951 ca_mutex_unlock(g_deviceListMutex);
2952 return CA_STATUS_FAILED;
2955 if (!strcmp(setAddress, remoteAddress))
2957 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2958 (*env)->DeleteGlobalRef(env, jarrayObj);
2960 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2961 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2963 if (NULL == u_arraylist_remove(g_deviceList, index))
2965 OIC_LOG(ERROR, TAG, "List removal failed.");
2966 ca_mutex_unlock(g_deviceListMutex);
2967 return CA_STATUS_FAILED;
2969 ca_mutex_unlock(g_deviceListMutex);
2970 return CA_STATUS_OK;
2972 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2973 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2976 ca_mutex_unlock(g_deviceListMutex);
2977 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2979 return CA_STATUS_OK;
2986 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2988 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2989 VERIFY_NON_NULL(env, TAG, "env is null");
2990 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2992 ca_mutex_lock(g_gattObjectMutex);
2994 if (!g_gattObjectList)
2996 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2997 ca_mutex_unlock(g_gattObjectMutex);
2998 return CA_STATUS_FAILED;
3001 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3002 if (!jni_remoteAddress)
3004 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3005 ca_mutex_unlock(g_gattObjectMutex);
3006 return CA_STATUS_FAILED;
3009 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3012 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3013 ca_mutex_unlock(g_gattObjectMutex);
3014 return CA_STATUS_FAILED;
3017 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3018 if (!CALEClientIsGattObjInList(env, remoteAddress))
3020 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3021 u_arraylist_add(g_gattObjectList, newGatt);
3022 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3025 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3026 ca_mutex_unlock(g_gattObjectMutex);
3027 return CA_STATUS_OK;
3030 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3032 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
3033 VERIFY_NON_NULL(env, TAG, "env is null");
3034 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3036 uint32_t length = u_arraylist_length(g_gattObjectList);
3037 for (uint32_t index = 0; index < length; index++)
3040 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3043 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3047 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3048 if (!jni_setAddress)
3050 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3054 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3057 OIC_LOG(ERROR, TAG, "setAddress is null");
3061 if (!strcmp(remoteAddress, setAddress))
3063 OIC_LOG(DEBUG, TAG, "the device is already set");
3064 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3069 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3074 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3078 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3080 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3081 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3082 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3084 ca_mutex_lock(g_gattObjectMutex);
3085 uint32_t length = u_arraylist_length(g_gattObjectList);
3086 for (uint32_t index = 0; index < length; index++)
3088 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3091 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3092 ca_mutex_unlock(g_gattObjectMutex);
3096 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3097 if (!jni_setAddress)
3099 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3100 ca_mutex_unlock(g_gattObjectMutex);
3104 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3107 OIC_LOG(ERROR, TAG, "setAddress is null");
3108 ca_mutex_unlock(g_gattObjectMutex);
3112 if (!strcmp(remoteAddress, setAddress))
3114 OIC_LOG(DEBUG, TAG, "the device is already set");
3115 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3116 ca_mutex_unlock(g_gattObjectMutex);
3119 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3122 ca_mutex_unlock(g_gattObjectMutex);
3123 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3127 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3129 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3130 VERIFY_NON_NULL(env, TAG, "env is null");
3132 ca_mutex_lock(g_gattObjectMutex);
3133 if (!g_gattObjectList)
3135 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3136 ca_mutex_unlock(g_gattObjectMutex);
3137 return CA_STATUS_OK;
3140 uint32_t length = u_arraylist_length(g_gattObjectList);
3141 for (uint32_t index = 0; index < length; index++)
3143 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3146 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3149 (*env)->DeleteGlobalRef(env, jarrayObj);
3153 OICFree(g_gattObjectList);
3154 g_gattObjectList = NULL;
3155 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3156 ca_mutex_unlock(g_gattObjectMutex);
3157 return CA_STATUS_OK;
3160 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3162 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3163 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3164 VERIFY_NON_NULL(env, TAG, "env is null");
3166 ca_mutex_lock(g_gattObjectMutex);
3167 if (!g_gattObjectList)
3169 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3170 ca_mutex_unlock(g_gattObjectMutex);
3171 return CA_STATUS_OK;
3174 uint32_t length = u_arraylist_length(g_gattObjectList);
3175 for (uint32_t index = 0; index < length; index++)
3177 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3180 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3181 ca_mutex_unlock(g_gattObjectMutex);
3182 return CA_STATUS_FAILED;
3185 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3186 if (!jni_setAddress)
3188 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3189 ca_mutex_unlock(g_gattObjectMutex);
3190 return CA_STATUS_FAILED;
3193 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3196 OIC_LOG(ERROR, TAG, "setAddress is null");
3197 ca_mutex_unlock(g_gattObjectMutex);
3198 return CA_STATUS_FAILED;
3201 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3202 if (!jni_remoteAddress)
3204 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3205 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3206 ca_mutex_unlock(g_gattObjectMutex);
3207 return CA_STATUS_FAILED;
3210 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3213 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3214 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3215 ca_mutex_unlock(g_gattObjectMutex);
3216 return CA_STATUS_FAILED;
3219 if (!strcmp(setAddress, remoteAddress))
3221 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3222 (*env)->DeleteGlobalRef(env, jarrayObj);
3224 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3225 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3227 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3229 OIC_LOG(ERROR, TAG, "List removal failed.");
3230 ca_mutex_unlock(g_gattObjectMutex);
3231 return CA_STATUS_FAILED;
3233 ca_mutex_unlock(g_gattObjectMutex);
3234 return CA_STATUS_OK;
3236 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3237 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3240 ca_mutex_unlock(g_gattObjectMutex);
3241 OIC_LOG(DEBUG, TAG, "there are no target object");
3242 return CA_STATUS_OK;
3245 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3247 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3248 VERIFY_NON_NULL(addr, TAG, "addr is null");
3249 VERIFY_NON_NULL(env, TAG, "env is null");
3251 ca_mutex_lock(g_gattObjectMutex);
3252 if (!g_gattObjectList)
3254 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3255 ca_mutex_unlock(g_gattObjectMutex);
3256 return CA_STATUS_OK;
3259 uint32_t length = u_arraylist_length(g_gattObjectList);
3260 for (uint32_t index = 0; index < length; index++)
3262 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3265 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3266 ca_mutex_unlock(g_gattObjectMutex);
3267 return CA_STATUS_FAILED;
3270 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3271 if (!jni_setAddress)
3273 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3274 ca_mutex_unlock(g_gattObjectMutex);
3275 return CA_STATUS_FAILED;
3278 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3281 OIC_LOG(ERROR, TAG, "setAddress is null");
3282 ca_mutex_unlock(g_gattObjectMutex);
3283 return CA_STATUS_FAILED;
3286 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3289 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3290 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3291 ca_mutex_unlock(g_gattObjectMutex);
3292 return CA_STATUS_FAILED;
3295 if (!strcmp(setAddress, remoteAddress))
3297 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3298 (*env)->DeleteGlobalRef(env, jarrayObj);
3300 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3301 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3302 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3304 OIC_LOG(ERROR, TAG, "List removal failed.");
3305 ca_mutex_unlock(g_gattObjectMutex);
3306 return CA_STATUS_FAILED;
3308 ca_mutex_unlock(g_gattObjectMutex);
3309 return CA_STATUS_OK;
3311 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3312 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3315 ca_mutex_unlock(g_gattObjectMutex);
3316 OIC_LOG(DEBUG, TAG, "there are no target object");
3317 return CA_STATUS_FAILED;
3320 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3322 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3324 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3325 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3327 // get Bluetooth Address
3328 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3329 if (!jni_btTargetAddress)
3331 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3335 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3338 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3342 // get method ID of getDevice()
3343 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3344 "getDevice", METHODID_BT_DEVICE);
3345 if (!jni_mid_getDevice)
3347 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3348 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3352 ca_mutex_lock(g_gattObjectMutex);
3354 size_t length = u_arraylist_length(g_gattObjectList);
3355 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3356 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3358 for (size_t index = 0; index < length; index++)
3360 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3363 ca_mutex_unlock(g_gattObjectMutex);
3364 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3365 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3369 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3370 if (!jni_obj_device)
3372 ca_mutex_unlock(g_gattObjectMutex);
3373 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3374 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3378 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3381 ca_mutex_unlock(g_gattObjectMutex);
3382 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3383 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3387 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3390 ca_mutex_unlock(g_gattObjectMutex);
3391 OIC_LOG(ERROR, TAG, "btAddress is not available");
3392 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3396 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3397 if (!strcmp(targetAddress, btAddress))
3399 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3402 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3405 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3407 ca_mutex_unlock(g_gattObjectMutex);
3408 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3409 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3410 (*env)->DeleteLocalRef(env, jni_btAddress);
3411 (*env)->DeleteLocalRef(env, jni_obj_device);
3412 return jni_LEAddress;
3414 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3415 (*env)->DeleteLocalRef(env, jni_btAddress);
3416 (*env)->DeleteLocalRef(env, jni_obj_device);
3418 ca_mutex_unlock(g_gattObjectMutex);
3420 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3421 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3429 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3430 uint16_t target_state)
3432 VERIFY_NON_NULL(address, TAG, "address is null");
3433 VERIFY_NON_NULL(address, TAG, "state_type is null");
3434 VERIFY_NON_NULL(address, TAG, "target_state is null");
3436 if (!g_deviceStateList)
3438 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3439 return CA_STATUS_FAILED;
3442 ca_mutex_lock(g_deviceStateListMutex);
3444 if (CALEClientIsDeviceInList(address))
3446 CALEState_t* curState = CALEClientGetStateInfo(address);
3449 OIC_LOG(ERROR, TAG, "curState is null");
3450 ca_mutex_unlock(g_deviceStateListMutex);
3451 return CA_STATUS_FAILED;
3456 case CA_LE_CONNECTION_STATE:
3457 curState->connectedState = target_state;
3459 case CA_LE_SEND_STATE:
3460 curState->sendState = target_state;
3465 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3466 curState->address, curState->connectedState, curState->sendState,
3467 curState->autoConnectFlag);
3469 else /** state is added newly **/
3471 if (strlen(address) > CA_MACADDR_SIZE)
3473 OIC_LOG(ERROR, TAG, "address is not proper");
3474 ca_mutex_unlock(g_deviceStateListMutex);
3475 return CA_STATUS_INVALID_PARAM;
3478 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3481 OIC_LOG(ERROR, TAG, "out of memory");
3482 ca_mutex_unlock(g_deviceStateListMutex);
3483 return CA_MEMORY_ALLOC_FAILED;
3486 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3490 case CA_LE_CONNECTION_STATE:
3491 newstate->connectedState = target_state;
3492 newstate->sendState = STATE_SEND_NONE;
3494 case CA_LE_SEND_STATE:
3495 newstate->connectedState = STATE_DISCONNECTED;
3496 newstate->sendState = target_state;
3501 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3502 "conn : %d, send : %d, ACFlag : %d",
3503 newstate->address, newstate->connectedState, newstate->sendState,
3504 newstate->autoConnectFlag);
3505 u_arraylist_add(g_deviceStateList, newstate); // update new state
3507 ca_mutex_unlock(g_deviceStateListMutex);
3509 return CA_STATUS_OK;
3512 bool CALEClientIsDeviceInList(const char* remoteAddress)
3514 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3516 if (!g_deviceStateList)
3518 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3522 uint32_t length = u_arraylist_length(g_deviceStateList);
3523 for (uint32_t index = 0; index < length; index++)
3525 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3528 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3532 if (!strcmp(remoteAddress, state->address))
3534 OIC_LOG(DEBUG, TAG, "the device is already set");
3543 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3547 CAResult_t CALEClientRemoveAllDeviceState()
3549 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3551 ca_mutex_lock(g_deviceStateListMutex);
3552 if (!g_deviceStateList)
3554 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3555 ca_mutex_unlock(g_deviceStateListMutex);
3556 return CA_STATUS_FAILED;
3559 uint32_t length = u_arraylist_length(g_deviceStateList);
3560 for (uint32_t index = 0; index < length; index++)
3562 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3565 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3571 OICFree(g_deviceStateList);
3572 g_deviceStateList = NULL;
3573 ca_mutex_unlock(g_deviceStateListMutex);
3575 return CA_STATUS_OK;
3578 CAResult_t CALEClientResetDeviceStateForAll()
3580 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3582 ca_mutex_lock(g_deviceStateListMutex);
3583 if (!g_deviceStateList)
3585 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3586 ca_mutex_unlock(g_deviceStateListMutex);
3587 return CA_STATUS_FAILED;
3590 size_t length = u_arraylist_length(g_deviceStateList);
3591 for (size_t index = 0; index < length; index++)
3593 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3596 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3600 // autoConnectFlag value will be not changed,
3601 // since it has reset only termination case.
3602 state->connectedState = STATE_DISCONNECTED;
3603 state->sendState = STATE_SEND_NONE;
3605 ca_mutex_unlock(g_deviceStateListMutex);
3607 return CA_STATUS_OK;
3610 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3612 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3613 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3615 if (!g_deviceStateList)
3617 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3618 return CA_STATUS_FAILED;
3621 uint32_t length = u_arraylist_length(g_deviceStateList);
3622 for (uint32_t index = 0; index < length; index++)
3624 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3627 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3631 if (!strcmp(state->address, remoteAddress))
3633 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3635 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3637 if (NULL == targetState)
3639 OIC_LOG(ERROR, TAG, "List removal failed.");
3640 return CA_STATUS_FAILED;
3643 OICFree(targetState);
3644 return CA_STATUS_OK;
3648 return CA_STATUS_OK;
3651 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3653 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3655 if (!g_deviceStateList)
3657 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3661 uint32_t length = u_arraylist_length(g_deviceStateList);
3662 OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
3663 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3665 for (uint32_t index = 0; index < length; index++)
3667 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3670 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3674 OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
3676 if (!strcmp(state->address, remoteAddress))
3678 OIC_LOG(DEBUG, TAG, "found state");
3683 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
3687 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3688 uint16_t target_state)
3690 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3691 state_type, target_state);
3692 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3694 ca_mutex_lock(g_deviceStateListMutex);
3695 if (!g_deviceStateList)
3697 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3698 ca_mutex_unlock(g_deviceStateListMutex);
3702 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3705 OIC_LOG(ERROR, TAG, "state is null");
3706 ca_mutex_unlock(g_deviceStateListMutex);
3710 uint16_t curValue = 0;
3713 case CA_LE_CONNECTION_STATE:
3714 curValue = state->connectedState;
3716 case CA_LE_SEND_STATE:
3717 curValue = state->sendState;
3723 if (target_state == curValue)
3725 ca_mutex_unlock(g_deviceStateListMutex);
3730 ca_mutex_unlock(g_deviceStateListMutex);
3734 ca_mutex_unlock(g_deviceStateListMutex);
3738 void CALEClientCreateDeviceList()
3740 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3742 // create new object array
3743 if (!g_gattObjectList)
3745 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3747 g_gattObjectList = u_arraylist_create();
3750 if (!g_deviceStateList)
3752 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3754 g_deviceStateList = u_arraylist_create();
3759 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3761 g_deviceList = u_arraylist_create();
3766 * Check Sent Count for remove g_sendBuffer
3768 void CALEClientUpdateSendCnt(JNIEnv *env)
3770 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3772 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3774 ca_mutex_lock(g_threadMutex);
3778 if (g_targetCnt <= g_currentSentCnt)
3781 g_currentSentCnt = 0;
3785 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3786 g_sendBuffer = NULL;
3788 // notity the thread
3789 ca_cond_signal(g_threadCond);
3791 CALEClientSetSendFinishFlag(true);
3792 OIC_LOG(DEBUG, TAG, "set signal for send data");
3795 ca_mutex_unlock(g_threadMutex);
3798 CAResult_t CALEClientInitGattMutexVaraibles()
3800 if (NULL == g_bleReqRespClientCbMutex)
3802 g_bleReqRespClientCbMutex = ca_mutex_new();
3803 if (NULL == g_bleReqRespClientCbMutex)
3805 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3806 return CA_STATUS_FAILED;
3810 if (NULL == g_bleServerBDAddressMutex)
3812 g_bleServerBDAddressMutex = ca_mutex_new();
3813 if (NULL == g_bleServerBDAddressMutex)
3815 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3816 return CA_STATUS_FAILED;
3820 if (NULL == g_threadMutex)
3822 g_threadMutex = ca_mutex_new();
3823 if (NULL == g_threadMutex)
3825 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3826 return CA_STATUS_FAILED;
3830 if (NULL == g_threadSendMutex)
3832 g_threadSendMutex = ca_mutex_new();
3833 if (NULL == g_threadSendMutex)
3835 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3836 return CA_STATUS_FAILED;
3840 if (NULL == g_deviceListMutex)
3842 g_deviceListMutex = ca_mutex_new();
3843 if (NULL == g_deviceListMutex)
3845 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3846 return CA_STATUS_FAILED;
3850 if (NULL == g_gattObjectMutex)
3852 g_gattObjectMutex = ca_mutex_new();
3853 if (NULL == g_gattObjectMutex)
3855 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3856 return CA_STATUS_FAILED;
3860 if (NULL == g_deviceStateListMutex)
3862 g_deviceStateListMutex = ca_mutex_new();
3863 if (NULL == g_deviceStateListMutex)
3865 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3866 return CA_STATUS_FAILED;
3870 if (NULL == g_SendFinishMutex)
3872 g_SendFinishMutex = ca_mutex_new();
3873 if (NULL == g_SendFinishMutex)
3875 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3876 return CA_STATUS_FAILED;
3880 if (NULL == g_threadWriteCharacteristicMutex)
3882 g_threadWriteCharacteristicMutex = ca_mutex_new();
3883 if (NULL == g_threadWriteCharacteristicMutex)
3885 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3886 return CA_STATUS_FAILED;
3890 if (NULL == g_deviceScanRetryDelayMutex)
3892 g_deviceScanRetryDelayMutex = ca_mutex_new();
3893 if (NULL == g_deviceScanRetryDelayMutex)
3895 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3896 return CA_STATUS_FAILED;
3900 if (NULL == g_threadSendStateMutex)
3902 g_threadSendStateMutex = ca_mutex_new();
3903 if (NULL == g_threadSendStateMutex)
3905 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3906 return CA_STATUS_FAILED;
3910 if (NULL == g_threadScanIntervalMutex)
3912 g_threadScanIntervalMutex = ca_mutex_new();
3913 if (NULL == g_threadScanIntervalMutex)
3915 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3916 return CA_STATUS_FAILED;
3920 return CA_STATUS_OK;
3923 void CALEClientTerminateGattMutexVariables()
3925 ca_mutex_free(g_bleReqRespClientCbMutex);
3926 g_bleReqRespClientCbMutex = NULL;
3928 ca_mutex_free(g_bleServerBDAddressMutex);
3929 g_bleServerBDAddressMutex = NULL;
3931 ca_mutex_free(g_threadMutex);
3932 g_threadMutex = NULL;
3934 ca_mutex_free(g_threadSendMutex);
3935 g_threadSendMutex = NULL;
3937 ca_mutex_free(g_deviceListMutex);
3938 g_deviceListMutex = NULL;
3940 ca_mutex_free(g_SendFinishMutex);
3941 g_SendFinishMutex = NULL;
3943 ca_mutex_free(g_threadWriteCharacteristicMutex);
3944 g_threadWriteCharacteristicMutex = NULL;
3946 ca_mutex_free(g_deviceScanRetryDelayMutex);
3947 g_deviceScanRetryDelayMutex = NULL;
3949 ca_mutex_free(g_threadSendStateMutex);
3950 g_threadSendStateMutex = NULL;
3952 ca_mutex_free(g_threadScanIntervalMutex);
3953 g_threadScanIntervalMutex = NULL;
3956 void CALEClientSetSendFinishFlag(bool flag)
3958 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3960 ca_mutex_lock(g_SendFinishMutex);
3961 g_isFinishedSendData = flag;
3962 ca_mutex_unlock(g_SendFinishMutex);
3969 CAResult_t CAStartLEGattClient()
3971 // init mutex for send logic
3972 if (!g_deviceDescCond)
3974 g_deviceDescCond = ca_cond_new();
3979 g_threadCond = ca_cond_new();
3982 if (!g_threadWriteCharacteristicCond)
3984 g_threadWriteCharacteristicCond = ca_cond_new();
3987 CAResult_t ret = CALEClientStartScanWithInterval();
3988 if (CA_STATUS_OK != ret)
3990 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
3994 g_isStartedLEClient = true;
3995 return CA_STATUS_OK;
3998 void CAStopLEGattClient()
4000 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4004 OIC_LOG(ERROR, TAG, "g_jvm is null");
4008 bool isAttached = false;
4010 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4013 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
4014 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4018 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4024 CAResult_t ret = CALEClientDisconnectAll(env);
4025 if (CA_STATUS_OK != ret)
4027 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4030 CALEClientStopScanWithInterval();
4032 ca_mutex_lock(g_threadMutex);
4033 OIC_LOG(DEBUG, TAG, "signal - connection cond");
4034 ca_cond_signal(g_threadCond);
4035 CALEClientSetSendFinishFlag(true);
4036 ca_mutex_unlock(g_threadMutex);
4038 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4039 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4040 ca_cond_signal(g_threadWriteCharacteristicCond);
4041 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4043 ca_mutex_lock(g_deviceScanRetryDelayMutex);
4044 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4045 ca_cond_signal(g_deviceScanRetryDelayCond);
4046 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
4048 ca_mutex_lock(g_threadScanIntervalMutex);
4049 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4050 ca_cond_signal(g_threadScanIntervalCond);
4051 ca_mutex_unlock(g_threadScanIntervalMutex);
4053 ca_cond_free(g_deviceDescCond);
4054 ca_cond_free(g_threadCond);
4055 ca_cond_free(g_threadWriteCharacteristicCond);
4056 ca_cond_free(g_deviceScanRetryDelayCond);
4057 ca_cond_free(g_threadScanIntervalCond);
4059 g_deviceDescCond = NULL;
4060 g_threadCond = NULL;
4061 g_threadWriteCharacteristicCond = NULL;
4062 g_deviceScanRetryDelayCond = NULL;
4063 g_threadScanIntervalCond = NULL;
4067 (*g_jvm)->DetachCurrentThread(g_jvm);
4072 CAResult_t CAInitializeLEGattClient()
4074 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4075 CALEClientInitialize();
4076 return CA_STATUS_OK;
4079 void CATerminateLEGattClient()
4081 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4082 CAStopLEGattClient();
4083 CALEClientTerminate();
4086 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4087 uint32_t dataLen, CALETransferType_t type,
4090 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4091 VERIFY_NON_NULL(data, TAG, "data is null");
4092 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4094 if (LE_UNICAST != type || position < 0)
4096 OIC_LOG(ERROR, TAG, "this request is not unicast");
4097 return CA_STATUS_INVALID_PARAM;
4100 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4103 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4105 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4106 VERIFY_NON_NULL(data, TAG, "data is null");
4108 return CALEClientSendMulticastMessage(data, dataLen);
4111 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4113 ca_mutex_lock(g_bleReqRespClientCbMutex);
4114 g_CABLEClientDataReceivedCallback = callback;
4115 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4118 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4120 g_threadPoolHandle = handle;
4123 CAResult_t CAGetLEAddress(char **local_address)
4125 VERIFY_NON_NULL(local_address, TAG, "local_address");
4126 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4127 return CA_NOT_SUPPORTED;
4130 JNIEXPORT void JNICALL
4131 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4134 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4135 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4136 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4137 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4139 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4142 JNIEXPORT void JNICALL
4143 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4146 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4147 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4148 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4149 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4151 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4154 JNIEXPORT void JNICALL
4155 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4158 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4159 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4160 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4162 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4163 if (CA_STATUS_OK != res)
4165 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4170 * Class: org_iotivity_ca_jar_caleinterface
4171 * Method: CALeGattConnectionStateChangeCallback
4172 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4174 JNIEXPORT void JNICALL
4175 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4181 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4183 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4184 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4185 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4187 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4189 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4192 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4196 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4199 OIC_LOG(ERROR, TAG, "address is null");
4202 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4204 if (state_connected == newstate)
4206 OIC_LOG(DEBUG, TAG, "LE is connected");
4207 if (GATT_SUCCESS == status)
4209 CAResult_t res = CALEClientUpdateDeviceState(address,
4210 CA_LE_CONNECTION_STATE,
4212 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4213 if (CA_STATUS_OK != res)
4215 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4219 res = CALEClientAddGattobjToList(env, gatt);
4220 if (CA_STATUS_OK != res)
4222 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4226 res = CALEClientDiscoverServices(env, gatt);
4227 if (CA_STATUS_OK != res)
4229 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4235 OIC_LOG(INFO, TAG, "unknown status");
4236 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4239 else // STATE_DISCONNECTED == newstate
4241 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4243 CAResult_t res = CALEClientUpdateDeviceState(address,
4244 CA_LE_CONNECTION_STATE,
4245 STATE_DISCONNECTED);
4246 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4247 if (CA_STATUS_OK != res)
4249 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4253 res = CALEClientGattClose(env, gatt);
4254 if (CA_STATUS_OK != res)
4256 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4259 if (CALECheckConnectionStateValue(status))
4261 // this state is unexpected reason to disconnect
4262 // if the reason is suitable, connection logic of the device will be destroyed.
4263 OIC_LOG(INFO, TAG, "connection logic destroy");
4268 // other reason except for gatt_success is expected to running
4269 // background connection in BT platform.
4270 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4271 CALEClientUpdateSendCnt(env);
4277 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4278 g_sendBuffer = NULL;
4285 CALEClientSendFinish(env, gatt);
4290 * Class: org_iotivity_ca_jar_caleinterface
4291 * Method: CALeGattServicesDiscoveredCallback
4292 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4294 JNIEXPORT void JNICALL
4295 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4300 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4301 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4302 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4303 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4305 if (GATT_SUCCESS != status) // discovery error
4307 CALEClientSendFinish(env, gatt);
4311 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4314 CALEClientSendFinish(env, gatt);
4318 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4321 CALEClientSendFinish(env, gatt);
4325 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4328 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4332 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4333 if (!jni_obj_GattCharacteristic)
4335 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4339 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4340 jni_obj_GattCharacteristic);
4341 if (CA_STATUS_OK != res)
4343 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4347 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4348 if (CA_STATUS_OK != res)
4350 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4352 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
4353 if (CA_STATUS_OK != res)
4355 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4359 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4360 STATE_SERVICE_CONNECTED);
4361 if (CA_STATUS_OK != res)
4363 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4369 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4370 if (CA_STATUS_OK != res)
4372 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4379 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
4380 if (CA_STATUS_OK != res)
4382 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4387 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4388 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4393 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4394 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4395 CALEClientSendFinish(env, gatt);
4400 * Class: org_iotivity_ca_jar_caleinterface
4401 * Method: CALeGattCharacteristicWritjclasseCallback
4402 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4404 JNIEXPORT void JNICALL
4405 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4406 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4408 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4409 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4410 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4411 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4413 // send success & signal
4414 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4420 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4426 if (GATT_SUCCESS != status) // error case
4428 OIC_LOG(ERROR, TAG, "send failure");
4431 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4432 if (CA_STATUS_OK != res)
4434 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4435 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4436 g_isSignalSetFlag = true;
4437 ca_cond_signal(g_threadWriteCharacteristicCond);
4438 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4440 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4442 if (CA_STATUS_OK != res)
4444 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4447 if (g_clientErrorCallback)
4449 jint length = (*env)->GetArrayLength(env, data);
4450 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4453 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4459 OIC_LOG(DEBUG, TAG, "send success");
4460 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4461 STATE_SEND_SUCCESS);
4462 if (CA_STATUS_OK != res)
4464 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4467 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4468 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4469 g_isSignalSetFlag = true;
4470 ca_cond_signal(g_threadWriteCharacteristicCond);
4471 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4473 CALEClientUpdateSendCnt(env);
4476 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4482 CALEClientSendFinish(env, gatt);
4487 * Class: org_iotivity_ca_jar_caleinterface
4488 * Method: CALeGattCharacteristicChangedCallback
4489 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4491 JNIEXPORT void JNICALL
4492 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4493 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4495 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4496 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4497 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4498 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4499 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4501 // get Byte Array and convert to uint8_t*
4502 jint length = (*env)->GetArrayLength(env, data);
4505 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4507 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4508 jni_byte_responseData);
4510 uint8_t* receivedData = OICMalloc(length);
4513 OIC_LOG(ERROR, TAG, "receivedData is null");
4517 memcpy(receivedData, jni_byte_responseData, length);
4518 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4520 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4523 OIC_LOG(ERROR, TAG, "jni_address is null");
4524 OICFree(receivedData);
4528 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4531 OIC_LOG(ERROR, TAG, "address is null");
4532 OICFree(receivedData);
4536 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4537 receivedData, length);
4539 uint32_t sentLength = 0;
4540 ca_mutex_lock(g_bleServerBDAddressMutex);
4541 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4542 ca_mutex_unlock(g_bleServerBDAddressMutex);
4544 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4548 * Class: org_iotivity_ca_jar_caleinterface
4549 * Method: CALeGattDescriptorWriteCallback
4550 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4552 JNIEXPORT void JNICALL
4553 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4557 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4558 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4559 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4560 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4562 if (GATT_SUCCESS != status) // error
4567 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4573 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4579 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4580 STATE_SERVICE_CONNECTED);
4581 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4582 if (CA_STATUS_OK != res)
4584 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4590 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4591 if (CA_STATUS_OK != res)
4593 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4602 CALEClientSendFinish(env, gatt);