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:
138 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount)
140 OIC_LOG_V(DEBUG, TAG, "CALEClientSetScanInterval : %d -> %d",
141 g_scanIntervalTime, intervalTime);
143 // previous time should be stored.
144 if (0 < workingCount)
146 g_scanIntervalTimePrev = g_scanIntervalTime;
148 g_scanIntervalTime = intervalTime;
149 g_intervalCount = workingCount;
152 void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount)
154 // restart scan with interval
155 CALEClientSetScanInterval(intervalTime, workingCount);
156 ca_cond_signal(g_threadScanIntervalCond);
159 static void CALEScanThread(void* object)
163 bool isAttached = false;
165 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
168 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
169 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
173 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
179 ca_mutex_lock(g_threadScanIntervalMutex);
180 while(g_isWorkingScanThread)
182 OIC_LOG(DEBUG, TAG, "scan waiting time out");
183 if (BLE_SCAN_ENABLE == g_scanningStep)
186 CAResult_t ret = CALEClientStopScan();
187 if (CA_STATUS_OK != ret)
189 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
195 CAResult_t ret = CALEClientStartScan();
196 if (CA_STATUS_OK != ret)
198 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
202 OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
203 if (CA_WAIT_SUCCESS == ca_cond_wait_for(g_threadScanIntervalCond,
204 g_threadScanIntervalMutex,
205 g_scanIntervalTime * MICROSECS_PER_SEC))
207 // called signal scan thread will be terminated
208 OIC_LOG(DEBUG, TAG, "signal scanInterval waiting");
209 g_scanningStep = BLE_SCAN_DISABLE;
213 if (BLE_SCAN_ENABLE == g_scanningStep)
215 if (g_intervalCount > 0)
217 if (g_intervalCount == 1)
219 OIC_LOG(DEBUG, TAG, "reset default time");
220 CALEClientSetScanInterval(g_scanIntervalTimePrev, 0);
223 OIC_LOG_V(DEBUG, TAG, "interval count : %d", g_intervalCount);
225 g_scanningStep = BLE_SCAN_DISABLE;
229 g_scanningStep = BLE_SCAN_ENABLE;
233 ca_mutex_unlock(g_threadScanIntervalMutex);
237 (*g_jvm)->DetachCurrentThread(g_jvm);
241 CAResult_t CALEClientStartScanWithInterval()
243 OIC_LOG(DEBUG, TAG, "IN - CALEClientStartScanWithInterval");
245 if (g_isWorkingScanThread)
247 OIC_LOG(DEBUG, TAG, "scan interval logic already running");
251 // initialize scan flags
252 g_scanningStep = BLE_SCAN_DISABLE;
253 g_isWorkingScanThread = true;
255 g_scanIntervalTime = g_scanIntervalTimePrev;
257 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
258 CALEScanThread, NULL))
260 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
261 g_isWorkingScanThread = false;
262 return CA_STATUS_FAILED;
265 OIC_LOG(DEBUG, TAG, "OUT - CALEClientStartScanWithInterval");
269 void CALEClientStopScanWithInterval()
271 g_isWorkingScanThread = false;
272 ca_cond_signal(g_threadScanIntervalCond);
276 void CALEClientJniInit()
278 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
279 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
282 void CALEClientJNISetContext()
284 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
285 g_context = (jobject) CANativeJNIGetContext();
288 CAResult_t CALECreateJniInterfaceObject()
290 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
294 OIC_LOG(ERROR, TAG, "g_context is null");
295 return CA_STATUS_FAILED;
300 OIC_LOG(ERROR, TAG, "g_jvm is null");
301 return CA_STATUS_FAILED;
304 bool isAttached = false;
306 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
309 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
310 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
314 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
315 return CA_STATUS_FAILED;
320 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
321 "getApplicationContext",
322 "()Landroid/content/Context;");
324 if (!mid_getApplicationContext)
326 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
327 return CA_STATUS_FAILED;
330 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
331 mid_getApplicationContext);
332 if (!jApplicationContext)
334 OIC_LOG(ERROR, TAG, "Could not get application context");
335 return CA_STATUS_FAILED;
338 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
339 if (!jni_LEInterface)
341 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
345 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
346 "(Landroid/content/Context;)V");
347 if (!LeInterfaceConstructorMethod)
349 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
353 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
354 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
358 (*g_jvm)->DetachCurrentThread(g_jvm);
367 (*g_jvm)->DetachCurrentThread(g_jvm);
370 return CA_STATUS_FAILED;
373 CAResult_t CALEClientInitialize()
375 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
381 OIC_LOG(ERROR, TAG, "g_jvm is null");
382 return CA_STATUS_FAILED;
385 bool isAttached = false;
387 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
390 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
391 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
395 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
396 return CA_STATUS_FAILED;
401 CAResult_t ret = CALECheckPlatformVersion(env, 18);
402 if (CA_STATUS_OK != ret)
404 OIC_LOG(ERROR, TAG, "it is not supported");
408 (*g_jvm)->DetachCurrentThread(g_jvm);
414 ret = CALEClientInitGattMutexVaraibles();
415 if (CA_STATUS_OK != ret)
417 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
418 CALEClientTerminateGattMutexVariables();
422 (*g_jvm)->DetachCurrentThread(g_jvm);
428 g_deviceDescCond = ca_cond_new();
430 // init mutex for send logic
431 g_threadCond = ca_cond_new();
432 g_threadWriteCharacteristicCond = ca_cond_new();
433 g_deviceScanRetryDelayCond = ca_cond_new();
434 g_threadScanIntervalCond = ca_cond_new();
436 CALEClientCreateDeviceList();
437 CALEClientJNISetContext();
439 ret = CALEClientCreateUUIDList();
440 if (CA_STATUS_OK != ret)
442 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
446 (*g_jvm)->DetachCurrentThread(g_jvm);
452 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
453 if (CA_STATUS_OK != ret)
455 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
459 (*g_jvm)->DetachCurrentThread(g_jvm);
464 g_isStartedLEClient = true;
468 (*g_jvm)->DetachCurrentThread(g_jvm);
474 void CALEClientTerminate()
476 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
480 OIC_LOG(ERROR, TAG, "g_jvm is null");
484 bool isAttached = false;
486 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
489 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
490 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
494 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
500 if (g_leScanCallback)
502 (*env)->DeleteGlobalRef(env, g_leScanCallback);
503 g_leScanCallback = NULL;
506 if (g_leGattCallback)
508 (*env)->DeleteGlobalRef(env, g_leGattCallback);
509 g_leGattCallback = NULL;
514 (*env)->DeleteGlobalRef(env, g_sendBuffer);
520 (*env)->DeleteGlobalRef(env, g_uuidList);
524 CAResult_t ret = CALEClientRemoveAllDeviceState();
525 if (CA_STATUS_OK != ret)
527 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
530 ret = CALEClientRemoveAllScanDevices(env);
531 if (CA_STATUS_OK != ret)
533 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
536 ret = CALEClientRemoveAllGattObjs(env);
537 if (CA_STATUS_OK != ret)
539 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
542 CALEClientSetSendFinishFlag(true);
544 CALEClientTerminateGattMutexVariables();
545 CALEClientDestroyJniInterface();
547 ca_cond_free(g_deviceDescCond);
548 ca_cond_free(g_threadCond);
549 ca_cond_free(g_threadWriteCharacteristicCond);
550 ca_cond_free(g_deviceScanRetryDelayCond);
551 ca_cond_free(g_threadScanIntervalCond);
553 g_deviceDescCond = NULL;
555 g_threadWriteCharacteristicCond = NULL;
556 g_deviceScanRetryDelayCond = NULL;
557 g_threadScanIntervalCond = NULL;
559 g_isSignalSetFlag = false;
562 CALEClientStopScanWithInterval();
566 (*g_jvm)->DetachCurrentThread(g_jvm);
570 CAResult_t CALEClientDestroyJniInterface()
572 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
576 OIC_LOG(ERROR, TAG, "g_jvm is null");
577 return CA_STATUS_FAILED;
580 bool isAttached = false;
582 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
585 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
586 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
590 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
591 return CA_STATUS_FAILED;
596 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
597 if (!jni_LeInterface)
599 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
603 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
604 "destroyLeInterface",
606 if (!jni_InterfaceDestroyMethod)
608 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
612 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
614 if ((*env)->ExceptionCheck(env))
616 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
617 (*env)->ExceptionDescribe(env);
618 (*env)->ExceptionClear(env);
622 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
626 (*g_jvm)->DetachCurrentThread(g_jvm);
635 (*g_jvm)->DetachCurrentThread(g_jvm);
638 return CA_STATUS_FAILED;
641 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
643 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
644 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
648 CAResult_t res = CALEClientDisconnect(env, gatt);
649 if (CA_STATUS_OK != res)
651 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
654 CALEClientUpdateSendCnt(env);
657 CAResult_t CALEClientSendUnicastMessage(const char* address,
659 const uint32_t dataLen)
661 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
662 VERIFY_NON_NULL(address, TAG, "address is null");
663 VERIFY_NON_NULL(data, TAG, "data is null");
665 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
668 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
669 const uint32_t dataLen)
671 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
672 VERIFY_NON_NULL(data, TAG, "data is null");
676 OIC_LOG(ERROR, TAG, "g_jvm is null");
677 return CA_STATUS_FAILED;
680 bool isAttached = false;
682 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
685 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
686 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
690 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
691 return CA_STATUS_FAILED;
696 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
697 if (CA_STATUS_OK != ret)
699 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
704 (*g_jvm)->DetachCurrentThread(g_jvm);
710 CAResult_t CALEClientStartUnicastServer(const char* address)
715 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
717 return CA_NOT_SUPPORTED;
720 CAResult_t CALEClientStartMulticastServer()
722 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
724 return CA_NOT_SUPPORTED;
727 void CALEClientStopUnicastServer()
729 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
732 void CALEClientStopMulticastServer()
734 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
737 void CALEClientSetCallback(CAPacketReceiveCallback callback)
739 g_packetReceiveCallback = callback;
742 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
744 g_clientErrorCallback = callback;
747 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
749 VERIFY_NON_NULL(env, TAG, "env");
753 OIC_LOG(ERROR, TAG, "g_deviceList is not available");
754 return CA_STATUS_FAILED;
757 if (0 == u_arraylist_length(g_deviceList) // multicast
758 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
760 // Wait for LE peripherals to be discovered.
762 // Number of times to wait for discovery to complete.
763 static size_t const RETRIES = 5;
765 static uint64_t const TIMEOUT =
766 2 * MICROSECS_PER_SEC; // Microseconds
768 // set scan interval and start scan
769 CALERestartScanWithInterval(WAIT_TIME_SCANNED_CHECKING, 1);
771 bool devicesDiscovered = false;
772 for (size_t i = 0; i < RETRIES; ++i)
774 OIC_LOG(DEBUG, TAG, "waiting for target device");
775 if (ca_cond_wait_for(g_deviceDescCond,
777 TIMEOUT) == CA_WAIT_SUCCESS)
779 ca_mutex_lock(g_deviceListMutex);
780 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
781 ca_mutex_unlock(g_deviceListMutex);
783 if (0 < scannedDeviceLen)
785 if (!address // multicast
786 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
788 devicesDiscovered = true;
795 OIC_LOG(INFO, TAG, "waiting..");
797 ca_mutex_lock(g_deviceScanRetryDelayMutex);
798 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
799 g_deviceScanRetryDelayMutex,
800 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
802 OIC_LOG(INFO, TAG, "finish to waiting for target device");
803 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
806 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
809 // checking whether a target device is found while waiting for time-out.
810 if (CALEClientIsDeviceInScanDeviceList(env, address))
812 devicesDiscovered = true;
821 // reset scan interval time after checking scanned devices
822 CALERestartScanWithInterval(g_scanIntervalTimePrev, 0);
824 // time out for scanning devices
825 if (!devicesDiscovered)
827 return CA_STATUS_FAILED;
832 OIC_LOG(DEBUG, TAG, "there is a target device in the scanned devices");
839 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
840 const uint32_t dataLen)
842 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
844 VERIFY_NON_NULL(address, TAG, "address is null");
845 VERIFY_NON_NULL(data, TAG, "data is null");
849 OIC_LOG(ERROR, TAG, "g_jvm is null");
850 return CA_STATUS_FAILED;
853 bool isAttached = false;
855 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
858 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
859 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
862 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
863 return CA_STATUS_FAILED;
868 ca_mutex_lock(g_threadSendMutex);
870 CALEClientSetSendFinishFlag(false);
872 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
873 if (CA_STATUS_OK != ret)
875 OIC_LOG(INFO, TAG, "there is no scanned device");
879 if (g_context && g_deviceList)
881 uint32_t length = u_arraylist_length(g_deviceList);
882 for (uint32_t index = 0; index < length; index++)
884 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
887 OIC_LOG(ERROR, TAG, "jarrayObj is null");
891 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
894 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
898 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
901 OIC_LOG(ERROR, TAG, "setAddress is null");
905 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
907 if (!strcmp(setAddress, address))
909 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
910 (*env)->DeleteLocalRef(env, jni_setAddress);
914 (*env)->DeleteGlobalRef(env, g_sendBuffer);
917 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
918 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
919 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
921 // Target device to send message is just one.
924 ret = CALEClientSendData(env, jarrayObj);
925 if (CA_STATUS_OK != ret)
927 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
931 OIC_LOG(INFO, TAG, "wake up");
934 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
935 (*env)->DeleteLocalRef(env, jni_setAddress);
939 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
941 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
942 // if there is no connection state.
943 ca_mutex_lock(g_threadMutex);
944 if (!g_isFinishedSendData)
946 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
947 ca_cond_wait(g_threadCond, g_threadMutex);
948 OIC_LOG(DEBUG, TAG, "the data was sent");
950 ca_mutex_unlock(g_threadMutex);
954 (*g_jvm)->DetachCurrentThread(g_jvm);
957 ca_mutex_unlock(g_threadSendMutex);
958 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
959 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
966 ret = CA_SEND_FAILED;
970 CAResult_t resetRet = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
972 if (CA_STATUS_OK != resetRet)
974 OIC_LOG_V(ERROR, TAG, "CALEClientUpdateDeviceState has failed (%d)", resetRet);
975 ret = CA_SEND_FAILED;
984 (*g_jvm)->DetachCurrentThread(g_jvm);
987 ca_mutex_unlock(g_threadSendMutex);
988 return CA_SEND_FAILED;
991 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
992 const uint32_t dataLen)
994 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
995 VERIFY_NON_NULL(data, TAG, "data is null");
996 VERIFY_NON_NULL(env, TAG, "env is null");
1000 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1001 return CA_STATUS_FAILED;
1004 ca_mutex_lock(g_threadSendMutex);
1006 CALEClientSetSendFinishFlag(false);
1008 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1011 (*env)->DeleteGlobalRef(env, g_sendBuffer);
1012 g_sendBuffer = NULL;
1015 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
1016 if (CA_STATUS_OK != res)
1018 OIC_LOG(INFO, TAG, "there is no scanned device");
1022 uint32_t length = u_arraylist_length(g_deviceList);
1023 g_targetCnt = length;
1025 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
1026 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
1027 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
1029 for (uint32_t index = 0; index < length; index++)
1031 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
1034 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
1038 res = CALEClientSendData(env, jarrayObj);
1039 if (res != CA_STATUS_OK)
1041 OIC_LOG(ERROR, TAG, "BT device - send has failed");
1045 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1047 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1048 ca_mutex_lock(g_threadMutex);
1049 if (!g_isFinishedSendData)
1051 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1052 ca_cond_wait(g_threadCond, g_threadMutex);
1053 OIC_LOG(DEBUG, TAG, "the data was sent");
1055 ca_mutex_unlock(g_threadMutex);
1056 ca_mutex_unlock(g_threadSendMutex);
1057 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1058 return CA_STATUS_OK;
1061 ca_mutex_unlock(g_threadSendMutex);
1062 OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1063 return CA_SEND_FAILED;
1066 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1068 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1069 VERIFY_NON_NULL(device, TAG, "device is null");
1070 VERIFY_NON_NULL(env, TAG, "env is null");
1072 // get BLE address from bluetooth device object.
1073 char* address = NULL;
1074 CALEState_t* state = NULL;
1075 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1078 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1079 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1082 OIC_LOG(ERROR, TAG, "address is not available");
1083 return CA_STATUS_FAILED;
1085 ca_mutex_lock(g_deviceStateListMutex);
1086 state = CALEClientGetStateInfo(address);
1087 ca_mutex_unlock(g_deviceStateListMutex);
1092 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1094 // cancel previous connection request before connection
1095 // if there is gatt object in g_gattObjectList.
1098 jobject gatt = CALEClientGetGattObjInList(env, address);
1101 CAResult_t res = CALEClientDisconnect(env, gatt);
1102 if (CA_STATUS_OK != res)
1104 OIC_LOG(INFO, TAG, "there is no gatt object");
1107 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1110 // connection request
1111 jobject newGatt = CALEClientConnect(env, device,
1113 if (NULL == newGatt)
1115 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1116 return CA_STATUS_FAILED;
1121 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1122 STATE_SERVICE_CONNECTED))
1124 OIC_LOG(INFO, TAG, "GATT has already connected");
1126 jobject gatt = CALEClientGetGattObjInList(env, address);
1129 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1130 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1131 return CA_STATUS_FAILED;
1134 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1135 if (CA_STATUS_OK != ret)
1137 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1138 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1141 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1143 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1146 OIC_LOG(INFO, TAG, "service connecting...");
1148 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1149 STATE_DISCONNECTED))
1151 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1153 // cancel previous connection request before connection
1154 // if there is gatt object in g_gattObjectList.
1157 jobject gatt = CALEClientGetGattObjInList(env, address);
1160 CAResult_t res = CALEClientDisconnect(env, gatt);
1161 if (CA_STATUS_OK != res)
1163 OIC_LOG(INFO, TAG, "there is no gatt object");
1166 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1169 OIC_LOG(DEBUG, TAG, "start to connect LE");
1170 jobject gatt = CALEClientConnect(env, device,
1171 CALEClientGetFlagFromState(env, jni_address,
1172 CA_LE_AUTO_CONNECT_FLAG));
1176 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1177 return CA_STATUS_FAILED;
1182 return CA_STATUS_OK;
1185 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1187 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1188 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1190 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1191 "()Landroid/bluetooth/BluetoothDevice;");
1192 if (!jni_mid_getDevice)
1194 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1198 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1199 if (!jni_obj_device)
1201 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1205 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1208 OIC_LOG(ERROR, TAG, "jni_address is null");
1218 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1221 OIC_LOG(DEBUG, TAG, "Gatt Close");
1222 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1223 VERIFY_NON_NULL(env, TAG, "env is null");
1225 // get BluetoothGatt method
1226 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1227 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1228 if (!jni_mid_closeGatt)
1230 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1231 return CA_STATUS_OK;
1234 // call disconnect gatt method
1235 OIC_LOG(DEBUG, TAG, "request to close GATT");
1236 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1238 if ((*env)->ExceptionCheck(env))
1240 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1241 (*env)->ExceptionDescribe(env);
1242 (*env)->ExceptionClear(env);
1243 return CA_STATUS_FAILED;
1246 return CA_STATUS_OK;
1249 CAResult_t CALEClientStartScan()
1251 if (!g_isStartedLEClient)
1253 OIC_LOG(ERROR, TAG, "LE client is not started");
1254 return CA_STATUS_FAILED;
1259 OIC_LOG(ERROR, TAG, "g_jvm is null");
1260 return CA_STATUS_FAILED;
1263 bool isAttached = false;
1265 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1268 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1270 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1273 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1274 return CA_STATUS_FAILED;
1279 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1281 CAResult_t ret = CA_STATUS_OK;
1282 // scan gatt server with UUID
1283 if (g_leScanCallback && g_uuidList)
1286 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1288 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1290 if (CA_STATUS_OK != ret)
1292 if (CA_ADAPTER_NOT_ENABLED == ret)
1294 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1298 OIC_LOG(ERROR, TAG, "start scan has failed");
1305 (*g_jvm)->DetachCurrentThread(g_jvm);
1311 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1313 VERIFY_NON_NULL(callback, TAG, "callback is null");
1314 VERIFY_NON_NULL(env, TAG, "env is null");
1316 if (!CALEIsEnableBTAdapter(env))
1318 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1319 return CA_ADAPTER_NOT_ENABLED;
1322 // get default bt adapter class
1323 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1324 if (!jni_cid_BTAdapter)
1326 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1327 return CA_STATUS_FAILED;
1330 // get remote bt adapter method
1331 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1332 "getDefaultAdapter",
1333 METHODID_OBJECTNONPARAM);
1334 if (!jni_mid_getDefaultAdapter)
1336 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1337 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1338 return CA_STATUS_FAILED;
1341 // get start le scan method
1342 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1343 "(Landroid/bluetooth/BluetoothAdapter$"
1344 "LeScanCallback;)Z");
1345 if (!jni_mid_startLeScan)
1347 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1348 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1349 return CA_STATUS_FAILED;
1352 // gat bt adapter object
1353 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1354 jni_mid_getDefaultAdapter);
1355 if (!jni_obj_BTAdapter)
1357 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1358 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1359 return CA_STATUS_FAILED;
1362 // call start le scan method
1363 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1364 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1365 jni_mid_startLeScan, callback);
1366 if (!jni_obj_startLeScan)
1368 OIC_LOG(INFO, TAG, "startLeScan has failed");
1372 OIC_LOG(DEBUG, TAG, "LeScan has started");
1375 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1376 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1377 return CA_STATUS_OK;
1380 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1382 VERIFY_NON_NULL(callback, TAG, "callback is null");
1383 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1384 VERIFY_NON_NULL(env, TAG, "env is null");
1386 if (!CALEIsEnableBTAdapter(env))
1388 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1389 return CA_ADAPTER_NOT_ENABLED;
1392 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1393 if (!jni_cid_BTAdapter)
1395 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1396 return CA_STATUS_FAILED;
1399 // get remote bt adapter method
1400 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1401 "getDefaultAdapter",
1402 METHODID_OBJECTNONPARAM);
1403 if (!jni_mid_getDefaultAdapter)
1405 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1406 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1407 return CA_STATUS_FAILED;
1410 // get start le scan method
1411 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1412 "([Ljava/util/UUID;Landroid/bluetooth/"
1413 "BluetoothAdapter$LeScanCallback;)Z");
1414 if (!jni_mid_startLeScan)
1416 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1417 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1418 return CA_STATUS_FAILED;
1421 // get bt adapter object
1422 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1423 jni_mid_getDefaultAdapter);
1424 if (!jni_obj_BTAdapter)
1426 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1427 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1428 return CA_STATUS_FAILED;
1431 // call start le scan method
1432 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1433 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1434 jni_mid_startLeScan, uuids, callback);
1435 if (!jni_obj_startLeScan)
1437 OIC_LOG(INFO, TAG, "startLeScan has failed");
1441 OIC_LOG(DEBUG, TAG, "LeScan has started");
1444 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1445 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1446 return CA_STATUS_OK;
1449 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1451 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1452 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1455 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1458 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1462 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1463 "(Ljava/lang/String;)"
1464 "Ljava/util/UUID;");
1465 if (!jni_mid_fromString)
1467 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1471 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1472 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1476 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1480 return jni_obj_uuid;
1483 CAResult_t CALEClientStopScan()
1487 OIC_LOG(ERROR, TAG, "g_jvm is null");
1488 return CA_STATUS_FAILED;
1491 bool isAttached = false;
1493 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1496 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1497 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1500 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1501 return CA_STATUS_FAILED;
1506 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1507 if (CA_STATUS_OK != ret)
1509 if (CA_ADAPTER_NOT_ENABLED == ret)
1511 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1515 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1521 (*g_jvm)->DetachCurrentThread(g_jvm);
1527 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1529 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1530 VERIFY_NON_NULL(callback, TAG, "callback is null");
1531 VERIFY_NON_NULL(env, TAG, "env is null");
1533 if (!CALEIsEnableBTAdapter(env))
1535 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1536 return CA_ADAPTER_NOT_ENABLED;
1539 // get default bt adapter class
1540 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1541 if (!jni_cid_BTAdapter)
1543 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1544 return CA_STATUS_FAILED;
1547 // get remote bt adapter method
1548 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1549 "getDefaultAdapter",
1550 METHODID_OBJECTNONPARAM);
1551 if (!jni_mid_getDefaultAdapter)
1553 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1554 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1555 return CA_STATUS_FAILED;
1558 // get start le scan method
1559 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1560 "(Landroid/bluetooth/"
1561 "BluetoothAdapter$LeScanCallback;)V");
1562 if (!jni_mid_stopLeScan)
1564 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1565 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1566 return CA_STATUS_FAILED;
1569 // gat bt adapter object
1570 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1571 jni_mid_getDefaultAdapter);
1572 if (!jni_obj_BTAdapter)
1574 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1575 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1576 return CA_STATUS_FAILED;
1579 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1580 // call start le scan method
1581 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1582 if ((*env)->ExceptionCheck(env))
1584 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1585 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1586 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1587 (*env)->ExceptionDescribe(env);
1588 (*env)->ExceptionClear(env);
1589 return CA_STATUS_FAILED;
1592 (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
1593 (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
1594 return CA_STATUS_OK;
1597 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1599 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1600 VERIFY_NON_NULL(env, TAG, "env");
1601 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1603 ca_mutex_lock(g_deviceStateListMutex);
1605 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1608 OIC_LOG(ERROR, TAG, "address is not available");
1609 return CA_STATUS_FAILED;
1612 if (CALEClientIsDeviceInList(address))
1614 CALEState_t* curState = CALEClientGetStateInfo(address);
1617 OIC_LOG(ERROR, TAG, "curState is null");
1618 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1619 ca_mutex_unlock(g_deviceStateListMutex);
1620 return CA_STATUS_FAILED;
1622 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1626 case CA_LE_AUTO_CONNECT_FLAG:
1627 curState->autoConnectFlag = flag;
1629 case CA_LE_DESCRIPTOR_FOUND:
1630 curState->isDescriptorFound = flag;
1637 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1638 ca_mutex_unlock(g_deviceStateListMutex);
1639 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1640 return CA_STATUS_OK;
1643 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1645 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1646 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1647 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1649 ca_mutex_lock(g_deviceStateListMutex);
1651 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1654 OIC_LOG(ERROR, TAG, "address is not available");
1655 ca_mutex_unlock(g_deviceStateListMutex);
1659 CALEState_t* curState = CALEClientGetStateInfo(address);
1660 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1663 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1664 ca_mutex_unlock(g_deviceStateListMutex);
1668 jboolean ret = JNI_FALSE;
1671 case CA_LE_AUTO_CONNECT_FLAG:
1672 ret = curState->autoConnectFlag;
1674 case CA_LE_DESCRIPTOR_FOUND:
1675 ret = curState->isDescriptorFound;
1680 ca_mutex_unlock(g_deviceStateListMutex);
1682 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1683 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1687 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1689 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1690 VERIFY_NON_NULL(env, TAG, "env is null");
1691 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1693 ca_mutex_lock(g_threadSendMutex);
1695 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1698 OIC_LOG(ERROR, TAG, "jni_address is not available");
1699 ca_mutex_unlock(g_threadSendMutex);
1700 return CA_STATUS_FAILED;
1703 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1706 OIC_LOG(ERROR, TAG, "address is not available");
1707 ca_mutex_unlock(g_threadSendMutex);
1708 return CA_STATUS_FAILED;
1711 CAResult_t res = CA_STATUS_OK;
1712 if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1713 STATE_DISCONNECTED))
1715 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1716 if (NULL == newGatt)
1718 OIC_LOG(INFO, TAG, "newGatt is not available");
1719 res = CA_STATUS_FAILED;
1722 ca_mutex_unlock(g_threadSendMutex);
1727 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1729 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1730 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1731 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1733 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1734 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1737 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1740 OIC_LOG(ERROR, TAG, "address is not available");
1744 // close the gatt service
1745 jobject gatt = CALEClientGetGattObjInList(env, address);
1748 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1749 if (CA_STATUS_OK != res)
1751 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1752 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1756 // clean previous gatt object after close profile service
1757 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1758 if (CA_STATUS_OK != res)
1760 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1761 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1765 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1768 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1771 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1775 // add new gatt object into g_gattObjectList
1776 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1777 if (CA_STATUS_OK != res)
1779 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1786 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1788 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1789 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1790 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1792 if (!g_leGattCallback)
1794 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1798 if (!CALEIsEnableBTAdapter(env))
1800 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1804 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1807 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1811 // get BluetoothDevice method
1812 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1813 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1815 "(Landroid/content/Context;ZLandroid/"
1816 "bluetooth/BluetoothGattCallback;)"
1817 "Landroid/bluetooth/BluetoothGatt;");
1818 if (!jni_mid_connectGatt)
1820 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1824 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1825 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1826 jni_mid_connectGatt,
1828 autoconnect, g_leGattCallback);
1829 if (!jni_obj_connectGatt)
1831 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1832 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1833 CALEClientUpdateSendCnt(env);
1838 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1840 return jni_obj_connectGatt;
1843 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1845 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1847 VERIFY_NON_NULL(env, TAG, "env is null");
1848 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1850 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1851 if (!jni_cid_BTAdapter)
1853 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1854 return CA_STATUS_FAILED;
1857 // get remote bt adapter method
1858 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1859 "getDefaultAdapter",
1860 METHODID_OBJECTNONPARAM);
1861 if (!jni_mid_getDefaultAdapter)
1863 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1864 return CA_STATUS_FAILED;
1867 // gat bt adapter object
1868 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1869 jni_mid_getDefaultAdapter);
1870 if (!jni_obj_BTAdapter)
1872 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1873 return CA_STATUS_FAILED;
1876 // get closeProfileProxy method
1877 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1878 "closeProfileProxy",
1879 "(ILandroid/bluetooth/"
1880 "BluetoothProfile;)V");
1881 if (!jni_mid_closeProfileProxy)
1883 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1884 return CA_STATUS_FAILED;
1887 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1888 if (!jni_cid_BTProfile)
1890 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1891 return CA_STATUS_FAILED;
1894 // GATT - Constant value : 7 (0x00000007)
1895 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1899 OIC_LOG(ERROR, TAG, "id_gatt is null");
1900 return CA_STATUS_FAILED;
1903 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1905 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1906 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1907 if ((*env)->ExceptionCheck(env))
1909 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1910 (*env)->ExceptionDescribe(env);
1911 (*env)->ExceptionClear(env);
1912 return CA_STATUS_FAILED;
1915 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1916 return CA_STATUS_OK;
1920 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1922 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1923 VERIFY_NON_NULL(env, TAG, "env is null");
1924 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1926 // get BluetoothGatt method
1927 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1928 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1929 "disconnect", "()V");
1930 if (!jni_mid_disconnectGatt)
1932 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1933 return CA_STATUS_FAILED;
1936 // call disconnect gatt method
1937 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1938 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1939 if ((*env)->ExceptionCheck(env))
1941 OIC_LOG(ERROR, TAG, "disconnect has failed");
1942 (*env)->ExceptionDescribe(env);
1943 (*env)->ExceptionClear(env);
1944 return CA_STATUS_FAILED;
1947 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1949 return CA_STATUS_OK;
1952 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1954 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1955 VERIFY_NON_NULL(env, TAG, "env is null");
1957 if (!g_gattObjectList)
1959 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1960 return CA_STATUS_OK;
1963 uint32_t length = u_arraylist_length(g_gattObjectList);
1964 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1965 for (uint32_t index = 0; index < length; index++)
1967 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1968 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1971 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1974 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1975 if (CA_STATUS_OK != res)
1977 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1982 return CA_STATUS_OK;
1985 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1987 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1988 VERIFY_NON_NULL(env, TAG, "env is null");
1990 if (!g_gattObjectList)
1992 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1993 return CA_STATUS_OK;
1996 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1999 OIC_LOG(ERROR, TAG, "address is null");
2000 return CA_STATUS_FAILED;
2003 uint32_t length = u_arraylist_length(g_gattObjectList);
2004 for (uint32_t index = 0; index < length; index++)
2006 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2009 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2013 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2014 if (!jni_setAddress)
2016 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2017 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2018 return CA_STATUS_FAILED;
2021 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2024 OIC_LOG(ERROR, TAG, "setAddress is null");
2025 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2026 return CA_STATUS_FAILED;
2029 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
2030 if (!strcmp(address, setAddress))
2032 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
2033 if (CA_STATUS_OK != res)
2035 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
2036 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2037 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2038 return CA_STATUS_FAILED;
2040 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2041 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2042 return CA_STATUS_OK;
2044 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2046 (*env)->ReleaseStringUTFChars(env, remote_address, address);
2048 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
2049 return CA_STATUS_OK;
2052 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
2054 VERIFY_NON_NULL(env, TAG, "env is null");
2055 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2057 if (!CALEIsEnableBTAdapter(env))
2059 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2060 return CA_ADAPTER_NOT_ENABLED;
2063 // get BluetoothGatt.discoverServices method
2064 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
2065 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2066 "discoverServices", "()Z");
2067 if (!jni_mid_discoverServices)
2069 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2070 return CA_STATUS_FAILED;
2073 // call disconnect gatt method
2074 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
2075 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2078 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2079 return CA_STATUS_FAILED;
2082 return CA_STATUS_OK;
2085 static void CALEWriteCharacteristicThread(void* object)
2087 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2089 bool isAttached = false;
2091 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2094 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2095 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2099 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2105 jobject gatt = (jobject)object;
2106 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2107 if (CA_STATUS_OK != ret)
2109 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2114 (*g_jvm)->DetachCurrentThread(g_jvm);
2118 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2120 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2122 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2123 VERIFY_NON_NULL(env, TAG, "env is null");
2125 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2128 CALEClientSendFinish(env, gatt);
2129 return CA_STATUS_FAILED;
2132 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2135 CALEClientSendFinish(env, gatt);
2136 return CA_STATUS_FAILED;
2139 ca_mutex_lock(g_threadSendStateMutex);
2141 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2143 OIC_LOG(INFO, TAG, "current state is SENDING");
2144 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2145 ca_mutex_unlock(g_threadSendStateMutex);
2146 return CA_STATUS_OK;
2149 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2152 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2153 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2154 CALEClientSendFinish(env, gatt);
2155 ca_mutex_unlock(g_threadSendStateMutex);
2156 return CA_STATUS_FAILED;
2159 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2161 ca_mutex_unlock(g_threadSendStateMutex);
2164 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2165 if (!jni_obj_character)
2167 CALEClientSendFinish(env, gatt);
2168 return CA_STATUS_FAILED;
2171 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2172 if (CA_STATUS_OK != ret)
2174 CALEClientSendFinish(env, gatt);
2175 return CA_STATUS_FAILED;
2178 // wait for callback for write Characteristic with success to sent data
2179 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2180 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2181 if (!g_isSignalSetFlag)
2183 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2184 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2185 g_threadWriteCharacteristicMutex,
2186 WAIT_TIME_WRITE_CHARACTERISTIC))
2188 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2189 g_isSignalSetFlag = false;
2190 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2191 return CA_STATUS_FAILED;
2194 // reset flag set by writeCharacteristic Callback
2195 g_isSignalSetFlag = false;
2196 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2198 CALEClientUpdateSendCnt(env);
2200 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2201 return CA_STATUS_OK;
2204 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2206 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2207 VERIFY_NON_NULL(env, TAG, "env is null");
2208 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2210 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2211 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2212 CALEWriteCharacteristicThread, (void*)gattParam))
2214 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2215 return CA_STATUS_FAILED;
2218 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2219 return CA_STATUS_OK;
2222 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2223 jobject gattCharacteristic)
2225 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2226 VERIFY_NON_NULL(env, TAG, "env is null");
2227 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2228 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2230 if (!CALEIsEnableBTAdapter(env))
2232 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2233 return CA_STATUS_FAILED;
2236 // get BluetoothGatt.write characteristic method
2237 OIC_LOG(DEBUG, TAG, "write characteristic method");
2238 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2239 "writeCharacteristic",
2240 "(Landroid/bluetooth/"
2241 "BluetoothGattCharacteristic;)Z");
2242 if (!jni_mid_writeCharacteristic)
2244 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2245 return CA_STATUS_FAILED;
2248 // call disconnect gatt method
2249 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2250 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2251 jni_mid_writeCharacteristic,
2252 gattCharacteristic);
2255 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2259 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2260 return CA_STATUS_FAILED;
2263 return CA_STATUS_OK;
2266 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2268 VERIFY_NON_NULL(env, TAG, "env is null");
2269 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2271 if (!CALEIsEnableBTAdapter(env))
2273 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2274 return CA_STATUS_FAILED;
2277 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2280 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2281 return CA_STATUS_FAILED;
2284 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2285 if (!jni_obj_GattCharacteristic)
2287 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2288 return CA_STATUS_FAILED;
2291 OIC_LOG(DEBUG, TAG, "read characteristic method");
2292 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2293 "readCharacteristic",
2294 "(Landroid/bluetooth/"
2295 "BluetoothGattCharacteristic;)Z");
2296 if (!jni_mid_readCharacteristic)
2298 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2299 return CA_STATUS_FAILED;
2302 // call disconnect gatt method
2303 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2304 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2305 jni_obj_GattCharacteristic);
2308 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2312 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2313 return CA_STATUS_FAILED;
2316 return CA_STATUS_OK;
2319 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2320 jobject characteristic)
2322 VERIFY_NON_NULL(env, TAG, "env is null");
2323 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2324 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2326 if (!CALEIsEnableBTAdapter(env))
2328 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2329 return CA_ADAPTER_NOT_ENABLED;
2332 // get BluetoothGatt.setCharacteristicNotification method
2333 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2334 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2335 "setCharacteristicNotification",
2336 "(Landroid/bluetooth/"
2337 "BluetoothGattCharacteristic;Z)Z");
2338 if (!jni_mid_setNotification)
2340 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2341 return CA_STATUS_FAILED;
2344 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2345 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2346 characteristic, JNI_TRUE);
2347 if (JNI_TRUE == ret)
2349 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2353 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2354 return CA_STATUS_FAILED;
2357 return CA_STATUS_OK;
2360 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2362 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2363 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2364 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2366 if (!CALEIsEnableBTAdapter(env))
2368 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2372 // get BluetoothGatt.getService method
2373 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2374 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2376 "(Ljava/util/UUID;)Landroid/bluetooth/"
2377 "BluetoothGattService;");
2378 if (!jni_mid_getService)
2380 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2384 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2385 if (!jni_obj_service_uuid)
2387 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2391 // get bluetooth gatt service
2392 OIC_LOG(DEBUG, TAG, "request to get service");
2393 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2394 jni_obj_service_uuid);
2395 if (!jni_obj_gattService)
2397 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2401 // get bluetooth gatt service method
2402 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2403 "BluetoothGattService",
2404 "getCharacteristic",
2405 "(Ljava/util/UUID;)"
2406 "Landroid/bluetooth/"
2407 "BluetoothGattCharacteristic;");
2408 if (!jni_mid_getCharacteristic)
2410 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2414 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2417 OIC_LOG(ERROR, TAG, "uuid is null");
2421 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2422 if (!jni_obj_tx_uuid)
2424 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2425 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2429 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2430 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2431 jni_mid_getCharacteristic,
2434 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2435 return jni_obj_GattCharacteristic;
2438 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2440 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2441 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2442 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2443 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2445 if (!CALEIsEnableBTAdapter(env))
2447 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2451 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2454 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2458 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2459 if (!jni_obj_GattCharacteristic)
2461 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2465 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2466 "/BluetoothGattCharacteristic");
2467 if (!jni_cid_BTGattCharacteristic)
2469 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2473 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2474 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2476 if (!jni_mid_setValue)
2478 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2482 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2484 if (JNI_TRUE == ret)
2486 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2490 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2495 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2496 "setWriteType", "(I)V");
2497 if (!jni_mid_setWriteType)
2499 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2503 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2504 "WRITE_TYPE_NO_RESPONSE", "I");
2505 if (!jni_fid_no_response)
2507 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2511 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2512 jni_fid_no_response);
2514 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2516 return jni_obj_GattCharacteristic;
2519 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2521 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2522 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2524 if (!CALEIsEnableBTAdapter(env))
2526 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2530 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2531 "BluetoothGattCharacteristic",
2532 "getValue", "()[B");
2533 if (!jni_mid_getValue)
2535 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2539 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2541 return jni_obj_data_array;
2544 CAResult_t CALEClientCreateUUIDList()
2548 OIC_LOG(ERROR, TAG, "g_jvm is null");
2549 return CA_STATUS_FAILED;
2552 bool isAttached = false;
2554 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2557 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2558 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2562 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2563 return CA_STATUS_FAILED;
2568 // create new object array
2569 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2570 if (!jni_cid_uuid_list)
2572 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2576 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2577 jni_cid_uuid_list, NULL);
2578 if (!jni_obj_uuid_list)
2580 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2585 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2588 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2591 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2593 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2597 (*g_jvm)->DetachCurrentThread(g_jvm);
2600 return CA_STATUS_OK;
2607 (*g_jvm)->DetachCurrentThread(g_jvm);
2609 return CA_STATUS_FAILED;
2612 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2613 jobject characteristic)
2615 VERIFY_NON_NULL(env, TAG, "env is null");
2616 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2617 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2619 if (!CALEIsEnableBTAdapter(env))
2621 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2622 return CA_ADAPTER_NOT_ENABLED;
2625 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2626 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2627 "BluetoothGattCharacteristic",
2629 "(Ljava/util/UUID;)Landroid/bluetooth/"
2630 "BluetoothGattDescriptor;");
2631 if (!jni_mid_getDescriptor)
2633 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2634 return CA_STATUS_FAILED;
2637 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2638 if (!jni_obj_cc_uuid)
2640 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2641 return CA_STATUS_FAILED;
2644 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2645 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2646 jni_mid_getDescriptor, jni_obj_cc_uuid);
2647 if (!jni_obj_descriptor)
2649 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2650 return CA_NOT_SUPPORTED;
2653 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2654 jclass jni_cid_descriptor = (*env)->FindClass(env,
2655 "android/bluetooth/BluetoothGattDescriptor");
2656 if (!jni_cid_descriptor)
2658 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2659 return CA_STATUS_FAILED;
2662 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2663 if (!jni_mid_setValue)
2665 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2666 return CA_STATUS_FAILED;
2669 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2670 "ENABLE_NOTIFICATION_VALUE", "[B");
2671 if (!jni_fid_NotiValue)
2673 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2674 return CA_STATUS_FAILED;
2677 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2679 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2680 env, jni_obj_descriptor, jni_mid_setValue,
2681 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2684 OIC_LOG(DEBUG, TAG, "setValue success");
2688 OIC_LOG(ERROR, TAG, "setValue has failed");
2689 return CA_STATUS_FAILED;
2692 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2694 "(Landroid/bluetooth/"
2695 "BluetoothGattDescriptor;)Z");
2696 if (!jni_mid_writeDescriptor)
2698 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2699 return CA_STATUS_FAILED;
2702 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2703 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2704 jni_obj_descriptor);
2707 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2711 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2712 return CA_STATUS_FAILED;
2715 return CA_STATUS_OK;
2718 void CALEClientCreateScanDeviceList(JNIEnv *env)
2720 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2721 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2723 ca_mutex_lock(g_deviceListMutex);
2724 // create new object array
2725 if (g_deviceList == NULL)
2727 OIC_LOG(DEBUG, TAG, "Create device list");
2729 g_deviceList = u_arraylist_create();
2731 ca_mutex_unlock(g_deviceListMutex);
2734 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2736 VERIFY_NON_NULL(device, TAG, "device is null");
2737 VERIFY_NON_NULL(env, TAG, "env is null");
2739 ca_mutex_lock(g_deviceListMutex);
2743 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2744 ca_mutex_unlock(g_deviceListMutex);
2745 return CA_STATUS_FAILED;
2748 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2749 if (!jni_remoteAddress)
2751 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2752 ca_mutex_unlock(g_deviceListMutex);
2753 return CA_STATUS_FAILED;
2756 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2759 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2760 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2761 ca_mutex_unlock(g_deviceListMutex);
2762 return CA_STATUS_FAILED;
2765 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2767 jobject gdevice = (*env)->NewGlobalRef(env, device);
2768 u_arraylist_add(g_deviceList, gdevice);
2769 ca_cond_signal(g_deviceDescCond);
2770 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2772 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2773 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2775 ca_mutex_unlock(g_deviceListMutex);
2777 return CA_STATUS_OK;
2780 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2782 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2783 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2787 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2791 uint32_t length = u_arraylist_length(g_deviceList);
2792 for (uint32_t index = 0; index < length; index++)
2794 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2797 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2801 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2802 if (!jni_setAddress)
2804 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2808 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2811 OIC_LOG(ERROR, TAG, "setAddress is null");
2812 (*env)->DeleteLocalRef(env, jni_setAddress);
2816 if (!strcmp(remoteAddress, setAddress))
2818 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2819 (*env)->DeleteLocalRef(env, jni_setAddress);
2823 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2824 (*env)->DeleteLocalRef(env, jni_setAddress);
2827 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2832 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2834 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2835 VERIFY_NON_NULL(env, TAG, "env is null");
2837 ca_mutex_lock(g_deviceListMutex);
2841 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2842 ca_mutex_unlock(g_deviceListMutex);
2843 return CA_STATUS_FAILED;
2846 uint32_t length = u_arraylist_length(g_deviceList);
2847 for (uint32_t index = 0; index < length; index++)
2849 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2852 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2855 (*env)->DeleteGlobalRef(env, jarrayObj);
2859 OICFree(g_deviceList);
2860 g_deviceList = NULL;
2862 ca_mutex_unlock(g_deviceListMutex);
2863 return CA_STATUS_OK;
2866 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2868 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2869 VERIFY_NON_NULL(address, TAG, "address is null");
2870 VERIFY_NON_NULL(env, TAG, "env is null");
2872 ca_mutex_lock(g_deviceListMutex);
2876 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2877 ca_mutex_unlock(g_deviceListMutex);
2878 return CA_STATUS_FAILED;
2881 uint32_t length = u_arraylist_length(g_deviceList);
2882 for (uint32_t index = 0; index < length; index++)
2884 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2887 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2888 ca_mutex_unlock(g_deviceListMutex);
2889 return CA_STATUS_FAILED;
2892 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2893 if (!jni_setAddress)
2895 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2896 ca_mutex_unlock(g_deviceListMutex);
2897 return CA_STATUS_FAILED;
2900 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2903 OIC_LOG(ERROR, TAG, "setAddress is null");
2904 ca_mutex_unlock(g_deviceListMutex);
2905 return CA_STATUS_FAILED;
2908 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2911 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2912 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2913 ca_mutex_unlock(g_deviceListMutex);
2914 return CA_STATUS_FAILED;
2917 if (!strcmp(setAddress, remoteAddress))
2919 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2920 (*env)->DeleteGlobalRef(env, jarrayObj);
2922 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2923 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2925 if (NULL == u_arraylist_remove(g_deviceList, index))
2927 OIC_LOG(ERROR, TAG, "List removal failed.");
2928 ca_mutex_unlock(g_deviceListMutex);
2929 return CA_STATUS_FAILED;
2931 ca_mutex_unlock(g_deviceListMutex);
2932 return CA_STATUS_OK;
2934 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2935 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2938 ca_mutex_unlock(g_deviceListMutex);
2939 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2941 return CA_STATUS_OK;
2948 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2950 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2951 VERIFY_NON_NULL(env, TAG, "env is null");
2952 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2954 ca_mutex_lock(g_gattObjectMutex);
2956 if (!g_gattObjectList)
2958 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2959 ca_mutex_unlock(g_gattObjectMutex);
2960 return CA_STATUS_FAILED;
2963 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2964 if (!jni_remoteAddress)
2966 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2967 ca_mutex_unlock(g_gattObjectMutex);
2968 return CA_STATUS_FAILED;
2971 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2974 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2975 ca_mutex_unlock(g_gattObjectMutex);
2976 return CA_STATUS_FAILED;
2979 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
2980 if (!CALEClientIsGattObjInList(env, remoteAddress))
2982 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2983 u_arraylist_add(g_gattObjectList, newGatt);
2984 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
2987 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2988 ca_mutex_unlock(g_gattObjectMutex);
2989 return CA_STATUS_OK;
2992 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2994 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2995 VERIFY_NON_NULL(env, TAG, "env is null");
2996 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2998 uint32_t length = u_arraylist_length(g_gattObjectList);
2999 for (uint32_t index = 0; index < length; index++)
3002 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3005 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3009 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3010 if (!jni_setAddress)
3012 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3016 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3019 OIC_LOG(ERROR, TAG, "setAddress is null");
3023 if (!strcmp(remoteAddress, setAddress))
3025 OIC_LOG(DEBUG, TAG, "the device is already set");
3026 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3031 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3036 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
3040 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
3042 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
3043 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3044 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3046 ca_mutex_lock(g_gattObjectMutex);
3047 uint32_t length = u_arraylist_length(g_gattObjectList);
3048 for (uint32_t index = 0; index < length; index++)
3050 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3053 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3054 ca_mutex_unlock(g_gattObjectMutex);
3058 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3059 if (!jni_setAddress)
3061 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3062 ca_mutex_unlock(g_gattObjectMutex);
3066 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3069 OIC_LOG(ERROR, TAG, "setAddress is null");
3070 ca_mutex_unlock(g_gattObjectMutex);
3074 if (!strcmp(remoteAddress, setAddress))
3076 OIC_LOG(DEBUG, TAG, "the device is already set");
3077 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3078 ca_mutex_unlock(g_gattObjectMutex);
3081 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3084 ca_mutex_unlock(g_gattObjectMutex);
3085 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3089 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3091 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3092 VERIFY_NON_NULL(env, TAG, "env is null");
3094 ca_mutex_lock(g_gattObjectMutex);
3095 if (!g_gattObjectList)
3097 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3098 ca_mutex_unlock(g_gattObjectMutex);
3099 return CA_STATUS_OK;
3102 uint32_t length = u_arraylist_length(g_gattObjectList);
3103 for (uint32_t index = 0; index < length; index++)
3105 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3108 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3111 (*env)->DeleteGlobalRef(env, jarrayObj);
3115 OICFree(g_gattObjectList);
3116 g_gattObjectList = NULL;
3117 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3118 ca_mutex_unlock(g_gattObjectMutex);
3119 return CA_STATUS_OK;
3122 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3124 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3125 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3126 VERIFY_NON_NULL(env, TAG, "env is null");
3128 ca_mutex_lock(g_gattObjectMutex);
3129 if (!g_gattObjectList)
3131 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3132 ca_mutex_unlock(g_gattObjectMutex);
3133 return CA_STATUS_OK;
3136 uint32_t length = u_arraylist_length(g_gattObjectList);
3137 for (uint32_t index = 0; index < length; index++)
3139 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3142 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3143 ca_mutex_unlock(g_gattObjectMutex);
3144 return CA_STATUS_FAILED;
3147 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3148 if (!jni_setAddress)
3150 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3151 ca_mutex_unlock(g_gattObjectMutex);
3152 return CA_STATUS_FAILED;
3155 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3158 OIC_LOG(ERROR, TAG, "setAddress is null");
3159 ca_mutex_unlock(g_gattObjectMutex);
3160 return CA_STATUS_FAILED;
3163 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3164 if (!jni_remoteAddress)
3166 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3167 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3168 ca_mutex_unlock(g_gattObjectMutex);
3169 return CA_STATUS_FAILED;
3172 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3175 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3176 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3177 ca_mutex_unlock(g_gattObjectMutex);
3178 return CA_STATUS_FAILED;
3181 if (!strcmp(setAddress, remoteAddress))
3183 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3184 (*env)->DeleteGlobalRef(env, jarrayObj);
3186 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3187 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3189 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3191 OIC_LOG(ERROR, TAG, "List removal failed.");
3192 ca_mutex_unlock(g_gattObjectMutex);
3193 return CA_STATUS_FAILED;
3195 ca_mutex_unlock(g_gattObjectMutex);
3196 return CA_STATUS_OK;
3198 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3199 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3202 ca_mutex_unlock(g_gattObjectMutex);
3203 OIC_LOG(DEBUG, TAG, "there are no target object");
3204 return CA_STATUS_OK;
3207 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3209 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3210 VERIFY_NON_NULL(addr, TAG, "addr is null");
3211 VERIFY_NON_NULL(env, TAG, "env is null");
3213 ca_mutex_lock(g_gattObjectMutex);
3214 if (!g_gattObjectList)
3216 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3217 ca_mutex_unlock(g_gattObjectMutex);
3218 return CA_STATUS_OK;
3221 uint32_t length = u_arraylist_length(g_gattObjectList);
3222 for (uint32_t index = 0; index < length; index++)
3224 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3227 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3228 ca_mutex_unlock(g_gattObjectMutex);
3229 return CA_STATUS_FAILED;
3232 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3233 if (!jni_setAddress)
3235 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3236 ca_mutex_unlock(g_gattObjectMutex);
3237 return CA_STATUS_FAILED;
3240 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3243 OIC_LOG(ERROR, TAG, "setAddress is null");
3244 ca_mutex_unlock(g_gattObjectMutex);
3245 return CA_STATUS_FAILED;
3248 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3251 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3252 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3253 ca_mutex_unlock(g_gattObjectMutex);
3254 return CA_STATUS_FAILED;
3257 if (!strcmp(setAddress, remoteAddress))
3259 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3260 (*env)->DeleteGlobalRef(env, jarrayObj);
3262 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3263 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3264 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3266 OIC_LOG(ERROR, TAG, "List removal failed.");
3267 ca_mutex_unlock(g_gattObjectMutex);
3268 return CA_STATUS_FAILED;
3270 ca_mutex_unlock(g_gattObjectMutex);
3271 return CA_STATUS_OK;
3273 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3274 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3277 ca_mutex_unlock(g_gattObjectMutex);
3278 OIC_LOG(DEBUG, TAG, "there are no target object");
3279 return CA_STATUS_FAILED;
3282 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3284 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3286 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3287 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3289 // get Bluetooth Address
3290 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3291 if (!jni_btTargetAddress)
3293 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3297 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3300 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3304 // get method ID of getDevice()
3305 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3306 "getDevice", METHODID_BT_DEVICE);
3307 if (!jni_mid_getDevice)
3309 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3310 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3314 ca_mutex_lock(g_gattObjectMutex);
3316 size_t length = u_arraylist_length(g_gattObjectList);
3317 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3318 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3320 for (size_t index = 0; index < length; index++)
3322 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3325 ca_mutex_unlock(g_gattObjectMutex);
3326 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3327 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3331 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3332 if (!jni_obj_device)
3334 ca_mutex_unlock(g_gattObjectMutex);
3335 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3336 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3340 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3343 ca_mutex_unlock(g_gattObjectMutex);
3344 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3345 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3349 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3352 ca_mutex_unlock(g_gattObjectMutex);
3353 OIC_LOG(ERROR, TAG, "btAddress is not available");
3354 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3358 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3359 if (!strcmp(targetAddress, btAddress))
3361 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3364 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3367 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3369 ca_mutex_unlock(g_gattObjectMutex);
3370 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3371 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3372 (*env)->DeleteLocalRef(env, jni_btAddress);
3373 (*env)->DeleteLocalRef(env, jni_obj_device);
3374 return jni_LEAddress;
3376 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3377 (*env)->DeleteLocalRef(env, jni_btAddress);
3378 (*env)->DeleteLocalRef(env, jni_obj_device);
3380 ca_mutex_unlock(g_gattObjectMutex);
3382 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3383 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3391 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3392 uint16_t target_state)
3394 VERIFY_NON_NULL(address, TAG, "address is null");
3395 VERIFY_NON_NULL(address, TAG, "state_type is null");
3396 VERIFY_NON_NULL(address, TAG, "target_state is null");
3398 if (!g_deviceStateList)
3400 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3401 return CA_STATUS_FAILED;
3404 ca_mutex_lock(g_deviceStateListMutex);
3406 if (CALEClientIsDeviceInList(address))
3408 CALEState_t* curState = CALEClientGetStateInfo(address);
3411 OIC_LOG(ERROR, TAG, "curState is null");
3412 ca_mutex_unlock(g_deviceStateListMutex);
3413 return CA_STATUS_FAILED;
3418 case CA_LE_CONNECTION_STATE:
3419 curState->connectedState = target_state;
3421 case CA_LE_SEND_STATE:
3422 curState->sendState = target_state;
3427 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3428 curState->address, curState->connectedState, curState->sendState,
3429 curState->autoConnectFlag);
3431 else /** state is added newly **/
3433 if (strlen(address) > CA_MACADDR_SIZE)
3435 OIC_LOG(ERROR, TAG, "address is not proper");
3436 ca_mutex_unlock(g_deviceStateListMutex);
3437 return CA_STATUS_INVALID_PARAM;
3440 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3443 OIC_LOG(ERROR, TAG, "out of memory");
3444 ca_mutex_unlock(g_deviceStateListMutex);
3445 return CA_MEMORY_ALLOC_FAILED;
3448 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3452 case CA_LE_CONNECTION_STATE:
3453 newstate->connectedState = target_state;
3454 newstate->sendState = STATE_SEND_NONE;
3456 case CA_LE_SEND_STATE:
3457 newstate->connectedState = STATE_DISCONNECTED;
3458 newstate->sendState = target_state;
3463 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3464 "conn : %d, send : %d, ACFlag : %d",
3465 newstate->address, newstate->connectedState, newstate->sendState,
3466 newstate->autoConnectFlag);
3467 u_arraylist_add(g_deviceStateList, newstate); // update new state
3469 ca_mutex_unlock(g_deviceStateListMutex);
3471 return CA_STATUS_OK;
3474 bool CALEClientIsDeviceInList(const char* remoteAddress)
3476 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3478 if (!g_deviceStateList)
3480 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3484 uint32_t length = u_arraylist_length(g_deviceStateList);
3485 for (uint32_t index = 0; index < length; index++)
3487 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3490 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3494 if (!strcmp(remoteAddress, state->address))
3496 OIC_LOG(DEBUG, TAG, "the device is already set");
3505 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3509 CAResult_t CALEClientRemoveAllDeviceState()
3511 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3513 ca_mutex_lock(g_deviceStateListMutex);
3514 if (!g_deviceStateList)
3516 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3517 ca_mutex_unlock(g_deviceStateListMutex);
3518 return CA_STATUS_FAILED;
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, "jarrayObj is null");
3533 OICFree(g_deviceStateList);
3534 g_deviceStateList = NULL;
3535 ca_mutex_unlock(g_deviceStateListMutex);
3537 return CA_STATUS_OK;
3540 CAResult_t CALEClientResetDeviceStateForAll()
3542 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3544 ca_mutex_lock(g_deviceStateListMutex);
3545 if (!g_deviceStateList)
3547 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3548 ca_mutex_unlock(g_deviceStateListMutex);
3549 return CA_STATUS_FAILED;
3552 size_t length = u_arraylist_length(g_deviceStateList);
3553 for (size_t index = 0; index < length; index++)
3555 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3558 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3562 // autoConnectFlag value will be not changed,
3563 // since it has reset only termination case.
3564 state->connectedState = STATE_DISCONNECTED;
3565 state->sendState = STATE_SEND_NONE;
3567 ca_mutex_unlock(g_deviceStateListMutex);
3569 return CA_STATUS_OK;
3572 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3574 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3575 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3577 if (!g_deviceStateList)
3579 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3580 return CA_STATUS_FAILED;
3583 uint32_t length = u_arraylist_length(g_deviceStateList);
3584 for (uint32_t index = 0; index < length; index++)
3586 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3589 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3593 if (!strcmp(state->address, remoteAddress))
3595 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3597 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3599 if (NULL == targetState)
3601 OIC_LOG(ERROR, TAG, "List removal failed.");
3602 return CA_STATUS_FAILED;
3605 OICFree(targetState);
3606 return CA_STATUS_OK;
3610 return CA_STATUS_OK;
3613 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3615 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3617 if (!g_deviceStateList)
3619 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3623 uint32_t length = u_arraylist_length(g_deviceStateList);
3624 OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
3625 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3627 for (uint32_t index = 0; index < length; index++)
3629 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3632 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3636 OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
3638 if (!strcmp(state->address, remoteAddress))
3640 OIC_LOG(DEBUG, TAG, "found state");
3645 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
3649 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3650 uint16_t target_state)
3652 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3653 state_type, target_state);
3654 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3656 ca_mutex_lock(g_deviceStateListMutex);
3657 if (!g_deviceStateList)
3659 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3660 ca_mutex_unlock(g_deviceStateListMutex);
3664 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3667 OIC_LOG(ERROR, TAG, "state is null");
3668 ca_mutex_unlock(g_deviceStateListMutex);
3672 uint16_t curValue = 0;
3675 case CA_LE_CONNECTION_STATE:
3676 curValue = state->connectedState;
3678 case CA_LE_SEND_STATE:
3679 curValue = state->sendState;
3685 if (target_state == curValue)
3687 ca_mutex_unlock(g_deviceStateListMutex);
3692 ca_mutex_unlock(g_deviceStateListMutex);
3696 ca_mutex_unlock(g_deviceStateListMutex);
3700 void CALEClientCreateDeviceList()
3702 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3704 // create new object array
3705 if (!g_gattObjectList)
3707 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3709 g_gattObjectList = u_arraylist_create();
3712 if (!g_deviceStateList)
3714 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3716 g_deviceStateList = u_arraylist_create();
3721 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3723 g_deviceList = u_arraylist_create();
3728 * Check Sent Count for remove g_sendBuffer
3730 void CALEClientUpdateSendCnt(JNIEnv *env)
3732 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3734 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3736 ca_mutex_lock(g_threadMutex);
3740 if (g_targetCnt <= g_currentSentCnt)
3743 g_currentSentCnt = 0;
3747 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3748 g_sendBuffer = NULL;
3750 // notity the thread
3751 ca_cond_signal(g_threadCond);
3753 CALEClientSetSendFinishFlag(true);
3754 OIC_LOG(DEBUG, TAG, "set signal for send data");
3757 ca_mutex_unlock(g_threadMutex);
3760 CAResult_t CALEClientInitGattMutexVaraibles()
3762 if (NULL == g_bleReqRespClientCbMutex)
3764 g_bleReqRespClientCbMutex = ca_mutex_new();
3765 if (NULL == g_bleReqRespClientCbMutex)
3767 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3768 return CA_STATUS_FAILED;
3772 if (NULL == g_bleServerBDAddressMutex)
3774 g_bleServerBDAddressMutex = ca_mutex_new();
3775 if (NULL == g_bleServerBDAddressMutex)
3777 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3778 return CA_STATUS_FAILED;
3782 if (NULL == g_threadMutex)
3784 g_threadMutex = ca_mutex_new();
3785 if (NULL == g_threadMutex)
3787 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3788 return CA_STATUS_FAILED;
3792 if (NULL == g_threadSendMutex)
3794 g_threadSendMutex = ca_mutex_new();
3795 if (NULL == g_threadSendMutex)
3797 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3798 return CA_STATUS_FAILED;
3802 if (NULL == g_deviceListMutex)
3804 g_deviceListMutex = ca_mutex_new();
3805 if (NULL == g_deviceListMutex)
3807 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3808 return CA_STATUS_FAILED;
3812 if (NULL == g_gattObjectMutex)
3814 g_gattObjectMutex = ca_mutex_new();
3815 if (NULL == g_gattObjectMutex)
3817 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3818 return CA_STATUS_FAILED;
3822 if (NULL == g_deviceStateListMutex)
3824 g_deviceStateListMutex = ca_mutex_new();
3825 if (NULL == g_deviceStateListMutex)
3827 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3828 return CA_STATUS_FAILED;
3832 if (NULL == g_SendFinishMutex)
3834 g_SendFinishMutex = ca_mutex_new();
3835 if (NULL == g_SendFinishMutex)
3837 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3838 return CA_STATUS_FAILED;
3842 if (NULL == g_threadWriteCharacteristicMutex)
3844 g_threadWriteCharacteristicMutex = ca_mutex_new();
3845 if (NULL == g_threadWriteCharacteristicMutex)
3847 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3848 return CA_STATUS_FAILED;
3852 if (NULL == g_deviceScanRetryDelayMutex)
3854 g_deviceScanRetryDelayMutex = ca_mutex_new();
3855 if (NULL == g_deviceScanRetryDelayMutex)
3857 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3858 return CA_STATUS_FAILED;
3862 if (NULL == g_threadSendStateMutex)
3864 g_threadSendStateMutex = ca_mutex_new();
3865 if (NULL == g_threadSendStateMutex)
3867 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3868 return CA_STATUS_FAILED;
3872 if (NULL == g_threadScanIntervalMutex)
3874 g_threadScanIntervalMutex = ca_mutex_new();
3875 if (NULL == g_threadScanIntervalMutex)
3877 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3878 return CA_STATUS_FAILED;
3882 return CA_STATUS_OK;
3885 void CALEClientTerminateGattMutexVariables()
3887 ca_mutex_free(g_bleReqRespClientCbMutex);
3888 g_bleReqRespClientCbMutex = NULL;
3890 ca_mutex_free(g_bleServerBDAddressMutex);
3891 g_bleServerBDAddressMutex = NULL;
3893 ca_mutex_free(g_threadMutex);
3894 g_threadMutex = NULL;
3896 ca_mutex_free(g_threadSendMutex);
3897 g_threadSendMutex = NULL;
3899 ca_mutex_free(g_deviceListMutex);
3900 g_deviceListMutex = NULL;
3902 ca_mutex_free(g_SendFinishMutex);
3903 g_SendFinishMutex = NULL;
3905 ca_mutex_free(g_threadWriteCharacteristicMutex);
3906 g_threadWriteCharacteristicMutex = NULL;
3908 ca_mutex_free(g_deviceScanRetryDelayMutex);
3909 g_deviceScanRetryDelayMutex = NULL;
3911 ca_mutex_free(g_threadSendStateMutex);
3912 g_threadSendStateMutex = NULL;
3914 ca_mutex_free(g_threadScanIntervalMutex);
3915 g_threadScanIntervalMutex = NULL;
3918 void CALEClientSetSendFinishFlag(bool flag)
3920 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3922 ca_mutex_lock(g_SendFinishMutex);
3923 g_isFinishedSendData = flag;
3924 ca_mutex_unlock(g_SendFinishMutex);
3931 CAResult_t CAStartLEGattClient()
3933 // init mutex for send logic
3934 if (!g_deviceDescCond)
3936 g_deviceDescCond = ca_cond_new();
3941 g_threadCond = ca_cond_new();
3944 if (!g_threadWriteCharacteristicCond)
3946 g_threadWriteCharacteristicCond = ca_cond_new();
3949 if (!g_threadScanIntervalCond)
3951 g_threadScanIntervalCond = ca_cond_new();
3954 CAResult_t ret = CALEClientStartScanWithInterval();
3955 if (CA_STATUS_OK != ret)
3957 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithInterval has failed");
3961 g_isStartedLEClient = true;
3962 return CA_STATUS_OK;
3965 void CAStopLEGattClient()
3967 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3971 OIC_LOG(ERROR, TAG, "g_jvm is null");
3975 bool isAttached = false;
3977 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3980 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3981 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3985 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3991 CAResult_t ret = CALEClientDisconnectAll(env);
3992 if (CA_STATUS_OK != ret)
3994 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3997 CALEClientStopScanWithInterval();
3999 ca_mutex_lock(g_threadMutex);
4000 OIC_LOG(DEBUG, TAG, "signal - connection cond");
4001 ca_cond_signal(g_threadCond);
4002 CALEClientSetSendFinishFlag(true);
4003 ca_mutex_unlock(g_threadMutex);
4005 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4006 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
4007 ca_cond_signal(g_threadWriteCharacteristicCond);
4008 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4010 ca_mutex_lock(g_deviceScanRetryDelayMutex);
4011 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4012 ca_cond_signal(g_deviceScanRetryDelayCond);
4013 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
4015 ca_mutex_lock(g_threadScanIntervalMutex);
4016 OIC_LOG(DEBUG, TAG, "signal - delay cond");
4017 ca_cond_signal(g_threadScanIntervalCond);
4018 ca_mutex_unlock(g_threadScanIntervalMutex);
4020 ca_cond_free(g_deviceDescCond);
4021 ca_cond_free(g_threadCond);
4022 ca_cond_free(g_threadWriteCharacteristicCond);
4023 ca_cond_free(g_deviceScanRetryDelayCond);
4024 ca_cond_free(g_threadScanIntervalCond);
4026 g_deviceDescCond = NULL;
4027 g_threadCond = NULL;
4028 g_threadWriteCharacteristicCond = NULL;
4029 g_deviceScanRetryDelayCond = NULL;
4030 g_threadScanIntervalCond = NULL;
4034 (*g_jvm)->DetachCurrentThread(g_jvm);
4039 CAResult_t CAInitializeLEGattClient()
4041 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4042 CALEClientInitialize();
4043 return CA_STATUS_OK;
4046 void CATerminateLEGattClient()
4048 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4049 CAStopLEGattClient();
4050 CALEClientTerminate();
4053 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4054 uint32_t dataLen, CALETransferType_t type,
4057 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4058 VERIFY_NON_NULL(data, TAG, "data is null");
4059 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4061 if (LE_UNICAST != type || position < 0)
4063 OIC_LOG(ERROR, TAG, "this request is not unicast");
4064 return CA_STATUS_INVALID_PARAM;
4067 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4070 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4072 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4073 VERIFY_NON_NULL(data, TAG, "data is null");
4075 return CALEClientSendMulticastMessage(data, dataLen);
4078 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4080 ca_mutex_lock(g_bleReqRespClientCbMutex);
4081 g_CABLEClientDataReceivedCallback = callback;
4082 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4085 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4087 g_threadPoolHandle = handle;
4090 CAResult_t CAGetLEAddress(char **local_address)
4092 VERIFY_NON_NULL(local_address, TAG, "local_address");
4093 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4094 return CA_NOT_SUPPORTED;
4097 JNIEXPORT void JNICALL
4098 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4101 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4102 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4103 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4104 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4106 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4109 JNIEXPORT void JNICALL
4110 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4113 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4114 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4115 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4116 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4118 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4121 JNIEXPORT void JNICALL
4122 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4125 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4126 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4127 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4129 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4130 if (CA_STATUS_OK != res)
4132 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4137 * Class: org_iotivity_ca_jar_caleinterface
4138 * Method: CALeGattConnectionStateChangeCallback
4139 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4141 JNIEXPORT void JNICALL
4142 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4148 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4150 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4151 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4152 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4154 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4156 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4159 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4163 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4166 OIC_LOG(ERROR, TAG, "address is null");
4169 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4171 if (state_connected == newstate)
4173 OIC_LOG(DEBUG, TAG, "LE is connected");
4174 if (GATT_SUCCESS == status)
4176 CAResult_t res = CALEClientUpdateDeviceState(address,
4177 CA_LE_CONNECTION_STATE,
4179 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4180 if (CA_STATUS_OK != res)
4182 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4186 res = CALEClientAddGattobjToList(env, gatt);
4187 if (CA_STATUS_OK != res)
4189 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4193 res = CALEClientDiscoverServices(env, gatt);
4194 if (CA_STATUS_OK != res)
4196 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4202 OIC_LOG(INFO, TAG, "unknown status");
4203 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4206 else // STATE_DISCONNECTED == newstate
4208 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4210 CAResult_t res = CALEClientUpdateDeviceState(address,
4211 CA_LE_CONNECTION_STATE,
4212 STATE_DISCONNECTED);
4213 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4214 if (CA_STATUS_OK != res)
4216 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4220 res = CALEClientGattClose(env, gatt);
4221 if (CA_STATUS_OK != res)
4223 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4226 if (CALECheckConnectionStateValue(status))
4228 // this state is unexpected reason to disconnect
4229 // if the reason is suitable, connection logic of the device will be destroyed.
4230 OIC_LOG(INFO, TAG, "connection logic destroy");
4235 // other reason except for gatt_success is expected to running
4236 // background connection in BT platform.
4237 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4238 CALEClientUpdateSendCnt(env);
4244 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4245 g_sendBuffer = NULL;
4252 CALEClientSendFinish(env, gatt);
4257 * Class: org_iotivity_ca_jar_caleinterface
4258 * Method: CALeGattServicesDiscoveredCallback
4259 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4261 JNIEXPORT void JNICALL
4262 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4267 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4268 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4269 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4270 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4272 if (GATT_SUCCESS != status) // discovery error
4274 CALEClientSendFinish(env, gatt);
4278 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4281 CALEClientSendFinish(env, gatt);
4285 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4288 CALEClientSendFinish(env, gatt);
4292 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4295 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4299 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4300 if (!jni_obj_GattCharacteristic)
4302 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4306 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4307 jni_obj_GattCharacteristic);
4308 if (CA_STATUS_OK != res)
4310 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4314 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4315 if (CA_STATUS_OK != res)
4317 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4319 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
4320 if (CA_STATUS_OK != res)
4322 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4326 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4327 STATE_SERVICE_CONNECTED);
4328 if (CA_STATUS_OK != res)
4330 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4336 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4337 if (CA_STATUS_OK != res)
4339 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4346 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
4347 if (CA_STATUS_OK != res)
4349 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4354 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4355 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4360 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4361 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4362 CALEClientSendFinish(env, gatt);
4367 * Class: org_iotivity_ca_jar_caleinterface
4368 * Method: CALeGattCharacteristicWritjclasseCallback
4369 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4371 JNIEXPORT void JNICALL
4372 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4373 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4375 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4376 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4377 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4378 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4380 // send success & signal
4381 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4387 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4393 if (GATT_SUCCESS != status) // error case
4395 OIC_LOG(ERROR, TAG, "send failure");
4398 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4399 if (CA_STATUS_OK != res)
4401 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4402 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4403 g_isSignalSetFlag = true;
4404 ca_cond_signal(g_threadWriteCharacteristicCond);
4405 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4407 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4409 if (CA_STATUS_OK != res)
4411 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4414 if (g_clientErrorCallback)
4416 jint length = (*env)->GetArrayLength(env, data);
4417 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4420 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4426 OIC_LOG(DEBUG, TAG, "send success");
4427 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4428 STATE_SEND_SUCCESS);
4429 if (CA_STATUS_OK != res)
4431 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4434 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4435 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4436 g_isSignalSetFlag = true;
4437 ca_cond_signal(g_threadWriteCharacteristicCond);
4438 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4441 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4447 CALEClientSendFinish(env, gatt);
4452 * Class: org_iotivity_ca_jar_caleinterface
4453 * Method: CALeGattCharacteristicChangedCallback
4454 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4456 JNIEXPORT void JNICALL
4457 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4458 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4460 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4461 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4462 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4463 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4464 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4466 // get Byte Array and convert to uint8_t*
4467 jint length = (*env)->GetArrayLength(env, data);
4470 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4472 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4473 jni_byte_responseData);
4475 uint8_t* receivedData = OICMalloc(length);
4478 OIC_LOG(ERROR, TAG, "receivedData is null");
4482 memcpy(receivedData, jni_byte_responseData, length);
4483 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4485 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4488 OIC_LOG(ERROR, TAG, "jni_address is null");
4489 OICFree(receivedData);
4493 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4496 OIC_LOG(ERROR, TAG, "address is null");
4497 OICFree(receivedData);
4501 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4502 receivedData, length);
4504 uint32_t sentLength = 0;
4505 ca_mutex_lock(g_bleServerBDAddressMutex);
4506 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4507 ca_mutex_unlock(g_bleServerBDAddressMutex);
4509 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4513 * Class: org_iotivity_ca_jar_caleinterface
4514 * Method: CALeGattDescriptorWriteCallback
4515 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4517 JNIEXPORT void JNICALL
4518 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4522 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4523 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4524 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4525 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4527 if (GATT_SUCCESS != status) // error
4532 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4538 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4544 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4545 STATE_SERVICE_CONNECTED);
4546 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4547 if (CA_STATUS_OK != res)
4549 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4555 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4556 if (CA_STATUS_OK != res)
4558 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4567 CALEClientSendFinish(env, gatt);