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("CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
44 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
45 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
46 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
47 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
50 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
51 static u_arraylist_t *g_gattObjectList = NULL;
52 static u_arraylist_t *g_deviceStateList = NULL;
54 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
55 static CABLEErrorHandleCallback g_clientErrorCallback;
56 static ca_thread_pool_t g_threadPoolHandle = NULL;
57 static jobject g_leScanCallback = NULL;
58 static jobject g_leGattCallback = NULL;
59 static jobject g_context = NULL;
60 static jobjectArray g_uuidList = NULL;
62 // it will be prevent to start send logic when adapter has stopped.
63 static bool g_isStartedLEClient = false;
64 static bool g_isStartedMulticastServer = false;
65 static bool g_isStartedScan = false;
67 static jbyteArray g_sendBuffer = NULL;
68 static uint32_t g_targetCnt = 0;
69 static uint32_t g_currentSentCnt = 0;
70 static bool g_isFinishedSendData = false;
71 static ca_mutex g_SendFinishMutex = NULL;
72 static ca_mutex g_threadMutex = NULL;
73 static ca_cond g_threadCond = NULL;
74 static ca_cond g_deviceDescCond = NULL;
76 static ca_mutex g_threadSendMutex = NULL;
78 static ca_mutex g_bleReqRespClientCbMutex = NULL;
79 static ca_mutex g_bleServerBDAddressMutex = NULL;
81 static ca_mutex g_deviceListMutex = NULL;
82 static ca_mutex g_gattObjectMutex = NULL;
83 static ca_mutex g_deviceStateListMutex = NULL;
85 static ca_mutex g_scanMutex = NULL;
87 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
90 void CALEClientJniInit()
92 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
93 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
96 void CALEClientJNISetContext()
98 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
99 g_context = (jobject) CANativeJNIGetContext();
102 CAResult_t CALECreateJniInterfaceObject()
104 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
108 OIC_LOG(ERROR, TAG, "g_context is null");
109 return CA_STATUS_FAILED;
114 OIC_LOG(ERROR, TAG, "g_jvm is null");
115 return CA_STATUS_FAILED;
118 bool isAttached = false;
120 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
123 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
124 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
128 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
129 return CA_STATUS_FAILED;
134 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
135 if (!jni_LEInterface)
137 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
141 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
142 "(Landroid/content/Context;)V");
143 if (!LeInterfaceConstructorMethod)
145 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
149 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
150 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
154 (*g_jvm)->DetachCurrentThread(g_jvm);
163 (*g_jvm)->DetachCurrentThread(g_jvm);
166 return CA_STATUS_FAILED;
169 CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
171 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
177 OIC_LOG(ERROR, TAG, "g_jvm is null");
178 return CA_STATUS_FAILED;
181 bool isAttached = false;
183 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
186 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
187 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
191 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
192 return CA_STATUS_FAILED;
197 CAResult_t ret = CALECheckPlatformVersion(env, 18);
198 if (CA_STATUS_OK != ret)
200 OIC_LOG(ERROR, TAG, "it is not supported");
204 (*g_jvm)->DetachCurrentThread(g_jvm);
210 g_threadPoolHandle = handle;
212 ret = CALEClientInitGattMutexVaraibles();
213 if (CA_STATUS_OK != ret)
215 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
216 CALEClientTerminateGattMutexVariables();
220 (*g_jvm)->DetachCurrentThread(g_jvm);
226 g_deviceDescCond = ca_cond_new();
228 // init mutex for send logic
229 g_threadCond = ca_cond_new();
231 CALEClientCreateDeviceList();
232 CALEClientJNISetContext();
234 ret = CALEClientCreateUUIDList();
235 if (CA_STATUS_OK != ret)
237 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
241 (*g_jvm)->DetachCurrentThread(g_jvm);
247 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
248 if (CA_STATUS_OK != ret)
250 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
254 (*g_jvm)->DetachCurrentThread(g_jvm);
259 g_isStartedLEClient = true;
263 (*g_jvm)->DetachCurrentThread(g_jvm);
269 void CALEClientTerminate()
271 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
275 OIC_LOG(ERROR, TAG, "g_jvm is null");
279 bool isAttached = false;
281 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
284 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
285 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
289 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
295 if (g_leScanCallback)
297 (*env)->DeleteGlobalRef(env, g_leScanCallback);
300 if (g_leGattCallback)
302 (*env)->DeleteGlobalRef(env, g_leGattCallback);
307 (*env)->DeleteGlobalRef(env, g_sendBuffer);
312 (*env)->DeleteGlobalRef(env, g_uuidList);
315 CAResult_t ret = CALEClientRemoveAllDeviceState();
316 if (CA_STATUS_OK != ret)
318 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
321 ret = CALEClientRemoveAllScanDevices(env);
322 if (CA_STATUS_OK != ret)
324 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
327 ret = CALEClientRemoveAllGattObjs(env);
328 if (CA_STATUS_OK != ret)
330 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
333 g_isStartedMulticastServer = false;
334 CALEClientSetScanFlag(false);
335 CALEClientSetSendFinishFlag(false);
337 CALEClientTerminateGattMutexVariables();
338 CALEClientDestroyJniInterface();
340 ca_cond_free(g_deviceDescCond);
341 ca_cond_free(g_threadCond);
343 g_deviceDescCond = NULL;
348 (*g_jvm)->DetachCurrentThread(g_jvm);
352 CAResult_t CALEClientDestroyJniInterface()
354 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
358 OIC_LOG(ERROR, TAG, "g_jvm is null");
359 return CA_STATUS_FAILED;
362 bool isAttached = false;
364 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
367 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
368 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
372 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
373 return CA_STATUS_FAILED;
378 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
379 if (!jni_LeInterface)
381 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
385 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
386 "destroyLeInterface",
388 if (!jni_InterfaceDestroyMethod)
390 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
394 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
396 if ((*env)->ExceptionCheck(env))
398 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
399 (*env)->ExceptionDescribe(env);
400 (*env)->ExceptionClear(env);
404 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
408 (*g_jvm)->DetachCurrentThread(g_jvm);
417 (*g_jvm)->DetachCurrentThread(g_jvm);
420 return CA_STATUS_FAILED;
423 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
425 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
426 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
430 CAResult_t res = CALEClientDisconnect(env, gatt);
431 if (CA_STATUS_OK != res)
433 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
436 CALEClientUpdateSendCnt(env);
439 CAResult_t CALEClientSendUnicastMessage(const char* address,
441 const uint32_t dataLen)
443 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
444 VERIFY_NON_NULL(address, TAG, "address is null");
445 VERIFY_NON_NULL(data, TAG, "data is null");
447 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
450 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
451 const uint32_t dataLen)
453 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
454 VERIFY_NON_NULL(data, TAG, "data is null");
458 OIC_LOG(ERROR, TAG, "g_jvm is null");
459 return CA_STATUS_FAILED;
462 bool isAttached = false;
464 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
467 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
468 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
472 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
473 return CA_STATUS_FAILED;
478 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
479 if (CA_STATUS_OK != ret)
481 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
486 (*g_jvm)->DetachCurrentThread(g_jvm);
492 CAResult_t CALEClientStartUnicastServer(const char* address)
494 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
496 return CA_NOT_SUPPORTED;
499 CAResult_t CALEClientStartMulticastServer()
501 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
503 if (g_isStartedMulticastServer)
505 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
506 return CA_STATUS_FAILED;
511 OIC_LOG(ERROR, TAG, "g_jvm is null");
512 return CA_STATUS_FAILED;
515 bool isAttached = false;
517 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
520 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
521 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
525 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
526 return CA_STATUS_FAILED;
531 g_isStartedMulticastServer = true;
532 CAResult_t ret = CALEClientStartScan();
533 if (CA_STATUS_OK != ret)
535 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
540 (*g_jvm)->DetachCurrentThread(g_jvm);
546 void CALEClientStopUnicastServer()
548 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
551 void CALEClientStopMulticastServer()
553 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
554 g_isStartedMulticastServer = false;
555 CAResult_t res = CALEClientStopScan();
556 if (CA_STATUS_OK != res)
558 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
563 void CALEClientSetCallback(CAPacketReceiveCallback callback)
565 g_packetReceiveCallback = callback;
568 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
570 g_clientErrorCallback = callback;
573 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
574 const uint32_t dataLen)
576 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
578 VERIFY_NON_NULL(address, TAG, "address is null");
579 VERIFY_NON_NULL(data, TAG, "data is null");
583 OIC_LOG(ERROR, TAG, "g_jvm is null");
584 return CA_STATUS_FAILED;
587 bool isAttached = false;
589 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
592 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
593 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
596 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
597 return CA_STATUS_FAILED;
602 ca_mutex_lock(g_threadSendMutex);
604 CAResult_t ret = CA_STATUS_OK;
605 if (g_context && g_deviceList)
607 uint32_t length = u_arraylist_length(g_deviceList);
608 for (uint32_t index = 0; index < length; index++)
610 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
613 OIC_LOG(ERROR, TAG, "jarrayObj is null");
617 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
620 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
624 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
627 OIC_LOG(ERROR, TAG, "setAddress is null");
631 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
633 if (!strcmp(setAddress, address))
635 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
637 // connect to gatt server
638 ret = CALEClientStopScan();
639 if (CA_STATUS_OK != ret)
641 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
647 (*env)->DeleteGlobalRef(env, g_sendBuffer);
649 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
650 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
651 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
653 ret = CALEClientSendData(env, jarrayObj);
654 if (CA_STATUS_OK != ret)
656 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
660 OIC_LOG(INFO, TAG, "wake up");
663 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
669 (*g_jvm)->DetachCurrentThread(g_jvm);
672 // start LE Scan again
673 ret = CALEClientStartScan();
674 if (CA_STATUS_OK != ret)
676 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
677 ca_mutex_unlock(g_threadSendMutex);
681 ca_mutex_unlock(g_threadSendMutex);
682 OIC_LOG(INFO, TAG, "unicast - send success");
688 // start LE Scan again
689 ret = CALEClientStartScan();
690 if (CA_STATUS_OK != ret)
692 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
693 ca_mutex_unlock(g_threadSendMutex);
696 (*g_jvm)->DetachCurrentThread(g_jvm);
703 (*g_jvm)->DetachCurrentThread(g_jvm);
706 if (g_clientErrorCallback)
708 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
710 ca_mutex_unlock(g_threadSendMutex);
711 return CA_SEND_FAILED;
714 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
715 const uint32_t dataLen)
717 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
718 VERIFY_NON_NULL(data, TAG, "data is null");
719 VERIFY_NON_NULL(env, TAG, "env is null");
723 OIC_LOG(ERROR, TAG, "g_deviceList is null");
724 return CA_STATUS_FAILED;
727 ca_mutex_lock(g_threadSendMutex);
729 CALEClientSetSendFinishFlag(false);
731 OIC_LOG(DEBUG, TAG, "set byteArray for data");
734 (*env)->DeleteGlobalRef(env, g_sendBuffer);
737 if (0 == u_arraylist_length(g_deviceList))
739 // Wait for LE peripherals to be discovered.
741 // Number of times to wait for discovery to complete.
742 static size_t const RETRIES = 5;
744 static uint64_t const TIMEOUT =
745 2 * MICROSECS_PER_SEC; // Microseconds
747 bool devicesDiscovered = false;
749 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
752 if (ca_cond_wait_for(g_deviceDescCond,
756 devicesDiscovered = true;
760 if (!devicesDiscovered)
766 // connect to gatt server
767 CAResult_t res = CALEClientStopScan();
768 if (CA_STATUS_OK != res)
770 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
771 ca_mutex_unlock(g_threadSendMutex);
774 uint32_t length = u_arraylist_length(g_deviceList);
775 g_targetCnt = length;
777 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
778 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
779 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
781 for (uint32_t index = 0; index < length; index++)
783 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
786 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
790 res = CALEClientSendData(env, jarrayObj);
791 if (res != CA_STATUS_OK)
793 OIC_LOG(ERROR, TAG, "BT device - send has failed");
796 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
799 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
803 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
806 OIC_LOG(ERROR, TAG, "address is not available");
810 (*env)->ReleaseStringUTFChars(env, jni_address, address);
813 OIC_LOG(DEBUG, TAG, "connection routine is finished");
815 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
816 if (!g_isFinishedSendData)
818 ca_mutex_lock(g_threadMutex);
819 ca_cond_wait(g_threadCond, g_threadMutex);
820 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
821 ca_mutex_unlock(g_threadMutex);
824 // start LE Scan again
825 res = CALEClientStartScan();
826 if (CA_STATUS_OK != res)
828 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
829 ca_mutex_unlock(g_threadSendMutex);
833 ca_mutex_unlock(g_threadSendMutex);
834 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
838 res = CALEClientStartScan();
839 if (CA_STATUS_OK != res)
841 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
842 ca_mutex_unlock(g_threadSendMutex);
846 ca_mutex_unlock(g_threadSendMutex);
847 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
848 return CA_SEND_FAILED;
851 CAResult_t CALECheckSendState(const char* address)
853 VERIFY_NON_NULL(address, TAG, "address is null");
855 ca_mutex_lock(g_deviceStateListMutex);
856 CALEState_t* state = CALEClientGetStateInfo(address);
859 OIC_LOG(ERROR, TAG, "state is null");
860 ca_mutex_unlock(g_deviceStateListMutex);
861 return CA_SEND_FAILED;
864 if (STATE_SEND_SUCCESS != state->sendState)
866 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
867 ca_mutex_unlock(g_deviceStateListMutex);
868 return CA_SEND_FAILED;
870 ca_mutex_unlock(g_deviceStateListMutex);
874 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
876 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
877 VERIFY_NON_NULL(device, TAG, "device is null");
878 VERIFY_NON_NULL(env, TAG, "env is null");
880 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
883 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
884 return CA_STATUS_FAILED;
887 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
890 OIC_LOG(ERROR, TAG, "address is not available");
891 return CA_STATUS_FAILED;
894 ca_mutex_lock(g_deviceStateListMutex);
895 CALEState_t* state = CALEClientGetStateInfo(address);
896 ca_mutex_unlock(g_deviceStateListMutex);
899 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
900 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
901 if (CA_STATUS_OK != ret)
903 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
904 (*env)->ReleaseStringUTFChars(env, jni_address, address);
910 if (STATE_CONNECTED == state->connectedState)
912 OIC_LOG(INFO, TAG, "GATT has already connected");
913 jobject gatt = CALEClientGetGattObjInList(env, address);
916 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
917 (*env)->ReleaseStringUTFChars(env, jni_address, address);
918 return CA_STATUS_FAILED;
921 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
922 if (CA_STATUS_OK != ret)
924 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
925 (*env)->ReleaseStringUTFChars(env, jni_address, address);
931 OIC_LOG(DEBUG, TAG, "start to connect LE");
932 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
933 if (CA_STATUS_OK != ret)
935 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
936 (*env)->ReleaseStringUTFChars(env, jni_address, address);
942 (*env)->ReleaseStringUTFChars(env, jni_address, address);
946 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
948 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
949 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
951 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
952 if (!jni_cid_gattdevice_list)
954 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
958 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
959 "()Landroid/bluetooth/BluetoothDevice;");
960 if (!jni_mid_getDevice)
962 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
966 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
969 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
973 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
976 OIC_LOG(ERROR, TAG, "jni_address is null");
986 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
989 OIC_LOG(DEBUG, TAG, "Gatt Close");
990 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
991 VERIFY_NON_NULL(env, TAG, "env is null");
993 // get BluetoothGatt class
994 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
995 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
996 if (!jni_cid_BluetoothGatt)
998 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
999 return CA_STATUS_FAILED;
1002 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1003 if (!jni_mid_closeGatt)
1005 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1006 return CA_STATUS_OK;
1009 // call disconnect gatt method
1010 OIC_LOG(DEBUG, TAG, "request to close GATT");
1011 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1013 if ((*env)->ExceptionCheck(env))
1015 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1016 (*env)->ExceptionDescribe(env);
1017 (*env)->ExceptionClear(env);
1018 return CA_STATUS_FAILED;
1021 return CA_STATUS_OK;
1024 CAResult_t CALEClientStartScan()
1026 if (!g_isStartedMulticastServer)
1028 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1029 return CA_STATUS_FAILED;
1032 if (!g_isStartedLEClient)
1034 OIC_LOG(ERROR, TAG, "LE client is not started");
1035 return CA_STATUS_FAILED;
1040 OIC_LOG(ERROR, TAG, "g_jvm is null");
1041 return CA_STATUS_FAILED;
1044 if (g_isStartedScan)
1046 OIC_LOG(INFO, TAG, "scanning is already started");
1047 return CA_STATUS_OK;
1050 bool isAttached = false;
1052 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1055 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1057 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1060 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1061 return CA_STATUS_FAILED;
1066 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1068 CAResult_t ret = CA_STATUS_OK;
1069 // scan gatt server with UUID
1070 if (g_leScanCallback && g_uuidList)
1073 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1074 if(CA_STATUS_OK != ret)
1076 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
1079 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1080 if (CA_STATUS_OK != ret)
1082 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
1089 (*g_jvm)->DetachCurrentThread(g_jvm);
1095 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1097 VERIFY_NON_NULL(callback, TAG, "callback is null");
1098 VERIFY_NON_NULL(env, TAG, "env is null");
1100 if (!CALEIsEnableBTAdapter(env))
1102 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1103 return CA_ADAPTER_NOT_ENABLED;
1106 // get default bt adapter class
1107 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1108 if (!jni_cid_BTAdapter)
1110 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1111 return CA_STATUS_FAILED;
1114 // get remote bt adapter method
1115 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1116 "getDefaultAdapter",
1117 METHODID_OBJECTNONPARAM);
1118 if (!jni_mid_getDefaultAdapter)
1120 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1121 return CA_STATUS_FAILED;
1124 // get start le scan method
1125 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1126 "(Landroid/bluetooth/BluetoothAdapter$"
1127 "LeScanCallback;)Z");
1128 if (!jni_mid_startLeScan)
1130 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1131 return CA_STATUS_FAILED;
1134 // gat bt adapter object
1135 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1136 jni_mid_getDefaultAdapter);
1137 if (!jni_obj_BTAdapter)
1139 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1140 return CA_STATUS_FAILED;
1143 // call start le scan method
1144 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1145 jni_mid_startLeScan, callback);
1146 if (!jni_obj_startLeScan)
1148 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1149 return CA_STATUS_FAILED;
1153 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1154 CALEClientSetScanFlag(true);
1157 return CA_STATUS_OK;
1160 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1162 VERIFY_NON_NULL(callback, TAG, "callback is null");
1163 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1164 VERIFY_NON_NULL(env, TAG, "env is null");
1166 if (!CALEIsEnableBTAdapter(env))
1168 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1169 return CA_ADAPTER_NOT_ENABLED;
1172 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1173 if (!jni_cid_BTAdapter)
1175 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1176 return CA_STATUS_FAILED;
1179 // get remote bt adapter method
1180 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1181 "getDefaultAdapter",
1182 METHODID_OBJECTNONPARAM);
1183 if (!jni_mid_getDefaultAdapter)
1185 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1186 return CA_STATUS_FAILED;
1189 // get start le scan method
1190 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1191 "([Ljava/util/UUID;Landroid/bluetooth/"
1192 "BluetoothAdapter$LeScanCallback;)Z");
1193 if (!jni_mid_startLeScan)
1195 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1196 return CA_STATUS_FAILED;
1199 // get bt adapter object
1200 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1201 jni_mid_getDefaultAdapter);
1202 if (!jni_obj_BTAdapter)
1204 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1205 return CA_STATUS_FAILED;
1208 // call start le scan method
1209 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1210 jni_mid_startLeScan, uuids, callback);
1211 if (!jni_obj_startLeScan)
1213 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1214 return CA_STATUS_FAILED;
1218 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1219 CALEClientSetScanFlag(true);
1222 return CA_STATUS_OK;
1225 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1227 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1228 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1231 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1234 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1238 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1239 "(Ljava/lang/String;)"
1240 "Ljava/util/UUID;");
1241 if (!jni_mid_fromString)
1243 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1247 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1248 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1252 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1256 return jni_obj_uuid;
1259 CAResult_t CALEClientStopScan()
1263 OIC_LOG(ERROR, TAG, "g_jvm is null");
1264 return CA_STATUS_FAILED;
1267 if (!g_isStartedScan)
1269 OIC_LOG(INFO, TAG, "scanning is already stopped");
1270 return CA_STATUS_OK;
1273 bool isAttached = false;
1275 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1278 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1279 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1282 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1283 return CA_STATUS_FAILED;
1288 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1289 if (CA_STATUS_OK != ret)
1291 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1295 CALEClientSetScanFlag(false);
1300 (*g_jvm)->DetachCurrentThread(g_jvm);
1306 void CALEClientSetScanFlag(bool flag)
1308 ca_mutex_lock(g_scanMutex);
1309 g_isStartedScan = flag;
1310 ca_mutex_unlock(g_scanMutex);
1313 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1315 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1316 VERIFY_NON_NULL(callback, TAG, "callback is null");
1317 VERIFY_NON_NULL(env, TAG, "env is null");
1319 if (!CALEIsEnableBTAdapter(env))
1321 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1322 return CA_ADAPTER_NOT_ENABLED;
1325 // get default bt adapter class
1326 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1327 if (!jni_cid_BTAdapter)
1329 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1330 return CA_STATUS_FAILED;
1333 // get remote bt adapter method
1334 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1335 "getDefaultAdapter",
1336 METHODID_OBJECTNONPARAM);
1337 if (!jni_mid_getDefaultAdapter)
1339 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1340 return CA_STATUS_FAILED;
1343 // get start le scan method
1344 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1345 "(Landroid/bluetooth/"
1346 "BluetoothAdapter$LeScanCallback;)V");
1347 if (!jni_mid_stopLeScan)
1349 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1350 return CA_STATUS_FAILED;
1353 // gat bt adapter object
1354 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1355 jni_mid_getDefaultAdapter);
1356 if (!jni_obj_BTAdapter)
1358 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1359 return CA_STATUS_FAILED;
1362 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1363 // call start le scan method
1364 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1365 if ((*env)->ExceptionCheck(env))
1367 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1368 (*env)->ExceptionDescribe(env);
1369 (*env)->ExceptionClear(env);
1370 return CA_STATUS_FAILED;
1373 return CA_STATUS_OK;
1376 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1379 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1380 VERIFY_NON_NULL(env, TAG, "env is null");
1381 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1382 VERIFY_NON_NULL(callback, TAG, "callback is null");
1384 if (!CALEIsEnableBTAdapter(env))
1386 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1387 return CA_ADAPTER_NOT_ENABLED;
1390 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1393 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1394 return CA_STATUS_FAILED;
1397 // get BluetoothDevice class
1398 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1399 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1400 if (!jni_cid_BluetoothDevice)
1402 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1403 return CA_STATUS_FAILED;
1406 // get connectGatt method
1407 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1408 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1409 "(Landroid/content/Context;ZLandroid/"
1410 "bluetooth/BluetoothGattCallback;)"
1411 "Landroid/bluetooth/BluetoothGatt;");
1412 if (!jni_mid_connectGatt)
1414 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1415 return CA_STATUS_FAILED;
1418 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1419 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1420 jni_mid_connectGatt,
1422 autoconnect, callback);
1423 if (!jni_obj_connectGatt)
1425 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1426 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1427 CALEClientUpdateSendCnt(env);
1428 return CA_STATUS_FAILED;
1432 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1434 return CA_STATUS_OK;
1437 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1439 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1440 VERIFY_NON_NULL(env, TAG, "env is null");
1441 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1443 if (!CALEIsEnableBTAdapter(env))
1445 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1446 return CA_ADAPTER_NOT_ENABLED;
1449 // get BluetoothGatt class
1450 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1451 if (!jni_cid_BluetoothGatt)
1453 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1454 return CA_STATUS_FAILED;
1457 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1458 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1459 "disconnect", "()V");
1460 if (!jni_mid_disconnectGatt)
1462 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1463 return CA_STATUS_FAILED;
1466 // call disconnect gatt method
1467 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1468 if ((*env)->ExceptionCheck(env))
1470 OIC_LOG(ERROR, TAG, "disconnect has failed");
1471 (*env)->ExceptionDescribe(env);
1472 (*env)->ExceptionClear(env);
1473 return CA_STATUS_FAILED;
1476 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1478 return CA_STATUS_OK;
1481 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1483 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1484 VERIFY_NON_NULL(env, TAG, "env is null");
1486 if (!g_gattObjectList)
1488 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1489 return CA_STATUS_FAILED;
1492 uint32_t length = u_arraylist_length(g_gattObjectList);
1493 for (uint32_t index = 0; index < length; index++)
1495 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1498 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1501 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1502 if (CA_STATUS_OK != res)
1504 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1509 OICFree(g_gattObjectList);
1510 g_gattObjectList = NULL;
1512 return CA_STATUS_OK;
1515 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1517 VERIFY_NON_NULL(env, TAG, "env is null");
1518 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1520 if (!CALEIsEnableBTAdapter(env))
1522 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1523 return CA_ADAPTER_NOT_ENABLED;
1526 // get BluetoothGatt class
1527 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1528 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1529 if (!jni_cid_BluetoothGatt)
1531 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1532 return CA_STATUS_FAILED;
1535 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1536 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1537 "discoverServices", "()Z");
1538 if (!jni_mid_discoverServices)
1540 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1541 return CA_STATUS_FAILED;
1543 // call disconnect gatt method
1544 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1545 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1548 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1549 return CA_STATUS_FAILED;
1552 return CA_STATUS_OK;
1555 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1557 VERIFY_NON_NULL(env, TAG, "env is null");
1558 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1561 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1562 if (!jni_obj_character)
1564 CALEClientSendFinish(env, gatt);
1565 return CA_STATUS_FAILED;
1568 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1569 if (CA_STATUS_OK != ret)
1571 CALEClientSendFinish(env, gatt);
1575 return CA_STATUS_OK;
1578 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1579 jobject gattCharacteristic)
1581 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1582 VERIFY_NON_NULL(env, TAG, "env is null");
1583 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1584 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1586 if (!CALEIsEnableBTAdapter(env))
1588 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1589 return CA_STATUS_FAILED;
1592 // get BluetoothGatt class
1593 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1594 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1595 if (!jni_cid_BluetoothGatt)
1597 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1598 return CA_STATUS_FAILED;
1601 OIC_LOG(DEBUG, TAG, "write characteristic method");
1602 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1603 "writeCharacteristic",
1604 "(Landroid/bluetooth/"
1605 "BluetoothGattCharacteristic;)Z");
1606 if (!jni_mid_writeCharacteristic)
1608 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1609 return CA_STATUS_FAILED;
1612 // call disconnect gatt method
1613 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1614 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1615 jni_mid_writeCharacteristic,
1616 gattCharacteristic);
1619 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1623 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1624 return CA_STATUS_FAILED;
1627 return CA_STATUS_OK;
1630 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1632 VERIFY_NON_NULL(env, TAG, "env is null");
1633 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1635 if (!CALEIsEnableBTAdapter(env))
1637 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1638 return CA_STATUS_FAILED;
1641 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1642 if (!jni_cid_BluetoothGatt)
1644 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1645 return CA_STATUS_FAILED;
1648 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1651 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1652 return CA_STATUS_FAILED;
1655 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1656 if (!jni_obj_GattCharacteristic)
1658 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1659 return CA_STATUS_FAILED;
1662 OIC_LOG(DEBUG, TAG, "read characteristic method");
1663 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1664 "readCharacteristic",
1665 "(Landroid/bluetooth/"
1666 "BluetoothGattCharacteristic;)Z");
1667 if (!jni_mid_readCharacteristic)
1669 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1670 return CA_STATUS_FAILED;
1673 // call disconnect gatt method
1674 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1675 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1676 jni_obj_GattCharacteristic);
1679 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1683 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1684 return CA_STATUS_FAILED;
1687 return CA_STATUS_OK;
1690 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1691 jobject characteristic)
1693 VERIFY_NON_NULL(env, TAG, "env is null");
1694 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1695 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1697 if (!CALEIsEnableBTAdapter(env))
1699 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1700 return CA_ADAPTER_NOT_ENABLED;
1703 // get BluetoothGatt class
1704 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1705 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1706 if (!jni_cid_BluetoothGatt)
1708 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1709 return CA_STATUS_FAILED;
1712 // set Characteristic Notification
1713 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1714 "setCharacteristicNotification",
1715 "(Landroid/bluetooth/"
1716 "BluetoothGattCharacteristic;Z)Z");
1717 if (!jni_mid_setNotification)
1719 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1720 return CA_STATUS_FAILED;
1723 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1724 characteristic, JNI_TRUE);
1725 if (JNI_TRUE == ret)
1727 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1731 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1732 return CA_STATUS_FAILED;
1735 return CA_STATUS_OK;
1738 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1740 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1741 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1742 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1744 if (!CALEIsEnableBTAdapter(env))
1746 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1750 // get BluetoothGatt class
1751 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1752 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1753 if (!jni_cid_BluetoothGatt)
1755 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1759 jmethodID jni_mid_getService = (*env)->GetMethodID(
1760 env, jni_cid_BluetoothGatt, "getService",
1761 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1762 if (!jni_mid_getService)
1764 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1768 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1769 if (!jni_obj_service_uuid)
1771 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1775 // get bluetooth gatt service
1776 OIC_LOG(DEBUG, TAG, "request to get service");
1777 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1778 jni_obj_service_uuid);
1779 if (!jni_obj_gattService)
1781 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1785 // get bluetooth gatt service class
1786 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1787 env, "android/bluetooth/BluetoothGattService");
1788 if (!jni_cid_BluetoothGattService)
1790 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1794 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1795 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1796 "getCharacteristic",
1797 "(Ljava/util/UUID;)"
1798 "Landroid/bluetooth/"
1799 "BluetoothGattCharacteristic;");
1800 if (!jni_mid_getCharacteristic)
1802 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1806 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1809 OIC_LOG(ERROR, TAG, "uuid is null");
1813 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1814 if (!jni_obj_tx_uuid)
1816 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1817 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1821 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1822 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1823 jni_mid_getCharacteristic,
1826 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1827 return jni_obj_GattCharacteristic;
1830 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1832 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1833 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1834 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1835 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1837 if (!CALEIsEnableBTAdapter(env))
1839 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1843 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1846 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1850 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1851 if (!jni_obj_GattCharacteristic)
1853 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1857 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1858 "/BluetoothGattCharacteristic");
1859 if (!jni_cid_BTGattCharacteristic)
1861 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1865 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1866 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1868 if (!jni_mid_setValue)
1870 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1874 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1876 if (JNI_TRUE == ret)
1878 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1882 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1887 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1888 "setWriteType", "(I)V");
1889 if (!jni_mid_setWriteType)
1891 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1895 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1896 "WRITE_TYPE_NO_RESPONSE", "I");
1897 if (!jni_fid_no_response)
1899 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1903 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1904 jni_fid_no_response);
1906 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1908 return jni_obj_GattCharacteristic;
1911 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1913 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1914 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1916 if (!CALEIsEnableBTAdapter(env))
1918 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1922 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1923 "BluetoothGattCharacteristic");
1924 if (!jni_cid_BTGattCharacteristic)
1926 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1930 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1931 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1933 if (!jni_mid_getValue)
1935 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1939 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1941 return jni_obj_data_array;
1944 CAResult_t CALEClientCreateUUIDList()
1948 OIC_LOG(ERROR, TAG, "g_jvm is null");
1949 return CA_STATUS_FAILED;
1952 bool isAttached = false;
1954 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1957 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1958 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1962 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1963 return CA_STATUS_FAILED;
1968 // create new object array
1969 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1970 if (!jni_cid_uuid_list)
1972 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1976 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1977 jni_cid_uuid_list, NULL);
1978 if (!jni_obj_uuid_list)
1980 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1985 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1988 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1991 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1993 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1997 (*g_jvm)->DetachCurrentThread(g_jvm);
2000 return CA_STATUS_OK;
2007 (*g_jvm)->DetachCurrentThread(g_jvm);
2009 return CA_STATUS_FAILED;
2012 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2013 jobject characteristic)
2015 VERIFY_NON_NULL(env, TAG, "env is null");
2016 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2017 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2019 if (!CALEIsEnableBTAdapter(env))
2021 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
2022 return CA_ADAPTER_NOT_ENABLED;
2025 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2026 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2027 "BluetoothGattCharacteristic");
2028 if (!jni_cid_BTGattCharacteristic)
2030 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2031 return CA_STATUS_FAILED;
2034 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2035 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2037 "(Ljava/util/UUID;)Landroid/bluetooth/"
2038 "BluetoothGattDescriptor;");
2039 if (!jni_mid_getDescriptor)
2041 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2042 return CA_STATUS_FAILED;
2045 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2046 if (!jni_obj_cc_uuid)
2048 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2049 return CA_STATUS_FAILED;
2052 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2053 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2054 jni_mid_getDescriptor, jni_obj_cc_uuid);
2055 if (!jni_obj_descriptor)
2057 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2058 return CA_NOT_SUPPORTED;
2061 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2062 jclass jni_cid_descriptor = (*env)->FindClass(env,
2063 "android/bluetooth/BluetoothGattDescriptor");
2064 if (!jni_cid_descriptor)
2066 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2067 return CA_STATUS_FAILED;
2070 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2071 if (!jni_mid_setValue)
2073 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2074 return CA_STATUS_FAILED;
2077 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2078 "ENABLE_NOTIFICATION_VALUE", "[B");
2079 if (!jni_fid_NotiValue)
2081 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2082 return CA_STATUS_FAILED;
2085 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2087 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2088 env, jni_obj_descriptor, jni_mid_setValue,
2089 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2092 OIC_LOG(DEBUG, TAG, "setValue success");
2096 OIC_LOG(ERROR, TAG, "setValue has failed");
2097 return CA_STATUS_FAILED;
2100 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2103 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2104 return CA_STATUS_FAILED;
2107 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2108 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2109 "(Landroid/bluetooth/"
2110 "BluetoothGattDescriptor;)Z");
2111 if (!jni_mid_writeDescriptor)
2113 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2114 return CA_STATUS_FAILED;
2117 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2118 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2119 jni_obj_descriptor);
2122 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2126 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2127 return CA_STATUS_FAILED;
2130 return CA_STATUS_OK;
2133 void CALEClientCreateScanDeviceList(JNIEnv *env)
2135 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2136 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2138 ca_mutex_lock(g_deviceListMutex);
2139 // create new object array
2140 if (g_deviceList == NULL)
2142 OIC_LOG(DEBUG, TAG, "Create device list");
2144 g_deviceList = u_arraylist_create();
2146 ca_mutex_unlock(g_deviceListMutex);
2149 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2151 VERIFY_NON_NULL(device, TAG, "device is null");
2152 VERIFY_NON_NULL(env, TAG, "env is null");
2154 ca_mutex_lock(g_deviceListMutex);
2158 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2159 ca_mutex_unlock(g_deviceListMutex);
2160 return CA_STATUS_FAILED;
2163 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2164 if (!jni_remoteAddress)
2166 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2167 ca_mutex_unlock(g_deviceListMutex);
2168 return CA_STATUS_FAILED;
2171 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2174 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2175 ca_mutex_unlock(g_deviceListMutex);
2176 return CA_STATUS_FAILED;
2179 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2181 jobject gdevice = (*env)->NewGlobalRef(env, device);
2182 u_arraylist_add(g_deviceList, gdevice);
2183 ca_cond_signal(g_deviceDescCond);
2184 OIC_LOG_V(DEBUG, TAG, "Added this Device[%d] in the List", remoteAddress);
2186 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2188 ca_mutex_unlock(g_deviceListMutex);
2190 return CA_STATUS_OK;
2193 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2195 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2196 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2200 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2204 uint32_t length = u_arraylist_length(g_deviceList);
2205 for (uint32_t index = 0; index < length; index++)
2207 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2210 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2214 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2215 if (!jni_setAddress)
2217 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2221 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2224 OIC_LOG(ERROR, TAG, "setAddress is null");
2228 if (!strcmp(remoteAddress, setAddress))
2230 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2234 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2237 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2242 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2244 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2245 VERIFY_NON_NULL(env, TAG, "env is null");
2247 ca_mutex_lock(g_deviceListMutex);
2251 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2252 ca_mutex_unlock(g_deviceListMutex);
2253 return CA_STATUS_FAILED;
2256 uint32_t length = u_arraylist_length(g_deviceList);
2257 for (uint32_t index = 0; index < length; index++)
2259 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2262 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2265 (*env)->DeleteGlobalRef(env, jarrayObj);
2268 OICFree(g_deviceList);
2269 g_deviceList = NULL;
2271 ca_mutex_unlock(g_deviceListMutex);
2272 return CA_STATUS_OK;
2275 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2277 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2278 VERIFY_NON_NULL(address, TAG, "address is null");
2279 VERIFY_NON_NULL(env, TAG, "env is null");
2281 ca_mutex_lock(g_deviceListMutex);
2285 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2286 ca_mutex_unlock(g_deviceListMutex);
2287 return CA_STATUS_FAILED;
2290 uint32_t length = u_arraylist_length(g_deviceList);
2291 for (uint32_t index = 0; index < length; index++)
2293 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2296 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2297 ca_mutex_unlock(g_deviceListMutex);
2298 return CA_STATUS_FAILED;
2301 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2302 if (!jni_setAddress)
2304 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2305 ca_mutex_unlock(g_deviceListMutex);
2306 return CA_STATUS_FAILED;
2309 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2312 OIC_LOG(ERROR, TAG, "setAddress is null");
2313 ca_mutex_unlock(g_deviceListMutex);
2314 return CA_STATUS_FAILED;
2317 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2320 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2321 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2322 ca_mutex_unlock(g_deviceListMutex);
2323 return CA_STATUS_FAILED;
2326 if (!strcmp(setAddress, remoteAddress))
2328 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2329 (*env)->DeleteGlobalRef(env, jarrayObj);
2330 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2331 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2333 if (NULL == u_arraylist_remove(g_deviceList, index))
2335 OIC_LOG(ERROR, TAG, "List removal failed.");
2336 ca_mutex_unlock(g_deviceListMutex);
2337 return CA_STATUS_FAILED;
2339 ca_mutex_unlock(g_deviceListMutex);
2340 return CA_STATUS_OK;
2342 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2343 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2346 ca_mutex_unlock(g_deviceListMutex);
2347 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2349 return CA_STATUS_OK;
2356 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2358 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2359 VERIFY_NON_NULL(env, TAG, "env is null");
2360 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2362 ca_mutex_lock(g_gattObjectMutex);
2364 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2365 if (!jni_remoteAddress)
2367 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2368 ca_mutex_unlock(g_gattObjectMutex);
2369 return CA_STATUS_FAILED;
2372 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2375 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2376 ca_mutex_unlock(g_gattObjectMutex);
2377 return CA_STATUS_FAILED;
2380 if (!CALEClientIsGattObjInList(env, remoteAddress))
2382 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2383 u_arraylist_add(g_gattObjectList, newGatt);
2384 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2387 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2388 ca_mutex_unlock(g_gattObjectMutex);
2389 return CA_STATUS_OK;
2392 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2394 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2395 VERIFY_NON_NULL(env, TAG, "env is null");
2396 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2398 uint32_t length = u_arraylist_length(g_gattObjectList);
2399 for (uint32_t index = 0; index < length; index++)
2402 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2405 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2409 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2410 if (!jni_setAddress)
2412 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2416 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2419 OIC_LOG(ERROR, TAG, "setAddress is null");
2423 if (!strcmp(remoteAddress, setAddress))
2425 OIC_LOG(DEBUG, TAG, "the device is already set");
2426 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2431 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2436 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2440 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2442 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2443 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2444 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2446 ca_mutex_lock(g_gattObjectMutex);
2447 uint32_t length = u_arraylist_length(g_gattObjectList);
2448 for (uint32_t index = 0; index < length; index++)
2450 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2453 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2454 ca_mutex_unlock(g_gattObjectMutex);
2458 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2459 if (!jni_setAddress)
2461 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2462 ca_mutex_unlock(g_gattObjectMutex);
2466 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2469 OIC_LOG(ERROR, TAG, "setAddress is null");
2470 ca_mutex_unlock(g_gattObjectMutex);
2474 if (!strcmp(remoteAddress, setAddress))
2476 OIC_LOG(DEBUG, TAG, "the device is already set");
2477 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2478 ca_mutex_unlock(g_gattObjectMutex);
2481 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2484 ca_mutex_unlock(g_gattObjectMutex);
2485 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2489 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2491 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2492 VERIFY_NON_NULL(env, TAG, "env is null");
2494 ca_mutex_lock(g_gattObjectMutex);
2495 if (!g_gattObjectList)
2497 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2498 ca_mutex_unlock(g_gattObjectMutex);
2499 return CA_STATUS_FAILED;
2502 uint32_t length = u_arraylist_length(g_gattObjectList);
2503 for (uint32_t index = 0; index < length; index++)
2505 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2508 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2511 (*env)->DeleteGlobalRef(env, jarrayObj);
2514 OICFree(g_gattObjectList);
2515 g_gattObjectList = NULL;
2516 ca_mutex_unlock(g_gattObjectMutex);
2517 return CA_STATUS_OK;
2520 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2522 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2523 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2524 VERIFY_NON_NULL(env, TAG, "env is null");
2526 ca_mutex_lock(g_gattObjectMutex);
2527 if (!g_gattObjectList)
2529 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2530 ca_mutex_unlock(g_gattObjectMutex);
2531 return CA_STATUS_FAILED;
2534 uint32_t length = u_arraylist_length(g_gattObjectList);
2535 for (uint32_t index = 0; index < length; index++)
2537 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2540 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2541 ca_mutex_unlock(g_gattObjectMutex);
2542 return CA_STATUS_FAILED;
2545 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2546 if (!jni_setAddress)
2548 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2549 ca_mutex_unlock(g_gattObjectMutex);
2550 return CA_STATUS_FAILED;
2553 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2556 OIC_LOG(ERROR, TAG, "setAddress is null");
2557 ca_mutex_unlock(g_gattObjectMutex);
2558 return CA_STATUS_FAILED;
2561 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2562 if (!jni_remoteAddress)
2564 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2565 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2566 ca_mutex_unlock(g_gattObjectMutex);
2567 return CA_STATUS_FAILED;
2570 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2573 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2574 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2575 ca_mutex_unlock(g_gattObjectMutex);
2576 return CA_STATUS_FAILED;
2579 if (!strcmp(setAddress, remoteAddress))
2581 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2582 (*env)->DeleteGlobalRef(env, jarrayObj);
2583 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2584 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2586 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2588 OIC_LOG(ERROR, TAG, "List removal failed.");
2589 ca_mutex_unlock(g_gattObjectMutex);
2590 return CA_STATUS_FAILED;
2592 ca_mutex_unlock(g_gattObjectMutex);
2593 return CA_STATUS_OK;
2595 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2596 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2599 ca_mutex_unlock(g_gattObjectMutex);
2600 OIC_LOG(DEBUG, TAG, "there are no target object");
2601 return CA_STATUS_OK;
2604 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2606 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2607 VERIFY_NON_NULL(addr, TAG, "addr is null");
2608 VERIFY_NON_NULL(env, TAG, "env is null");
2610 ca_mutex_lock(g_gattObjectMutex);
2611 if (!g_gattObjectList)
2613 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2614 ca_mutex_unlock(g_gattObjectMutex);
2615 return CA_STATUS_FAILED;
2618 uint32_t length = u_arraylist_length(g_gattObjectList);
2619 for (uint32_t index = 0; index < length; index++)
2621 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2624 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2625 ca_mutex_unlock(g_gattObjectMutex);
2626 return CA_STATUS_FAILED;
2629 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2630 if (!jni_setAddress)
2632 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2633 ca_mutex_unlock(g_gattObjectMutex);
2634 return CA_STATUS_FAILED;
2637 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2640 OIC_LOG(ERROR, TAG, "setAddress is null");
2641 ca_mutex_unlock(g_gattObjectMutex);
2642 return CA_STATUS_FAILED;
2645 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2648 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2649 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2650 ca_mutex_unlock(g_gattObjectMutex);
2651 return CA_STATUS_FAILED;
2654 if (!strcmp(setAddress, remoteAddress))
2656 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2657 (*env)->DeleteGlobalRef(env, jarrayObj);
2659 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2660 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2661 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2663 OIC_LOG(ERROR, TAG, "List removal failed.");
2664 ca_mutex_unlock(g_gattObjectMutex);
2665 return CA_STATUS_FAILED;
2667 ca_mutex_unlock(g_gattObjectMutex);
2668 return CA_STATUS_OK;
2670 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2671 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2674 ca_mutex_unlock(g_gattObjectMutex);
2675 OIC_LOG(DEBUG, TAG, "there are no target object");
2676 return CA_STATUS_FAILED;
2683 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2684 uint16_t notificationState, uint16_t sendState)
2686 VERIFY_NON_NULL(address, TAG, "address is null");
2688 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2691 OIC_LOG(ERROR, TAG, "out of memory");
2692 return CA_MEMORY_ALLOC_FAILED;
2695 if (strlen(address) > CA_MACADDR_SIZE)
2697 OIC_LOG(ERROR, TAG, "address is not proper");
2699 return CA_STATUS_FAILED;
2702 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2703 newstate->connectedState = connectedState;
2704 newstate->notificationState = notificationState;
2705 newstate->sendState = sendState;
2706 return CALEClientAddDeviceStateToList(newstate);
2709 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2711 VERIFY_NON_NULL(state, TAG, "state is null");
2713 ca_mutex_lock(g_deviceStateListMutex);
2715 if (!g_deviceStateList)
2717 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2718 ca_mutex_unlock(g_deviceStateListMutex);
2719 return CA_STATUS_FAILED;
2722 if (CALEClientIsDeviceInList(state->address))
2724 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2727 OIC_LOG(ERROR, TAG, "curState is null");
2728 ca_mutex_unlock(g_deviceStateListMutex);
2729 return CA_STATUS_FAILED;
2732 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2734 state->notificationState = curState->notificationState;
2737 // delete previous state for update new state
2738 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2739 if (CA_STATUS_OK != res)
2741 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2742 ca_mutex_unlock(g_deviceStateListMutex);
2746 u_arraylist_add(g_deviceStateList, state); // update new state
2747 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2748 state->connectedState, state->notificationState);
2750 ca_mutex_unlock(g_deviceStateListMutex);
2751 return CA_STATUS_OK;
2754 bool CALEClientIsDeviceInList(const char* remoteAddress)
2756 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2758 if (!g_deviceStateList)
2760 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2764 uint32_t length = u_arraylist_length(g_deviceStateList);
2765 for (uint32_t index = 0; index < length; index++)
2767 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2770 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2774 if (!strcmp(remoteAddress, state->address))
2776 OIC_LOG(DEBUG, TAG, "the device is already set");
2785 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2789 CAResult_t CALEClientRemoveAllDeviceState()
2791 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2793 ca_mutex_lock(g_deviceStateListMutex);
2794 if (!g_deviceStateList)
2796 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2797 ca_mutex_unlock(g_deviceStateListMutex);
2798 return CA_STATUS_FAILED;
2801 uint32_t length = u_arraylist_length(g_deviceStateList);
2802 for (uint32_t index = 0; index < length; index++)
2804 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2807 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2813 OICFree(g_deviceStateList);
2814 g_deviceStateList = NULL;
2815 ca_mutex_unlock(g_deviceStateListMutex);
2817 return CA_STATUS_OK;
2820 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2822 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2823 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2825 if (!g_deviceStateList)
2827 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2828 return CA_STATUS_FAILED;
2831 uint32_t length = u_arraylist_length(g_deviceStateList);
2832 for (uint32_t index = 0; index < length; index++)
2834 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2837 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2841 if (!strcmp(state->address, remoteAddress))
2843 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2846 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2848 OIC_LOG(ERROR, TAG, "List removal failed.");
2849 return CA_STATUS_FAILED;
2852 return CA_STATUS_OK;
2856 return CA_STATUS_FAILED;
2859 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2861 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2862 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2864 if (!g_deviceStateList)
2866 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2870 uint32_t length = u_arraylist_length(g_deviceStateList);
2871 for (uint32_t index = 0; index < length; index++)
2873 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2876 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2880 if (!strcmp(state->address, remoteAddress))
2882 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2889 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2891 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2892 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2894 ca_mutex_lock(g_deviceStateListMutex);
2895 if (!g_deviceStateList)
2897 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2898 ca_mutex_unlock(g_deviceStateListMutex);
2902 uint32_t length = u_arraylist_length(g_deviceStateList);
2903 for (uint32_t index = 0; index < length; index++)
2905 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2908 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2912 if (!strcmp(state->address, remoteAddress))
2914 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2916 if (STATE_CONNECTED == state->connectedState)
2918 ca_mutex_unlock(g_deviceStateListMutex);
2923 ca_mutex_unlock(g_deviceStateListMutex);
2928 ca_mutex_unlock(g_deviceStateListMutex);
2932 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2934 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2935 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2937 ca_mutex_lock(g_deviceStateListMutex);
2938 if (!g_deviceStateList)
2940 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2941 ca_mutex_unlock(g_deviceStateListMutex);
2945 uint32_t length = u_arraylist_length(g_deviceStateList);
2946 for (uint32_t index = 0; index < length; index++)
2948 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2951 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2955 if (!strcmp(state->address, remoteAddress))
2957 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2959 if (STATE_CHARACTER_SET == state->notificationState)
2961 ca_mutex_unlock(g_deviceStateListMutex);
2966 ca_mutex_unlock(g_deviceStateListMutex);
2972 ca_mutex_unlock(g_deviceStateListMutex);
2976 void CALEClientCreateDeviceList()
2978 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2980 // create new object array
2981 if (!g_gattObjectList)
2983 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2985 g_gattObjectList = u_arraylist_create();
2988 if (!g_deviceStateList)
2990 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2992 g_deviceStateList = u_arraylist_create();
2997 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2999 g_deviceList = u_arraylist_create();
3004 * Check Sent Count for remove g_sendBuffer
3006 void CALEClientUpdateSendCnt(JNIEnv *env)
3008 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3010 ca_mutex_lock(g_threadMutex);
3014 if (g_targetCnt <= g_currentSentCnt)
3017 g_currentSentCnt = 0;
3021 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3022 g_sendBuffer = NULL;
3024 // notity the thread
3025 ca_cond_signal(g_threadCond);
3026 CALEClientSetSendFinishFlag(true);
3027 OIC_LOG(DEBUG, TAG, "set signal for send data");
3030 ca_mutex_unlock(g_threadMutex);
3033 CAResult_t CALEClientInitGattMutexVaraibles()
3035 if (NULL == g_bleReqRespClientCbMutex)
3037 g_bleReqRespClientCbMutex = ca_mutex_new();
3038 if (NULL == g_bleReqRespClientCbMutex)
3040 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3041 return CA_STATUS_FAILED;
3045 if (NULL == g_bleServerBDAddressMutex)
3047 g_bleServerBDAddressMutex = ca_mutex_new();
3048 if (NULL == g_bleServerBDAddressMutex)
3050 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3051 return CA_STATUS_FAILED;
3055 if (NULL == g_threadMutex)
3057 g_threadMutex = ca_mutex_new();
3058 if (NULL == g_threadMutex)
3060 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3061 return CA_STATUS_FAILED;
3065 if (NULL == g_threadSendMutex)
3067 g_threadSendMutex = ca_mutex_new();
3068 if (NULL == g_threadSendMutex)
3070 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3071 return CA_STATUS_FAILED;
3075 if (NULL == g_deviceListMutex)
3077 g_deviceListMutex = ca_mutex_new();
3078 if (NULL == g_deviceListMutex)
3080 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3081 return CA_STATUS_FAILED;
3085 if (NULL == g_gattObjectMutex)
3087 g_gattObjectMutex = ca_mutex_new();
3088 if (NULL == g_gattObjectMutex)
3090 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3091 return CA_STATUS_FAILED;
3095 if (NULL == g_deviceStateListMutex)
3097 g_deviceStateListMutex = ca_mutex_new();
3098 if (NULL == g_deviceStateListMutex)
3100 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3101 return CA_STATUS_FAILED;
3105 if (NULL == g_SendFinishMutex)
3107 g_SendFinishMutex = ca_mutex_new();
3108 if (NULL == g_SendFinishMutex)
3110 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3111 return CA_STATUS_FAILED;
3115 if (NULL == g_scanMutex)
3117 g_scanMutex = ca_mutex_new();
3118 if (NULL == g_scanMutex)
3120 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3121 return CA_STATUS_FAILED;
3125 return CA_STATUS_OK;
3128 void CALEClientTerminateGattMutexVariables()
3130 ca_mutex_free(g_bleReqRespClientCbMutex);
3131 g_bleReqRespClientCbMutex = NULL;
3133 ca_mutex_free(g_bleServerBDAddressMutex);
3134 g_bleServerBDAddressMutex = NULL;
3136 ca_mutex_free(g_threadMutex);
3137 g_threadMutex = NULL;
3139 ca_mutex_free(g_threadSendMutex);
3140 g_threadSendMutex = NULL;
3142 ca_mutex_free(g_deviceListMutex);
3143 g_deviceListMutex = NULL;
3145 ca_mutex_free(g_SendFinishMutex);
3146 g_SendFinishMutex = NULL;
3148 ca_mutex_free(g_scanMutex);
3152 void CALEClientSetSendFinishFlag(bool flag)
3154 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3156 ca_mutex_lock(g_SendFinishMutex);
3157 g_isFinishedSendData = flag;
3158 ca_mutex_unlock(g_SendFinishMutex);
3165 CAResult_t CAStartLEGattClient()
3167 CAResult_t res = CALEClientStartMulticastServer();
3168 if (CA_STATUS_OK != res)
3170 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3174 g_isStartedLEClient = true;
3180 void CAStopLEGattClient()
3182 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3186 OIC_LOG(ERROR, TAG, "g_jvm is null");
3190 bool isAttached = false;
3192 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3195 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3196 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3200 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3206 CAResult_t ret = CALEClientDisconnectAll(env);
3207 if (CA_STATUS_OK != ret)
3209 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3212 ret = CALEClientStopScan();
3213 if(CA_STATUS_OK != ret)
3215 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3218 ca_cond_signal(g_threadCond);
3222 (*g_jvm)->DetachCurrentThread(g_jvm);
3227 void CATerminateLEGattClient()
3229 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3230 CALEClientTerminate();
3233 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3234 uint32_t dataLen, CALETransferType_t type,
3237 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3238 VERIFY_NON_NULL(data, TAG, "data is null");
3239 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3241 if (LE_UNICAST != type || position < 0)
3243 OIC_LOG(ERROR, TAG, "this request is not unicast");
3244 return CA_STATUS_INVALID_PARAM;
3247 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3250 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3252 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3253 VERIFY_NON_NULL(data, TAG, "data is null");
3255 return CALEClientSendMulticastMessage(data, dataLen);
3258 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3260 ca_mutex_lock(g_bleReqRespClientCbMutex);
3261 g_CABLEClientDataReceivedCallback = callback;
3262 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3265 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3267 CALEClientInitialize(handle);
3270 CAResult_t CAGetLEAddress(char **local_address)
3272 VERIFY_NON_NULL(local_address, TAG, "local_address");
3273 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3274 return CA_NOT_SUPPORTED;
3277 JNIEXPORT void JNICALL
3278 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3281 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3282 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3283 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3284 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3286 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3289 JNIEXPORT void JNICALL
3290 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3293 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3294 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3295 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3296 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3298 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3301 JNIEXPORT void JNICALL
3302 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3305 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3306 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3307 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3309 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3310 if (CA_STATUS_OK != res)
3312 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3317 * Class: org_iotivity_ca_jar_caleinterface
3318 * Method: CALeGattConnectionStateChangeCallback
3319 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3321 JNIEXPORT void JNICALL
3322 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3328 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3330 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3331 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3332 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3334 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3336 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3342 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3345 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3346 STATE_CHARACTER_NO_CHANGE,
3348 if (CA_STATUS_OK != res)
3350 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3351 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3354 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3357 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3358 if (CA_STATUS_OK != res)
3360 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3364 res = CALEClientDiscoverServices(env, gatt);
3365 if (CA_STATUS_OK != res)
3367 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3371 else // le disconnected
3373 CAResult_t res = CALEClientStartScan();
3374 if (CA_STATUS_OK != res)
3376 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3380 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3383 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3387 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3390 res = CALEClientRemoveDeviceState(address);
3391 if (CA_STATUS_OK != res)
3393 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3397 res = CALEClientRemoveGattObjForAddr(env, jni_address);
3398 if (CA_STATUS_OK != res)
3400 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
3404 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3407 res = CALEClientGattClose(env, gatt);
3408 if (CA_STATUS_OK != res)
3410 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3418 CALEClientSendFinish(env, gatt);
3423 * Class: org_iotivity_ca_jar_caleinterface
3424 * Method: CALeGattServicesDiscoveredCallback
3425 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3427 JNIEXPORT void JNICALL
3428 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3433 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3434 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3435 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3436 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3438 if (0 != status) // discovery error
3440 CALEClientSendFinish(env, gatt);
3444 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3447 CALEClientSendFinish(env, gatt);
3451 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3454 CALEClientSendFinish(env, gatt);
3458 if (!CALEClientIsSetCharacteristic(address))
3460 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3463 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3467 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3468 if (!jni_obj_GattCharacteristic)
3470 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3474 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3475 jni_obj_GattCharacteristic);
3476 if (CA_STATUS_OK != res)
3478 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3482 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3483 if (CA_STATUS_OK != res)
3485 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
3486 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3487 if (CA_STATUS_OK != res)
3489 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3494 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3496 if (CA_STATUS_OK != res)
3498 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3504 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3505 if (CA_STATUS_OK != res)
3507 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3511 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3516 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3517 CALEClientSendFinish(env, gatt);
3522 * Class: org_iotivity_ca_jar_caleinterface
3523 * Method: CALeGattCharacteristicWritjclasseCallback
3524 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3526 JNIEXPORT void JNICALL
3527 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3528 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3531 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3532 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3533 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3534 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3537 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3539 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3541 // send success & signal
3542 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3548 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3554 if (GATT_SUCCESS != status) // error case
3556 OIC_LOG(ERROR, TAG, "send failure");
3557 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3559 if (CA_STATUS_OK != res)
3561 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3564 if (g_clientErrorCallback)
3566 jint length = (*env)->GetArrayLength(env, data);
3567 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
3570 CALEClientSendFinish(env, gatt);
3574 OIC_LOG(DEBUG, TAG, "send success");
3575 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3576 STATE_SEND_SUCCESS);
3577 if (CA_STATUS_OK != res)
3579 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3581 CALEClientUpdateSendCnt(env);
3584 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3590 CALEClientSendFinish(env, gatt);
3595 * Class: org_iotivity_ca_jar_caleinterface
3596 * Method: CALeGattCharacteristicChangedCallback
3597 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3599 JNIEXPORT void JNICALL
3600 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3601 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3603 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3604 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3605 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3606 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3607 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3609 // get Byte Array and convert to uint8_t*
3610 jint length = (*env)->GetArrayLength(env, data);
3613 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3615 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3616 jni_byte_responseData);
3618 uint8_t* receivedData = OICMalloc(length);
3621 OIC_LOG(ERROR, TAG, "receivedData is null");
3625 memcpy(receivedData, jni_byte_responseData, length);
3626 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3628 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3631 OIC_LOG(ERROR, TAG, "jni_address is null");
3632 OICFree(receivedData);
3636 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3639 OIC_LOG(ERROR, TAG, "address is null");
3640 OICFree(receivedData);
3644 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3645 receivedData, length);
3647 ca_mutex_lock(g_bleServerBDAddressMutex);
3648 uint32_t sentLength = 0;
3649 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3651 ca_mutex_unlock(g_bleServerBDAddressMutex);
3653 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3657 * Class: org_iotivity_ca_jar_caleinterface
3658 * Method: CALeGattDescriptorWriteCallback
3659 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3661 JNIEXPORT void JNICALL
3662 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3666 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3667 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3668 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3669 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3671 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3672 if (CA_STATUS_OK != res)
3674 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3682 CALEClientSendFinish(env, gatt);