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 ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
975 if (CA_STATUS_OK != ret)
977 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
985 // start LE Scan again
986 ret = CALEClientStartScanWithInterval();
987 if (CA_STATUS_OK != ret)
989 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
990 ca_mutex_unlock(g_threadSendMutex);
993 (*g_jvm)->DetachCurrentThread(g_jvm);
1000 (*g_jvm)->DetachCurrentThread(g_jvm);
1003 ca_mutex_unlock(g_threadSendMutex);
1004 return CA_SEND_FAILED;
1007 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
1008 const uint32_t dataLen)
1010 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1011 VERIFY_NON_NULL(data, TAG, "data is null");
1012 VERIFY_NON_NULL(env, TAG, "env is null");
1016 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1017 return CA_STATUS_FAILED;
1020 ca_mutex_lock(g_threadSendMutex);
1022 CALEClientSetSendFinishFlag(false);
1024 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1027 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1028 g_sendBuffer = NULL;
1031 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1032 if (CA_STATUS_OK != res)
1034 OIC_LOG(INFO, TAG, "there is no scanned device");
1038 // stop scan while sending
1039 CALEClientStopScanWithInterval();
1041 uint32_t length = u_arraylist_length(g_deviceList);
1042 g_targetCnt = length;
1044 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1045 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1046 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1048 for (uint32_t index = 0; index < length; index++)
1050 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1053 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1057 res = CALEClientSendData(env, jarrayObj);
1058 if (res != CA_STATUS_OK)
1060 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1064 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1066 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1067 ca_mutex_lock(g_threadMutex);
1068 if (!g_isFinishedSendData)
1070 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1071 ca_cond_wait(g_threadCond, g_threadMutex);
1072 OIC_LOG(DEBUG, TAG, "the data was sent");
1074 ca_mutex_unlock(g_threadMutex);
1076 // start LE Scan again
1077 res = CALEClientStartScanWithInterval();
1078 if (CA_STATUS_OK != res)
1080 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
1081 ca_mutex_unlock(g_threadSendMutex);
1085 ca_mutex_unlock(g_threadSendMutex);
1086 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1087 return CA_STATUS_OK;
1090 res = CALEClientStartScanWithInterval();
1091 if (CA_STATUS_OK != res)
1093 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
1094 ca_mutex_unlock(g_threadSendMutex);
1098 ca_mutex_unlock(g_threadSendMutex);
1099 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1100 return CA_SEND_FAILED;
1103 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1105 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1106 VERIFY_NON_NULL(device, TAG, "device is null");
1107 VERIFY_NON_NULL(env, TAG, "env is null");
1109 // get BLE address from bluetooth device object.
1110 char* address = NULL;
1111 CALEState_t* state = NULL;
1112 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1115 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1116 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1119 OIC_LOG(ERROR, TAG, "address is not available");
1120 return CA_STATUS_FAILED;
1122 ca_mutex_lock(g_deviceStateListMutex);
1123 state = CALEClientGetStateInfo(address);
1124 ca_mutex_unlock(g_deviceStateListMutex);
1129 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1131 // cancel previous connection request before connection
1132 // if there is gatt object in g_gattObjectList.
1135 jobject gatt = CALEClientGetGattObjInList(env, address);
1138 CAResult_t res = CALEClientDisconnect(env, gatt);
1139 if (CA_STATUS_OK != res)
1141 OIC_LOG(INFO, TAG, "there is no gatt object");
1144 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1147 // connection request
1148 jobject newGatt = CALEClientConnect(env, device,
1150 if (NULL == newGatt)
1152 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1153 return CA_STATUS_FAILED;
1158 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1159 STATE_SERVICE_CONNECTED))
1161 OIC_LOG(INFO, TAG, "GATT has already connected");
1163 jobject gatt = CALEClientGetGattObjInList(env, address);
1166 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1167 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1168 return CA_STATUS_FAILED;
1171 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1172 if (CA_STATUS_OK != ret)
1174 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1175 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1178 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1180 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1183 OIC_LOG(INFO, TAG, "service connecting...");
1185 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1186 STATE_DISCONNECTED))
1188 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1190 // cancel previous connection request before connection
1191 // if there is gatt object in g_gattObjectList.
1194 jobject gatt = CALEClientGetGattObjInList(env, address);
1197 CAResult_t res = CALEClientDisconnect(env, gatt);
1198 if (CA_STATUS_OK != res)
1200 OIC_LOG(INFO, TAG, "there is no gatt object");
1203 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1206 OIC_LOG(DEBUG, TAG, "start to connect LE");
1207 jobject gatt = CALEClientConnect(env, device,
1208 CALEClientGetFlagFromState(env, jni_address,
1209 CA_LE_AUTO_CONNECT_FLAG));
1213 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1214 return CA_STATUS_FAILED;
1219 return CA_STATUS_OK;
1222 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1224 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1225 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1227 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1228 "()Landroid/bluetooth/BluetoothDevice;");
1229 if (!jni_mid_getDevice)
1231 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1235 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1236 if (!jni_obj_device)
1238 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1242 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1245 OIC_LOG(ERROR, TAG, "jni_address is null");
1255 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1258 OIC_LOG(DEBUG, TAG, "Gatt Close");
1259 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1260 VERIFY_NON_NULL(env, TAG, "env is null");
1262 // get BluetoothGatt method
1263 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1264 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1265 if (!jni_mid_closeGatt)
1267 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1268 return CA_STATUS_OK;
1271 // call disconnect gatt method
1272 OIC_LOG(DEBUG, TAG, "request to close GATT");
1273 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1275 if ((*env)->ExceptionCheck(env))
1277 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1278 (*env)->ExceptionDescribe(env);
1279 (*env)->ExceptionClear(env);
1280 return CA_STATUS_FAILED;
1283 return CA_STATUS_OK;
1286 CAResult_t CALEClientStartScan()
1288 if (!g_isStartedLEClient)
1290 OIC_LOG(ERROR, TAG, "LE client is not started");
1291 return CA_STATUS_FAILED;
1296 OIC_LOG(ERROR, TAG, "g_jvm is null");
1297 return CA_STATUS_FAILED;
1300 bool isAttached = false;
1302 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1305 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1307 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1310 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1311 return CA_STATUS_FAILED;
1316 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1318 CAResult_t ret = CA_STATUS_OK;
1319 // scan gatt server with UUID
1320 if (g_leScanCallback && g_uuidList)
1323 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1325 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1327 if (CA_STATUS_OK != ret)
1329 if (CA_ADAPTER_NOT_ENABLED == ret)
1331 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1335 OIC_LOG(ERROR, TAG, "start scan has failed");
1342 (*g_jvm)->DetachCurrentThread(g_jvm);
1348 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1350 VERIFY_NON_NULL(callback, TAG, "callback is null");
1351 VERIFY_NON_NULL(env, TAG, "env is null");
1353 if (!CALEIsEnableBTAdapter(env))
1355 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1356 return CA_ADAPTER_NOT_ENABLED;
1359 // get default bt adapter class
1360 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1361 if (!jni_cid_BTAdapter)
1363 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1364 return CA_STATUS_FAILED;
1367 // get remote bt adapter method
1368 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1369 "getDefaultAdapter",
1370 METHODID_OBJECTNONPARAM);
1371 if (!jni_mid_getDefaultAdapter)
1373 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1374 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1375 return CA_STATUS_FAILED;
1378 // get start le scan method
1379 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1380 "(Landroid/bluetooth/BluetoothAdapter$"
1381 "LeScanCallback;)Z");
1382 if (!jni_mid_startLeScan)
1384 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1385 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1386 return CA_STATUS_FAILED;
1389 // gat bt adapter object
1390 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1391 jni_mid_getDefaultAdapter);
1392 if (!jni_obj_BTAdapter)
1394 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1395 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1396 return CA_STATUS_FAILED;
1399 // call start le scan method
1400 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1401 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1402 jni_mid_startLeScan, callback);
1403 if (!jni_obj_startLeScan)
1405 OIC_LOG(INFO, TAG, "startLeScan has failed");
1409 OIC_LOG(DEBUG, TAG, "LeScan has started");
1412 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1413 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1414 return CA_STATUS_OK;
1417 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1419 VERIFY_NON_NULL(callback, TAG, "callback is null");
1420 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1421 VERIFY_NON_NULL(env, TAG, "env is null");
1423 if (!CALEIsEnableBTAdapter(env))
1425 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1426 return CA_ADAPTER_NOT_ENABLED;
1429 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1430 if (!jni_cid_BTAdapter)
1432 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1433 return CA_STATUS_FAILED;
1436 // get remote bt adapter method
1437 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1438 "getDefaultAdapter",
1439 METHODID_OBJECTNONPARAM);
1440 if (!jni_mid_getDefaultAdapter)
1442 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1443 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1444 return CA_STATUS_FAILED;
1447 // get start le scan method
1448 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1449 "([Ljava/util/UUID;Landroid/bluetooth/"
1450 "BluetoothAdapter$LeScanCallback;)Z");
1451 if (!jni_mid_startLeScan)
1453 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1454 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1455 return CA_STATUS_FAILED;
1458 // get bt adapter object
1459 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1460 jni_mid_getDefaultAdapter);
1461 if (!jni_obj_BTAdapter)
1463 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1464 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1465 return CA_STATUS_FAILED;
1468 // call start le scan method
1469 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1470 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1471 jni_mid_startLeScan, uuids, callback);
1472 if (!jni_obj_startLeScan)
1474 OIC_LOG(INFO, TAG, "startLeScan has failed");
1478 OIC_LOG(DEBUG, TAG, "LeScan has started");
1481 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1482 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1483 return CA_STATUS_OK;
1486 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1488 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1489 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1492 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1495 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1499 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1500 "(Ljava/lang/String;)"
1501 "Ljava/util/UUID;");
1502 if (!jni_mid_fromString)
1504 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1508 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1509 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1513 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1517 return jni_obj_uuid;
1520 CAResult_t CALEClientStopScan()
1524 OIC_LOG(ERROR, TAG, "g_jvm is null");
1525 return CA_STATUS_FAILED;
1528 bool isAttached = false;
1530 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1533 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1534 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1537 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1538 return CA_STATUS_FAILED;
1543 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1544 if (CA_STATUS_OK != ret)
1546 if (CA_ADAPTER_NOT_ENABLED == ret)
1548 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1552 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1558 (*g_jvm)->DetachCurrentThread(g_jvm);
1564 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1566 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1567 VERIFY_NON_NULL(callback, TAG, "callback is null");
1568 VERIFY_NON_NULL(env, TAG, "env is null");
1570 if (!CALEIsEnableBTAdapter(env))
1572 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1573 return CA_ADAPTER_NOT_ENABLED;
1576 // get default bt adapter class
1577 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1578 if (!jni_cid_BTAdapter)
1580 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1581 return CA_STATUS_FAILED;
1584 // get remote bt adapter method
1585 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1586 "getDefaultAdapter",
1587 METHODID_OBJECTNONPARAM);
1588 if (!jni_mid_getDefaultAdapter)
1590 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1591 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1592 return CA_STATUS_FAILED;
1595 // get start le scan method
1596 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1597 "(Landroid/bluetooth/"
1598 "BluetoothAdapter$LeScanCallback;)V");
1599 if (!jni_mid_stopLeScan)
1601 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1602 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1603 return CA_STATUS_FAILED;
1606 // gat bt adapter object
1607 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1608 jni_mid_getDefaultAdapter);
1609 if (!jni_obj_BTAdapter)
1611 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1612 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1613 return CA_STATUS_FAILED;
1616 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1617 // call start le scan method
1618 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1619 if ((*env)->ExceptionCheck(env))
1621 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1622 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1623 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1624 (*env)->ExceptionDescribe(env);
1625 (*env)->ExceptionClear(env);
1626 return CA_STATUS_FAILED;
1629 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1630 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1631 return CA_STATUS_OK;
1634 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1636 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1637 VERIFY_NON_NULL(env, TAG, "env");
1638 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1640 ca_mutex_lock(g_deviceStateListMutex);
1642 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1645 OIC_LOG(ERROR, TAG, "address is not available");
1646 return CA_STATUS_FAILED;
1649 if (CALEClientIsDeviceInList(address))
1651 CALEState_t* curState = CALEClientGetStateInfo(address);
1654 OIC_LOG(ERROR, TAG, "curState is null");
1655 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1656 ca_mutex_unlock(g_deviceStateListMutex);
1657 return CA_STATUS_FAILED;
1659 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1663 case CA_LE_AUTO_CONNECT_FLAG:
1664 curState->autoConnectFlag = flag;
1666 case CA_LE_DESCRIPTOR_FOUND:
1667 curState->isDescriptorFound = flag;
1674 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1675 ca_mutex_unlock(g_deviceStateListMutex);
1676 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1677 return CA_STATUS_OK;
1680 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1682 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1683 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1684 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1686 ca_mutex_lock(g_deviceStateListMutex);
1688 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1691 OIC_LOG(ERROR, TAG, "address is not available");
1692 ca_mutex_unlock(g_deviceStateListMutex);
1696 CALEState_t* curState = CALEClientGetStateInfo(address);
1697 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1700 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1701 ca_mutex_unlock(g_deviceStateListMutex);
1705 jboolean ret = JNI_FALSE;
1708 case CA_LE_AUTO_CONNECT_FLAG:
1709 ret = curState->autoConnectFlag;
1711 case CA_LE_DESCRIPTOR_FOUND:
1712 ret = curState->isDescriptorFound;
1717 ca_mutex_unlock(g_deviceStateListMutex);
1719 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1720 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1724 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1726 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1727 VERIFY_NON_NULL(env, TAG, "env is null");
1728 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1730 ca_mutex_lock(g_threadSendMutex);
1732 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1735 OIC_LOG(ERROR, TAG, "jni_address is not available");
1736 ca_mutex_unlock(g_threadSendMutex);
1737 return CA_STATUS_FAILED;
1740 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1743 OIC_LOG(ERROR, TAG, "address is not available");
1744 ca_mutex_unlock(g_threadSendMutex);
1745 return CA_STATUS_FAILED;
1748 CAResult_t res = CA_STATUS_OK;
1749 if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1750 STATE_DISCONNECTED))
1752 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1753 if (NULL == newGatt)
1755 OIC_LOG(INFO, TAG, "newGatt is not available");
1756 res = CA_STATUS_FAILED;
1759 ca_mutex_unlock(g_threadSendMutex);
1764 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1766 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1767 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1768 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1770 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1771 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1774 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1777 OIC_LOG(ERROR, TAG, "address is not available");
1781 // close the gatt service
1782 jobject gatt = CALEClientGetGattObjInList(env, address);
1785 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1786 if (CA_STATUS_OK != res)
1788 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1789 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1793 // clean previous gatt object after close profile service
1794 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1795 if (CA_STATUS_OK != res)
1797 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1798 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1802 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1805 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1808 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1812 // add new gatt object into g_gattObjectList
1813 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1814 if (CA_STATUS_OK != res)
1816 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1823 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1825 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1826 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1827 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1829 if (!g_leGattCallback)
1831 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1835 if (!CALEIsEnableBTAdapter(env))
1837 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1841 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1844 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1848 // get BluetoothDevice method
1849 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1850 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1852 "(Landroid/content/Context;ZLandroid/"
1853 "bluetooth/BluetoothGattCallback;)"
1854 "Landroid/bluetooth/BluetoothGatt;");
1855 if (!jni_mid_connectGatt)
1857 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1861 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1862 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1863 jni_mid_connectGatt,
1865 autoconnect, g_leGattCallback);
1866 if (!jni_obj_connectGatt)
1868 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1869 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1870 CALEClientUpdateSendCnt(env);
1875 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1877 return jni_obj_connectGatt;
1880 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1882 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1884 VERIFY_NON_NULL(env, TAG, "env is null");
1885 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1887 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1888 if (!jni_cid_BTAdapter)
1890 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1891 return CA_STATUS_FAILED;
1894 // get remote bt adapter method
1895 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1896 "getDefaultAdapter",
1897 METHODID_OBJECTNONPARAM);
1898 if (!jni_mid_getDefaultAdapter)
1900 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1901 return CA_STATUS_FAILED;
1904 // gat bt adapter object
1905 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1906 jni_mid_getDefaultAdapter);
1907 if (!jni_obj_BTAdapter)
1909 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1910 return CA_STATUS_FAILED;
1913 // get closeProfileProxy method
1914 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1915 "closeProfileProxy",
1916 "(ILandroid/bluetooth/"
1917 "BluetoothProfile;)V");
1918 if (!jni_mid_closeProfileProxy)
1920 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1921 return CA_STATUS_FAILED;
1924 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1925 if (!jni_cid_BTProfile)
1927 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1928 return CA_STATUS_FAILED;
1931 // GATT - Constant value : 7 (0x00000007)
1932 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1936 OIC_LOG(ERROR, TAG, "id_gatt is null");
1937 return CA_STATUS_FAILED;
1940 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1942 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1943 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1944 if ((*env)->ExceptionCheck(env))
1946 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1947 (*env)->ExceptionDescribe(env);
1948 (*env)->ExceptionClear(env);
1949 return CA_STATUS_FAILED;
1952 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1953 return CA_STATUS_OK;
1957 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1959 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1960 VERIFY_NON_NULL(env, TAG, "env is null");
1961 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1963 // get BluetoothGatt method
1964 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1965 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1966 "disconnect", "()V");
1967 if (!jni_mid_disconnectGatt)
1969 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1970 return CA_STATUS_FAILED;
1973 // call disconnect gatt method
1974 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1975 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1976 if ((*env)->ExceptionCheck(env))
1978 OIC_LOG(ERROR, TAG, "disconnect has failed");
1979 (*env)->ExceptionDescribe(env);
1980 (*env)->ExceptionClear(env);
1981 return CA_STATUS_FAILED;
1984 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1986 return CA_STATUS_OK;
1989 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1991 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1992 VERIFY_NON_NULL(env, TAG, "env is null");
1994 if (!g_gattObjectList)
1996 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1997 return CA_STATUS_OK;
2000 uint32_t length = u_arraylist_length(g_gattObjectList);
2001 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
2002 for (uint32_t index = 0; index < length; index++)
2004 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
2005 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2008 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2011 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2012 if (CA_STATUS_OK != res)
2014 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2019 return CA_STATUS_OK;
2022 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
2024 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
2025 VERIFY_NON_NULL(env, TAG, "env is null");
2027 if (!g_gattObjectList)
2029 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2030 return CA_STATUS_OK;
2033 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
2036 OIC_LOG(ERROR, TAG, "address is null");
2037 return CA_STATUS_FAILED;
2040 uint32_t length = u_arraylist_length(g_gattObjectList);
2041 for (uint32_t index = 0; index < length; index++)
2043 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2046 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2050 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2051 if (!jni_setAddress)
2053 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2054 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2055 return CA_STATUS_FAILED;
2058 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2061 OIC_LOG(ERROR, TAG, "setAddress is null");
2062 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2063 return CA_STATUS_FAILED;
2066 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2067 if (!strcmp(address, setAddress))
2069 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2070 if (CA_STATUS_OK != res)
2072 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2073 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2074 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2075 return CA_STATUS_FAILED;
2077 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2078 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2079 return CA_STATUS_OK;
2081 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2083 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2085 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2086 return CA_STATUS_OK;
2089 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2091 VERIFY_NON_NULL(env, TAG, "env is null");
2092 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2094 if (!CALEIsEnableBTAdapter(env))
2096 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2097 return CA_ADAPTER_NOT_ENABLED;
2100 // get BluetoothGatt.discoverServices method
2101 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2102 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2103 "discoverServices", "()Z");
2104 if (!jni_mid_discoverServices)
2106 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2107 return CA_STATUS_FAILED;
2110 // call disconnect gatt method
2111 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2112 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2115 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2116 return CA_STATUS_FAILED;
2119 return CA_STATUS_OK;
2122 static void CALEWriteCharacteristicThread(void* object)
2124 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2126 bool isAttached = false;
2128 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2131 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2132 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2136 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2142 jobject gatt = (jobject)object;
2143 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2144 if (CA_STATUS_OK != ret)
2146 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2151 (*g_jvm)->DetachCurrentThread(g_jvm);
2155 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2157 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2159 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2160 VERIFY_NON_NULL(env, TAG, "env is null");
2162 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2165 CALEClientSendFinish(env, gatt);
2166 return CA_STATUS_FAILED;
2169 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2172 CALEClientSendFinish(env, gatt);
2173 return CA_STATUS_FAILED;
2176 ca_mutex_lock(g_threadSendStateMutex);
2178 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2180 OIC_LOG(INFO, TAG, "current state is SENDING");
2181 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2182 ca_mutex_unlock(g_threadSendStateMutex);
2183 return CA_STATUS_OK;
2186 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2189 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2190 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2191 CALEClientSendFinish(env, gatt);
2192 ca_mutex_unlock(g_threadSendStateMutex);
2193 return CA_STATUS_FAILED;
2196 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2198 ca_mutex_unlock(g_threadSendStateMutex);
2201 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2202 if (!jni_obj_character)
2204 CALEClientSendFinish(env, gatt);
2205 return CA_STATUS_FAILED;
2208 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2209 if (CA_STATUS_OK != ret)
2211 CALEClientSendFinish(env, gatt);
2212 return CA_STATUS_FAILED;
2215 // wait for callback for write Characteristic with success to sent data
2216 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2217 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2218 if (!g_isSignalSetFlag)
2220 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2221 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2222 g_threadWriteCharacteristicMutex,
2223 WAIT_TIME_WRITE_CHARACTERISTIC))
2225 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2226 g_isSignalSetFlag = false;
2227 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2228 return CA_STATUS_FAILED;
2231 // reset flag set by writeCharacteristic Callback
2232 g_isSignalSetFlag = false;
2233 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2235 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2236 return CA_STATUS_OK;
2239 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2241 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2242 VERIFY_NON_NULL(env, TAG, "env is null");
2243 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2245 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2246 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2247 CALEWriteCharacteristicThread, (void*)gattParam))
2249 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2250 return CA_STATUS_FAILED;
2253 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2254 return CA_STATUS_OK;
2257 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2258 jobject gattCharacteristic)
2260 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2261 VERIFY_NON_NULL(env, TAG, "env is null");
2262 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2263 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2265 if (!CALEIsEnableBTAdapter(env))
2267 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2268 return CA_STATUS_FAILED;
2271 // get BluetoothGatt.write characteristic method
2272 OIC_LOG(DEBUG, TAG, "write characteristic method");
2273 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2274 "writeCharacteristic",
2275 "(Landroid/bluetooth/"
2276 "BluetoothGattCharacteristic;)Z");
2277 if (!jni_mid_writeCharacteristic)
2279 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2280 return CA_STATUS_FAILED;
2283 // call disconnect gatt method
2284 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2285 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2286 jni_mid_writeCharacteristic,
2287 gattCharacteristic);
2290 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2294 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2295 return CA_STATUS_FAILED;
2298 return CA_STATUS_OK;
2301 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2303 VERIFY_NON_NULL(env, TAG, "env is null");
2304 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2306 if (!CALEIsEnableBTAdapter(env))
2308 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2309 return CA_STATUS_FAILED;
2312 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2315 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2316 return CA_STATUS_FAILED;
2319 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2320 if (!jni_obj_GattCharacteristic)
2322 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2323 return CA_STATUS_FAILED;
2326 OIC_LOG(DEBUG, TAG, "read characteristic method");
2327 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2328 "readCharacteristic",
2329 "(Landroid/bluetooth/"
2330 "BluetoothGattCharacteristic;)Z");
2331 if (!jni_mid_readCharacteristic)
2333 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2334 return CA_STATUS_FAILED;
2337 // call disconnect gatt method
2338 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2339 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2340 jni_obj_GattCharacteristic);
2343 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2347 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2348 return CA_STATUS_FAILED;
2351 return CA_STATUS_OK;
2354 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2355 jobject characteristic)
2357 VERIFY_NON_NULL(env, TAG, "env is null");
2358 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2359 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2361 if (!CALEIsEnableBTAdapter(env))
2363 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2364 return CA_ADAPTER_NOT_ENABLED;
2367 // get BluetoothGatt.setCharacteristicNotification method
2368 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2369 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2370 "setCharacteristicNotification",
2371 "(Landroid/bluetooth/"
2372 "BluetoothGattCharacteristic;Z)Z");
2373 if (!jni_mid_setNotification)
2375 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2376 return CA_STATUS_FAILED;
2379 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2380 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2381 characteristic, JNI_TRUE);
2382 if (JNI_TRUE == ret)
2384 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2388 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2389 return CA_STATUS_FAILED;
2392 return CA_STATUS_OK;
2395 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2397 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2398 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2399 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2401 if (!CALEIsEnableBTAdapter(env))
2403 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2407 // get BluetoothGatt.getService method
2408 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2409 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2411 "(Ljava/util/UUID;)Landroid/bluetooth/"
2412 "BluetoothGattService;");
2413 if (!jni_mid_getService)
2415 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2419 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2420 if (!jni_obj_service_uuid)
2422 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2426 // get bluetooth gatt service
2427 OIC_LOG(DEBUG, TAG, "request to get service");
2428 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2429 jni_obj_service_uuid);
2430 if (!jni_obj_gattService)
2432 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2436 // get bluetooth gatt service method
2437 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2438 "BluetoothGattService",
2439 "getCharacteristic",
2440 "(Ljava/util/UUID;)"
2441 "Landroid/bluetooth/"
2442 "BluetoothGattCharacteristic;");
2443 if (!jni_mid_getCharacteristic)
2445 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2449 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2452 OIC_LOG(ERROR, TAG, "uuid is null");
2456 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2457 if (!jni_obj_tx_uuid)
2459 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2460 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2464 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2465 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2466 jni_mid_getCharacteristic,
2469 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2470 return jni_obj_GattCharacteristic;
2473 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2475 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2476 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2477 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2478 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2480 if (!CALEIsEnableBTAdapter(env))
2482 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2486 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2489 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2493 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2494 if (!jni_obj_GattCharacteristic)
2496 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2500 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2501 "/BluetoothGattCharacteristic");
2502 if (!jni_cid_BTGattCharacteristic)
2504 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2508 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2509 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2511 if (!jni_mid_setValue)
2513 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2517 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2519 if (JNI_TRUE == ret)
2521 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2525 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2530 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2531 "setWriteType", "(I)V");
2532 if (!jni_mid_setWriteType)
2534 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2538 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2539 "WRITE_TYPE_NO_RESPONSE", "I");
2540 if (!jni_fid_no_response)
2542 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2546 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2547 jni_fid_no_response);
2549 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2551 return jni_obj_GattCharacteristic;
2554 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2556 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2557 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2559 if (!CALEIsEnableBTAdapter(env))
2561 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2565 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2566 "BluetoothGattCharacteristic",
2567 "getValue", "()[B");
2568 if (!jni_mid_getValue)
2570 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2574 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2576 return jni_obj_data_array;
2579 CAResult_t CALEClientCreateUUIDList()
2583 OIC_LOG(ERROR, TAG, "g_jvm is null");
2584 return CA_STATUS_FAILED;
2587 bool isAttached = false;
2589 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2592 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2593 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2597 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2598 return CA_STATUS_FAILED;
2603 // create new object array
2604 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2605 if (!jni_cid_uuid_list)
2607 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2611 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2612 jni_cid_uuid_list, NULL);
2613 if (!jni_obj_uuid_list)
2615 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2620 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2623 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2626 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2628 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2632 (*g_jvm)->DetachCurrentThread(g_jvm);
2635 return CA_STATUS_OK;
2642 (*g_jvm)->DetachCurrentThread(g_jvm);
2644 return CA_STATUS_FAILED;
2647 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2648 jobject characteristic)
2650 VERIFY_NON_NULL(env, TAG, "env is null");
2651 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2652 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2654 if (!CALEIsEnableBTAdapter(env))
2656 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2657 return CA_ADAPTER_NOT_ENABLED;
2660 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2661 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2662 "BluetoothGattCharacteristic",
2664 "(Ljava/util/UUID;)Landroid/bluetooth/"
2665 "BluetoothGattDescriptor;");
2666 if (!jni_mid_getDescriptor)
2668 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2669 return CA_STATUS_FAILED;
2672 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2673 if (!jni_obj_cc_uuid)
2675 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2676 return CA_STATUS_FAILED;
2679 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2680 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2681 jni_mid_getDescriptor, jni_obj_cc_uuid);
2682 if (!jni_obj_descriptor)
2684 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2685 return CA_NOT_SUPPORTED;
2688 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2689 jclass jni_cid_descriptor = (*env)->FindClass(env,
2690 "android/bluetooth/BluetoothGattDescriptor");
2691 if (!jni_cid_descriptor)
2693 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2694 return CA_STATUS_FAILED;
2697 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2698 if (!jni_mid_setValue)
2700 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2701 return CA_STATUS_FAILED;
2704 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2705 "ENABLE_NOTIFICATION_VALUE", "[B");
2706 if (!jni_fid_NotiValue)
2708 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2709 return CA_STATUS_FAILED;
2712 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2714 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2715 env, jni_obj_descriptor, jni_mid_setValue,
2716 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2719 OIC_LOG(DEBUG, TAG, "setValue success");
2723 OIC_LOG(ERROR, TAG, "setValue has failed");
2724 return CA_STATUS_FAILED;
2727 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2729 "(Landroid/bluetooth/"
2730 "BluetoothGattDescriptor;)Z");
2731 if (!jni_mid_writeDescriptor)
2733 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2734 return CA_STATUS_FAILED;
2737 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2738 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2739 jni_obj_descriptor);
2742 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2746 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2747 return CA_STATUS_FAILED;
2750 return CA_STATUS_OK;
2753 void CALEClientCreateScanDeviceList(JNIEnv *env)
2755 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2756 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2758 ca_mutex_lock(g_deviceListMutex);
2759 // create new object array
2760 if (g_deviceList == NULL)
2762 OIC_LOG(DEBUG, TAG, "Create device list");
2764 g_deviceList = u_arraylist_create();
2766 ca_mutex_unlock(g_deviceListMutex);
2769 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2771 VERIFY_NON_NULL(device, TAG, "device is null");
2772 VERIFY_NON_NULL(env, TAG, "env is null");
2774 ca_mutex_lock(g_deviceListMutex);
2778 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2779 CALEClientStopScanWithInterval();
2781 ca_mutex_unlock(g_deviceListMutex);
2782 return CA_STATUS_FAILED;
2785 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2786 if (!jni_remoteAddress)
2788 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2789 ca_mutex_unlock(g_deviceListMutex);
2790 return CA_STATUS_FAILED;
2793 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2796 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2797 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2798 ca_mutex_unlock(g_deviceListMutex);
2799 return CA_STATUS_FAILED;
2802 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2804 jobject gdevice = (*env)->NewGlobalRef(env, device);
2805 u_arraylist_add(g_deviceList, gdevice);
2806 ca_cond_signal(g_deviceDescCond);
2807 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2809 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2810 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2812 ca_mutex_unlock(g_deviceListMutex);
2814 return CA_STATUS_OK;
2817 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2819 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2820 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2824 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2828 uint32_t length = u_arraylist_length(g_deviceList);
2829 for (uint32_t index = 0; index < length; index++)
2831 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2834 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2838 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2839 if (!jni_setAddress)
2841 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2845 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2848 OIC_LOG(ERROR, TAG, "setAddress is null");
2849 (*env)->DeleteLocalRef(env, jni_setAddress);
2853 if (!strcmp(remoteAddress, setAddress))
2855 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2856 (*env)->DeleteLocalRef(env, jni_setAddress);
2860 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2861 (*env)->DeleteLocalRef(env, jni_setAddress);
2864 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2869 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2871 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2872 VERIFY_NON_NULL(env, TAG, "env is null");
2874 ca_mutex_lock(g_deviceListMutex);
2878 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2879 ca_mutex_unlock(g_deviceListMutex);
2880 return CA_STATUS_FAILED;
2883 uint32_t length = u_arraylist_length(g_deviceList);
2884 for (uint32_t index = 0; index < length; index++)
2886 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2889 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2892 (*env)->DeleteGlobalRef(env, jarrayObj);
2896 OICFree(g_deviceList);
2897 g_deviceList = NULL;
2899 ca_mutex_unlock(g_deviceListMutex);
2900 return CA_STATUS_OK;
2903 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2905 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2906 VERIFY_NON_NULL(address, TAG, "address is null");
2907 VERIFY_NON_NULL(env, TAG, "env is null");
2909 ca_mutex_lock(g_deviceListMutex);
2913 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2914 ca_mutex_unlock(g_deviceListMutex);
2915 return CA_STATUS_FAILED;
2918 uint32_t length = u_arraylist_length(g_deviceList);
2919 for (uint32_t index = 0; index < length; index++)
2921 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2924 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2925 ca_mutex_unlock(g_deviceListMutex);
2926 return CA_STATUS_FAILED;
2929 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2930 if (!jni_setAddress)
2932 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2933 ca_mutex_unlock(g_deviceListMutex);
2934 return CA_STATUS_FAILED;
2937 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2940 OIC_LOG(ERROR, TAG, "setAddress is null");
2941 ca_mutex_unlock(g_deviceListMutex);
2942 return CA_STATUS_FAILED;
2945 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2948 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2949 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2950 ca_mutex_unlock(g_deviceListMutex);
2951 return CA_STATUS_FAILED;
2954 if (!strcmp(setAddress, remoteAddress))
2956 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2957 (*env)->DeleteGlobalRef(env, jarrayObj);
2959 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2960 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2962 if (NULL == u_arraylist_remove(g_deviceList, index))
2964 OIC_LOG(ERROR, TAG, "List removal failed.");
2965 ca_mutex_unlock(g_deviceListMutex);
2966 return CA_STATUS_FAILED;
2968 ca_mutex_unlock(g_deviceListMutex);
2969 return CA_STATUS_OK;
2971 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2972 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2975 ca_mutex_unlock(g_deviceListMutex);
2976 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2978 return CA_STATUS_OK;
2985 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2987 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2988 VERIFY_NON_NULL(env, TAG, "env is null");
2989 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2991 ca_mutex_lock(g_gattObjectMutex);
2993 if (!g_gattObjectList)
2995 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2996 ca_mutex_unlock(g_gattObjectMutex);
2997 return CA_STATUS_FAILED;
3000 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3001 if (!jni_remoteAddress)
3003 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3004 ca_mutex_unlock(g_gattObjectMutex);
3005 return CA_STATUS_FAILED;
3008 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3011 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3012 ca_mutex_unlock(g_gattObjectMutex);
3013 return CA_STATUS_FAILED;
3016 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
3017 if (!CALEClientIsGattObjInList(env, remoteAddress))
3019 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
3020 u_arraylist_add(g_gattObjectList, newGatt);
3021 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
3024 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3025 ca_mutex_unlock(g_gattObjectMutex);
3026 return CA_STATUS_OK;
3029 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
3031 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
3032 VERIFY_NON_NULL(env, TAG, "env is null");
3033 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
3035 uint32_t length = u_arraylist_length(g_gattObjectList);
3036 for (uint32_t index = 0; index < length; index++)
3039 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3042 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3046 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3047 if (!jni_setAddress)
3049 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3053 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3056 OIC_LOG(ERROR, TAG, "setAddress is null");
3060 if (!strcmp(remoteAddress, setAddress))
3062 OIC_LOG(DEBUG, TAG, "the device is already set");
3063 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3068 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3073 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3077 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3079 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3080 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3081 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3083 ca_mutex_lock(g_gattObjectMutex);
3084 uint32_t length = u_arraylist_length(g_gattObjectList);
3085 for (uint32_t index = 0; index < length; index++)
3087 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3090 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3091 ca_mutex_unlock(g_gattObjectMutex);
3095 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3096 if (!jni_setAddress)
3098 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3099 ca_mutex_unlock(g_gattObjectMutex);
3103 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3106 OIC_LOG(ERROR, TAG, "setAddress is null");
3107 ca_mutex_unlock(g_gattObjectMutex);
3111 if (!strcmp(remoteAddress, setAddress))
3113 OIC_LOG(DEBUG, TAG, "the device is already set");
3114 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3115 ca_mutex_unlock(g_gattObjectMutex);
3118 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3121 ca_mutex_unlock(g_gattObjectMutex);
3122 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3126 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3128 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3129 VERIFY_NON_NULL(env, TAG, "env is null");
3131 ca_mutex_lock(g_gattObjectMutex);
3132 if (!g_gattObjectList)
3134 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3135 ca_mutex_unlock(g_gattObjectMutex);
3136 return CA_STATUS_OK;
3139 uint32_t length = u_arraylist_length(g_gattObjectList);
3140 for (uint32_t index = 0; index < length; index++)
3142 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3145 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3148 (*env)->DeleteGlobalRef(env, jarrayObj);
3152 OICFree(g_gattObjectList);
3153 g_gattObjectList = NULL;
3154 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3155 ca_mutex_unlock(g_gattObjectMutex);
3156 return CA_STATUS_OK;
3159 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3161 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3162 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3163 VERIFY_NON_NULL(env, TAG, "env is null");
3165 ca_mutex_lock(g_gattObjectMutex);
3166 if (!g_gattObjectList)
3168 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3169 ca_mutex_unlock(g_gattObjectMutex);
3170 return CA_STATUS_OK;
3173 uint32_t length = u_arraylist_length(g_gattObjectList);
3174 for (uint32_t index = 0; index < length; index++)
3176 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3179 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3180 ca_mutex_unlock(g_gattObjectMutex);
3181 return CA_STATUS_FAILED;
3184 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3185 if (!jni_setAddress)
3187 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3188 ca_mutex_unlock(g_gattObjectMutex);
3189 return CA_STATUS_FAILED;
3192 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3195 OIC_LOG(ERROR, TAG, "setAddress is null");
3196 ca_mutex_unlock(g_gattObjectMutex);
3197 return CA_STATUS_FAILED;
3200 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3201 if (!jni_remoteAddress)
3203 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3204 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3205 ca_mutex_unlock(g_gattObjectMutex);
3206 return CA_STATUS_FAILED;
3209 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3212 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3213 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3214 ca_mutex_unlock(g_gattObjectMutex);
3215 return CA_STATUS_FAILED;
3218 if (!strcmp(setAddress, remoteAddress))
3220 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3221 (*env)->DeleteGlobalRef(env, jarrayObj);
3223 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3224 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3226 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3228 OIC_LOG(ERROR, TAG, "List removal failed.");
3229 ca_mutex_unlock(g_gattObjectMutex);
3230 return CA_STATUS_FAILED;
3232 ca_mutex_unlock(g_gattObjectMutex);
3233 return CA_STATUS_OK;
3235 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3236 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3239 ca_mutex_unlock(g_gattObjectMutex);
3240 OIC_LOG(DEBUG, TAG, "there are no target object");
3241 return CA_STATUS_OK;
3244 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3246 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3247 VERIFY_NON_NULL(addr, TAG, "addr is null");
3248 VERIFY_NON_NULL(env, TAG, "env is null");
3250 ca_mutex_lock(g_gattObjectMutex);
3251 if (!g_gattObjectList)
3253 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3254 ca_mutex_unlock(g_gattObjectMutex);
3255 return CA_STATUS_OK;
3258 uint32_t length = u_arraylist_length(g_gattObjectList);
3259 for (uint32_t index = 0; index < length; index++)
3261 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3264 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3265 ca_mutex_unlock(g_gattObjectMutex);
3266 return CA_STATUS_FAILED;
3269 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3270 if (!jni_setAddress)
3272 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3273 ca_mutex_unlock(g_gattObjectMutex);
3274 return CA_STATUS_FAILED;
3277 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3280 OIC_LOG(ERROR, TAG, "setAddress is null");
3281 ca_mutex_unlock(g_gattObjectMutex);
3282 return CA_STATUS_FAILED;
3285 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3288 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3289 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3290 ca_mutex_unlock(g_gattObjectMutex);
3291 return CA_STATUS_FAILED;
3294 if (!strcmp(setAddress, remoteAddress))
3296 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3297 (*env)->DeleteGlobalRef(env, jarrayObj);
3299 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3300 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3301 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3303 OIC_LOG(ERROR, TAG, "List removal failed.");
3304 ca_mutex_unlock(g_gattObjectMutex);
3305 return CA_STATUS_FAILED;
3307 ca_mutex_unlock(g_gattObjectMutex);
3308 return CA_STATUS_OK;
3310 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3311 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3314 ca_mutex_unlock(g_gattObjectMutex);
3315 OIC_LOG(DEBUG, TAG, "there are no target object");
3316 return CA_STATUS_FAILED;
3319 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3321 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3323 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3324 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3326 // get Bluetooth Address
3327 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3328 if (!jni_btTargetAddress)
3330 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3334 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3337 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3341 // get method ID of getDevice()
3342 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3343 "getDevice", METHODID_BT_DEVICE);
3344 if (!jni_mid_getDevice)
3346 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3347 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3351 ca_mutex_lock(g_gattObjectMutex);
3353 size_t length = u_arraylist_length(g_gattObjectList);
3354 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3355 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3357 for (size_t index = 0; index < length; index++)
3359 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3362 ca_mutex_unlock(g_gattObjectMutex);
3363 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3364 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3368 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3369 if (!jni_obj_device)
3371 ca_mutex_unlock(g_gattObjectMutex);
3372 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3373 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3377 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3380 ca_mutex_unlock(g_gattObjectMutex);
3381 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3382 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3386 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3389 ca_mutex_unlock(g_gattObjectMutex);
3390 OIC_LOG(ERROR, TAG, "btAddress is not available");
3391 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3395 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3396 if (!strcmp(targetAddress, btAddress))
3398 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3401 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3404 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3406 ca_mutex_unlock(g_gattObjectMutex);
3407 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3408 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3409 (*env)->DeleteLocalRef(env, jni_btAddress);
3410 (*env)->DeleteLocalRef(env, jni_obj_device);
3411 return jni_LEAddress;
3413 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3414 (*env)->DeleteLocalRef(env, jni_btAddress);
3415 (*env)->DeleteLocalRef(env, jni_obj_device);
3417 ca_mutex_unlock(g_gattObjectMutex);
3419 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3420 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3428 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3429 uint16_t target_state)
3431 VERIFY_NON_NULL(address, TAG, "address is null");
3432 VERIFY_NON_NULL(address, TAG, "state_type is null");
3433 VERIFY_NON_NULL(address, TAG, "target_state is null");
3435 if (!g_deviceStateList)
3437 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3438 return CA_STATUS_FAILED;
3441 ca_mutex_lock(g_deviceStateListMutex);
3443 if (CALEClientIsDeviceInList(address))
3445 CALEState_t* curState = CALEClientGetStateInfo(address);
3448 OIC_LOG(ERROR, TAG, "curState is null");
3449 ca_mutex_unlock(g_deviceStateListMutex);
3450 return CA_STATUS_FAILED;
3455 case CA_LE_CONNECTION_STATE:
3456 curState->connectedState = target_state;
3458 case CA_LE_SEND_STATE:
3459 curState->sendState = target_state;
3464 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3465 curState->address, curState->connectedState, curState->sendState,
3466 curState->autoConnectFlag);
3468 else /** state is added newly **/
3470 if (strlen(address) > CA_MACADDR_SIZE)
3472 OIC_LOG(ERROR, TAG, "address is not proper");
3473 ca_mutex_unlock(g_deviceStateListMutex);
3474 return CA_STATUS_INVALID_PARAM;
3477 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3480 OIC_LOG(ERROR, TAG, "out of memory");
3481 ca_mutex_unlock(g_deviceStateListMutex);
3482 return CA_MEMORY_ALLOC_FAILED;
3485 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3489 case CA_LE_CONNECTION_STATE:
3490 newstate->connectedState = target_state;
3491 newstate->sendState = STATE_SEND_NONE;
3493 case CA_LE_SEND_STATE:
3494 newstate->connectedState = STATE_DISCONNECTED;
3495 newstate->sendState = target_state;
3500 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3501 "conn : %d, send : %d, ACFlag : %d",
3502 newstate->address, newstate->connectedState, newstate->sendState,
3503 newstate->autoConnectFlag);
3504 u_arraylist_add(g_deviceStateList, newstate); // update new state
3506 ca_mutex_unlock(g_deviceStateListMutex);
3508 return CA_STATUS_OK;
3511 bool CALEClientIsDeviceInList(const char* remoteAddress)
3513 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3515 if (!g_deviceStateList)
3517 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3521 uint32_t length = u_arraylist_length(g_deviceStateList);
3522 for (uint32_t index = 0; index < length; index++)
3524 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3527 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3531 if (!strcmp(remoteAddress, state->address))
3533 OIC_LOG(DEBUG, TAG, "the device is already set");
3542 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3546 CAResult_t CALEClientRemoveAllDeviceState()
3548 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3550 ca_mutex_lock(g_deviceStateListMutex);
3551 if (!g_deviceStateList)
3553 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3554 ca_mutex_unlock(g_deviceStateListMutex);
3555 return CA_STATUS_FAILED;
3558 uint32_t length = u_arraylist_length(g_deviceStateList);
3559 for (uint32_t index = 0; index < length; index++)
3561 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3564 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3570 OICFree(g_deviceStateList);
3571 g_deviceStateList = NULL;
3572 ca_mutex_unlock(g_deviceStateListMutex);
3574 return CA_STATUS_OK;
3577 CAResult_t CALEClientResetDeviceStateForAll()
3579 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3581 ca_mutex_lock(g_deviceStateListMutex);
3582 if (!g_deviceStateList)
3584 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3585 ca_mutex_unlock(g_deviceStateListMutex);
3586 return CA_STATUS_FAILED;
3589 size_t length = u_arraylist_length(g_deviceStateList);
3590 for (size_t index = 0; index < length; index++)
3592 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3595 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3599 // autoConnectFlag value will be not changed,
3600 // since it has reset only termination case.
3601 state->connectedState = STATE_DISCONNECTED;
3602 state->sendState = STATE_SEND_NONE;
3604 ca_mutex_unlock(g_deviceStateListMutex);
3606 return CA_STATUS_OK;
3609 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3611 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3612 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3614 if (!g_deviceStateList)
3616 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3617 return CA_STATUS_FAILED;
3620 uint32_t length = u_arraylist_length(g_deviceStateList);
3621 for (uint32_t index = 0; index < length; index++)
3623 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3626 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3630 if (!strcmp(state->address, remoteAddress))
3632 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3634 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3636 if (NULL == targetState)
3638 OIC_LOG(ERROR, TAG, "List removal failed.");
3639 return CA_STATUS_FAILED;
3642 OICFree(targetState);
3643 return CA_STATUS_OK;
3647 return CA_STATUS_OK;
3650 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3652 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3654 if (!g_deviceStateList)
3656 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3660 uint32_t length = u_arraylist_length(g_deviceStateList);
3661 OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
3662 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3664 for (uint32_t index = 0; index < length; index++)
3666 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3669 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3673 OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
3675 if (!strcmp(state->address, remoteAddress))
3677 OIC_LOG(DEBUG, TAG, "found state");
3682 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
3686 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3687 uint16_t target_state)
3689 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3690 state_type, target_state);
3691 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3693 ca_mutex_lock(g_deviceStateListMutex);
3694 if (!g_deviceStateList)
3696 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3697 ca_mutex_unlock(g_deviceStateListMutex);
3701 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3704 OIC_LOG(ERROR, TAG, "state is null");
3705 ca_mutex_unlock(g_deviceStateListMutex);
3709 uint16_t curValue = 0;
3712 case CA_LE_CONNECTION_STATE:
3713 curValue = state->connectedState;
3715 case CA_LE_SEND_STATE:
3716 curValue = state->sendState;
3722 if (target_state == curValue)
3724 ca_mutex_unlock(g_deviceStateListMutex);
3729 ca_mutex_unlock(g_deviceStateListMutex);
3733 ca_mutex_unlock(g_deviceStateListMutex);
3737 void CALEClientCreateDeviceList()
3739 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3741 // create new object array
3742 if (!g_gattObjectList)
3744 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3746 g_gattObjectList = u_arraylist_create();
3749 if (!g_deviceStateList)
3751 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3753 g_deviceStateList = u_arraylist_create();
3758 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3760 g_deviceList = u_arraylist_create();
3765 * Check Sent Count for remove g_sendBuffer
3767 void CALEClientUpdateSendCnt(JNIEnv *env)
3769 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3771 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3773 ca_mutex_lock(g_threadMutex);
3777 if (g_targetCnt <= g_currentSentCnt)
3780 g_currentSentCnt = 0;
3784 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3785 g_sendBuffer = NULL;
3787 // notity the thread
3788 ca_cond_signal(g_threadCond);
3790 CALEClientSetSendFinishFlag(true);
3791 OIC_LOG(DEBUG, TAG, "set signal for send data");
3794 ca_mutex_unlock(g_threadMutex);
3797 CAResult_t CALEClientInitGattMutexVaraibles()
3799 if (NULL == g_bleReqRespClientCbMutex)
3801 g_bleReqRespClientCbMutex = ca_mutex_new();
3802 if (NULL == g_bleReqRespClientCbMutex)
3804 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3805 return CA_STATUS_FAILED;
3809 if (NULL == g_bleServerBDAddressMutex)
3811 g_bleServerBDAddressMutex = ca_mutex_new();
3812 if (NULL == g_bleServerBDAddressMutex)
3814 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3815 return CA_STATUS_FAILED;
3819 if (NULL == g_threadMutex)
3821 g_threadMutex = ca_mutex_new();
3822 if (NULL == g_threadMutex)
3824 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3825 return CA_STATUS_FAILED;
3829 if (NULL == g_threadSendMutex)
3831 g_threadSendMutex = ca_mutex_new();
3832 if (NULL == g_threadSendMutex)
3834 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3835 return CA_STATUS_FAILED;
3839 if (NULL == g_deviceListMutex)
3841 g_deviceListMutex = ca_mutex_new();
3842 if (NULL == g_deviceListMutex)
3844 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3845 return CA_STATUS_FAILED;
3849 if (NULL == g_gattObjectMutex)
3851 g_gattObjectMutex = ca_mutex_new();
3852 if (NULL == g_gattObjectMutex)
3854 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3855 return CA_STATUS_FAILED;
3859 if (NULL == g_deviceStateListMutex)
3861 g_deviceStateListMutex = ca_mutex_new();
3862 if (NULL == g_deviceStateListMutex)
3864 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3865 return CA_STATUS_FAILED;
3869 if (NULL == g_SendFinishMutex)
3871 g_SendFinishMutex = ca_mutex_new();
3872 if (NULL == g_SendFinishMutex)
3874 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3875 return CA_STATUS_FAILED;
3879 if (NULL == g_threadWriteCharacteristicMutex)
3881 g_threadWriteCharacteristicMutex = ca_mutex_new();
3882 if (NULL == g_threadWriteCharacteristicMutex)
3884 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3885 return CA_STATUS_FAILED;
3889 if (NULL == g_deviceScanRetryDelayMutex)
3891 g_deviceScanRetryDelayMutex = ca_mutex_new();
3892 if (NULL == g_deviceScanRetryDelayMutex)
3894 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3895 return CA_STATUS_FAILED;
3899 if (NULL == g_threadSendStateMutex)
3901 g_threadSendStateMutex = ca_mutex_new();
3902 if (NULL == g_threadSendStateMutex)
3904 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3905 return CA_STATUS_FAILED;
3909 if (NULL == g_threadScanIntervalMutex)
3911 g_threadScanIntervalMutex = ca_mutex_new();
3912 if (NULL == g_threadScanIntervalMutex)
3914 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3915 return CA_STATUS_FAILED;
3919 return CA_STATUS_OK;
3922 void CALEClientTerminateGattMutexVariables()
3924 ca_mutex_free(g_bleReqRespClientCbMutex);
3925 g_bleReqRespClientCbMutex = NULL;
3927 ca_mutex_free(g_bleServerBDAddressMutex);
3928 g_bleServerBDAddressMutex = NULL;
3930 ca_mutex_free(g_threadMutex);
3931 g_threadMutex = NULL;
3933 ca_mutex_free(g_threadSendMutex);
3934 g_threadSendMutex = NULL;
3936 ca_mutex_free(g_deviceListMutex);
3937 g_deviceListMutex = NULL;
3939 ca_mutex_free(g_SendFinishMutex);
3940 g_SendFinishMutex = NULL;
3942 ca_mutex_free(g_threadWriteCharacteristicMutex);
3943 g_threadWriteCharacteristicMutex = NULL;
3945 ca_mutex_free(g_deviceScanRetryDelayMutex);
3946 g_deviceScanRetryDelayMutex = NULL;
3948 ca_mutex_free(g_threadSendStateMutex);
3949 g_threadSendStateMutex = NULL;
3951 ca_mutex_free(g_threadScanIntervalMutex);
3952 g_threadScanIntervalMutex = NULL;
3955 void CALEClientSetSendFinishFlag(bool flag)
3957 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3959 ca_mutex_lock(g_SendFinishMutex);
3960 g_isFinishedSendData = flag;
3961 ca_mutex_unlock(g_SendFinishMutex);
3968 CAResult_t CAStartLEGattClient()
3970 // init mutex for send logic
3971 if (!g_deviceDescCond)
3973 g_deviceDescCond = ca_cond_new();
3978 g_threadCond = ca_cond_new();
3981 if (!g_threadWriteCharacteristicCond)
3983 g_threadWriteCharacteristicCond = ca_cond_new();
3986 CAResult_t ret = CALEClientStartScanWithInterval();
3987 if (CA_STATUS_OK != ret)
3989 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
3993 g_isStartedLEClient = true;
3994 return CA_STATUS_OK;
3997 void CAStopLEGattClient()
3999 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
4003 OIC_LOG(ERROR, TAG, "g_jvm is null");
4007 bool isAttached = false;
4009 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
4012 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
4013 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
4017 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
4023 CAResult_t ret = CALEClientDisconnectAll(env);
4024 if (CA_STATUS_OK != ret)
4026 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
4029 CALEClientStopScanWithInterval();
4031 ca_mutex_lock(g_threadMutex);
4032 OIC_LOG(DEBUG, TAG, "signal - connection cond");
4033 ca_cond_signal(g_threadCond);
4034 CALEClientSetSendFinishFlag(true);
4035 ca_mutex_unlock(g_threadMutex);
4037 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4038 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4039 ca_cond_signal(g_threadWriteCharacteristicCond);
4040 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4042 ca_mutex_lock(g_deviceScanRetryDelayMutex);
4043 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4044 ca_cond_signal(g_deviceScanRetryDelayCond);
4045 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
4047 ca_mutex_lock(g_threadScanIntervalMutex);
4048 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4049 ca_cond_signal(g_threadScanIntervalCond);
4050 ca_mutex_unlock(g_threadScanIntervalMutex);
4052 ca_cond_free(g_deviceDescCond);
4053 ca_cond_free(g_threadCond);
4054 ca_cond_free(g_threadWriteCharacteristicCond);
4055 ca_cond_free(g_deviceScanRetryDelayCond);
4056 ca_cond_free(g_threadScanIntervalCond);
4058 g_deviceDescCond = NULL;
4059 g_threadCond = NULL;
4060 g_threadWriteCharacteristicCond = NULL;
4061 g_deviceScanRetryDelayCond = NULL;
4062 g_threadScanIntervalCond = NULL;
4066 (*g_jvm)->DetachCurrentThread(g_jvm);
4071 CAResult_t CAInitializeLEGattClient()
4073 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4074 CALEClientInitialize();
4075 return CA_STATUS_OK;
4078 void CATerminateLEGattClient()
4080 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4081 CAStopLEGattClient();
4082 CALEClientTerminate();
4085 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4086 uint32_t dataLen, CALETransferType_t type,
4089 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4090 VERIFY_NON_NULL(data, TAG, "data is null");
4091 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4093 if (LE_UNICAST != type || position < 0)
4095 OIC_LOG(ERROR, TAG, "this request is not unicast");
4096 return CA_STATUS_INVALID_PARAM;
4099 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4102 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4104 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4105 VERIFY_NON_NULL(data, TAG, "data is null");
4107 return CALEClientSendMulticastMessage(data, dataLen);
4110 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4112 ca_mutex_lock(g_bleReqRespClientCbMutex);
4113 g_CABLEClientDataReceivedCallback = callback;
4114 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4117 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4119 g_threadPoolHandle = handle;
4122 CAResult_t CAGetLEAddress(char **local_address)
4124 VERIFY_NON_NULL(local_address, TAG, "local_address");
4125 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4126 return CA_NOT_SUPPORTED;
4129 JNIEXPORT void JNICALL
4130 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4133 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4134 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4135 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4136 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4138 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4141 JNIEXPORT void JNICALL
4142 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4145 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4146 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4147 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4148 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4150 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4153 JNIEXPORT void JNICALL
4154 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4157 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4158 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4159 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4161 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4162 if (CA_STATUS_OK != res)
4164 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4168 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4170 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4172 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4173 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4175 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4176 "getDevice", METHODID_BT_DEVICE);
4177 if (!jni_mid_getDevice)
4179 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4183 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4184 if (!jni_obj_device)
4186 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4190 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4193 OIC_LOG(ERROR, TAG, "jni_address is null");
4197 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4202 * Class: org_iotivity_ca_jar_caleinterface
4203 * Method: CALeGattConnectionStateChangeCallback
4204 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4206 JNIEXPORT void JNICALL
4207 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4213 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4215 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4216 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4217 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4219 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4221 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4224 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4228 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4231 OIC_LOG(ERROR, TAG, "address is null");
4234 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4237 if (state_connected == newstate)
4239 OIC_LOG(DEBUG, TAG, "LE is connected");
4240 if (GATT_SUCCESS == status)
4242 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_CONNECTED);
4243 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4244 if (CA_STATUS_OK != res)
4246 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4250 res = CALEClientAddGattobjToList(env, gatt);
4251 if (CA_STATUS_OK != res)
4253 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4257 res = CALEClientDiscoverServices(env, gatt);
4258 if (CA_STATUS_OK != res)
4260 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4266 OIC_LOG(INFO, TAG, "unknown status");
4267 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4270 else // STATE_DISCONNECTED == newstate
4272 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4274 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_DISCONNECTED);
4275 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4276 if (CA_STATUS_OK != res)
4278 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4282 res = CALEClientGattClose(env, gatt);
4283 if (CA_STATUS_OK != res)
4285 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4288 if (CALECheckConnectionStateValue(status))
4290 // this state is unexpected reason to disconnect
4291 // if the reason is suitable, connection logic of the device will be destroyed.
4292 OIC_LOG(INFO, TAG, "connection logic destroy");
4297 // other reason except for gatt_success is expected to running
4298 // background connection in BT platform.
4299 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4300 CALEClientUpdateSendCnt(env);
4306 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4307 g_sendBuffer = NULL;
4314 CALEClientSendFinish(env, gatt);
4319 * Class: org_iotivity_ca_jar_caleinterface
4320 * Method: CALeGattServicesDiscoveredCallback
4321 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4323 JNIEXPORT void JNICALL
4324 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4329 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4330 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4331 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4332 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4334 if (GATT_SUCCESS != status) // discovery error
4336 CALEClientSendFinish(env, gatt);
4340 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4343 CALEClientSendFinish(env, gatt);
4347 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4350 CALEClientSendFinish(env, gatt);
4354 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4357 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4361 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4362 if (!jni_obj_GattCharacteristic)
4364 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4368 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4369 jni_obj_GattCharacteristic);
4370 if (CA_STATUS_OK != res)
4372 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4376 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4377 if (CA_STATUS_OK != res)
4379 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4381 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
4382 if (CA_STATUS_OK != res)
4384 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4388 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4389 STATE_SERVICE_CONNECTED);
4390 if (CA_STATUS_OK != res)
4392 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4398 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4399 if (CA_STATUS_OK != res)
4401 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4408 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
4409 if (CA_STATUS_OK != res)
4411 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4416 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4417 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4422 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4423 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4424 CALEClientSendFinish(env, gatt);
4429 * Class: org_iotivity_ca_jar_caleinterface
4430 * Method: CALeGattCharacteristicWritjclasseCallback
4431 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4433 JNIEXPORT void JNICALL
4434 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4435 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4437 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4438 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4439 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4440 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4442 // send success & signal
4443 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4449 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4455 if (GATT_SUCCESS != status) // error case
4457 OIC_LOG(ERROR, TAG, "send failure");
4460 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4461 if (CA_STATUS_OK != res)
4463 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4464 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4465 g_isSignalSetFlag = true;
4466 ca_cond_signal(g_threadWriteCharacteristicCond);
4467 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4469 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4471 if (CA_STATUS_OK != res)
4473 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4476 if (g_clientErrorCallback)
4478 jint length = (*env)->GetArrayLength(env, data);
4479 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4482 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4488 OIC_LOG(DEBUG, TAG, "send success");
4489 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4490 STATE_SEND_SUCCESS);
4491 if (CA_STATUS_OK != res)
4493 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4496 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4497 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4498 g_isSignalSetFlag = true;
4499 ca_cond_signal(g_threadWriteCharacteristicCond);
4500 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4502 CALEClientUpdateSendCnt(env);
4505 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4511 CALEClientSendFinish(env, gatt);
4516 * Class: org_iotivity_ca_jar_caleinterface
4517 * Method: CALeGattCharacteristicChangedCallback
4518 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4520 JNIEXPORT void JNICALL
4521 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4522 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4524 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4525 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4526 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4527 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4528 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4530 // get Byte Array and convert to uint8_t*
4531 jint length = (*env)->GetArrayLength(env, data);
4534 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4536 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4537 jni_byte_responseData);
4539 uint8_t* receivedData = OICMalloc(length);
4542 OIC_LOG(ERROR, TAG, "receivedData is null");
4546 memcpy(receivedData, jni_byte_responseData, length);
4547 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4549 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4552 OIC_LOG(ERROR, TAG, "jni_address is null");
4553 OICFree(receivedData);
4557 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4560 OIC_LOG(ERROR, TAG, "address is null");
4561 OICFree(receivedData);
4565 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4566 receivedData, length);
4568 uint32_t sentLength = 0;
4569 ca_mutex_lock(g_bleServerBDAddressMutex);
4570 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4571 ca_mutex_unlock(g_bleServerBDAddressMutex);
4573 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4577 * Class: org_iotivity_ca_jar_caleinterface
4578 * Method: CALeGattDescriptorWriteCallback
4579 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4581 JNIEXPORT void JNICALL
4582 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4586 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4587 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4588 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4589 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4591 if (GATT_SUCCESS != status) // error
4596 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4602 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4608 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4609 STATE_SERVICE_CONNECTED);
4610 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4611 if (CA_STATUS_OK != res)
4613 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4619 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4620 if (CA_STATUS_OK != res)
4622 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4631 CALEClientSendFinish(env, gatt);