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
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 jobject g_leScanCallback = NULL;
57 static jobject g_leGattCallback = NULL;
58 static jobject g_context = NULL;
59 static jobjectArray g_uuidList = NULL;
61 // it will be prevent to start send logic when adapter has stopped.
62 static bool g_isStartedLEClient = false;
63 static bool g_isStartedMulticastServer = false;
64 static bool g_isStartedScan = false;
66 static jbyteArray g_sendBuffer = NULL;
67 static uint32_t g_targetCnt = 0;
68 static uint32_t g_currentSentCnt = 0;
69 static bool g_isFinishedSendData = false;
70 static ca_mutex g_SendFinishMutex = NULL;
71 static ca_mutex g_threadMutex = NULL;
72 static ca_cond g_threadCond = NULL;
73 static ca_cond g_deviceDescCond = NULL;
75 static ca_mutex g_threadSendMutex = NULL;
77 static ca_mutex g_bleReqRespClientCbMutex = NULL;
78 static ca_mutex g_bleServerBDAddressMutex = NULL;
80 static ca_mutex g_deviceListMutex = NULL;
81 static ca_mutex g_gattObjectMutex = NULL;
82 static ca_mutex g_deviceStateListMutex = NULL;
84 static ca_mutex g_scanMutex = NULL;
86 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
89 void CALEClientJniInit()
91 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
92 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
95 void CALEClientJNISetContext()
97 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
98 g_context = (jobject) CANativeJNIGetContext();
101 CAResult_t CALECreateJniInterfaceObject()
103 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
107 OIC_LOG(ERROR, TAG, "g_context is null");
108 return CA_STATUS_FAILED;
113 OIC_LOG(ERROR, TAG, "g_jvm is null");
114 return CA_STATUS_FAILED;
117 bool isAttached = false;
119 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
122 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
123 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
127 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
128 return CA_STATUS_FAILED;
133 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
134 if (!jni_LEInterface)
136 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
140 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
141 "(Landroid/content/Context;)V");
142 if (!LeInterfaceConstructorMethod)
144 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
148 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
149 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
153 (*g_jvm)->DetachCurrentThread(g_jvm);
162 (*g_jvm)->DetachCurrentThread(g_jvm);
165 return CA_STATUS_FAILED;
168 CAResult_t CALEClientInitialize()
170 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
176 OIC_LOG(ERROR, TAG, "g_jvm is null");
177 return CA_STATUS_FAILED;
180 bool isAttached = false;
182 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
185 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
186 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
190 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
191 return CA_STATUS_FAILED;
196 CAResult_t ret = CALECheckPlatformVersion(env, 18);
197 if (CA_STATUS_OK != ret)
199 OIC_LOG(ERROR, TAG, "it is not supported");
203 (*g_jvm)->DetachCurrentThread(g_jvm);
209 ret = CALEClientInitGattMutexVaraibles();
210 if (CA_STATUS_OK != ret)
212 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
213 CALEClientTerminateGattMutexVariables();
217 (*g_jvm)->DetachCurrentThread(g_jvm);
223 g_deviceDescCond = ca_cond_new();
225 // init mutex for send logic
226 g_threadCond = ca_cond_new();
228 CALEClientCreateDeviceList();
229 CALEClientJNISetContext();
231 ret = CALEClientCreateUUIDList();
232 if (CA_STATUS_OK != ret)
234 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
238 (*g_jvm)->DetachCurrentThread(g_jvm);
244 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
245 if (CA_STATUS_OK != ret)
247 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
251 (*g_jvm)->DetachCurrentThread(g_jvm);
256 g_isStartedLEClient = true;
260 (*g_jvm)->DetachCurrentThread(g_jvm);
266 void CALEClientTerminate()
268 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
272 OIC_LOG(ERROR, TAG, "g_jvm is null");
276 bool isAttached = false;
278 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
281 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
282 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
286 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
292 if (g_leScanCallback)
294 (*env)->DeleteGlobalRef(env, g_leScanCallback);
297 if (g_leGattCallback)
299 (*env)->DeleteGlobalRef(env, g_leGattCallback);
304 (*env)->DeleteGlobalRef(env, g_sendBuffer);
309 (*env)->DeleteGlobalRef(env, g_uuidList);
312 CAResult_t ret = CALEClientRemoveAllDeviceState();
313 if (CA_STATUS_OK != ret)
315 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
318 ret = CALEClientRemoveAllScanDevices(env);
319 if (CA_STATUS_OK != ret)
321 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
324 ret = CALEClientRemoveAllGattObjs(env);
325 if (CA_STATUS_OK != ret)
327 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
330 g_isStartedMulticastServer = false;
331 CALEClientSetScanFlag(false);
332 CALEClientSetSendFinishFlag(false);
334 CALEClientTerminateGattMutexVariables();
335 CALEClientDestroyJniInterface();
337 ca_cond_free(g_deviceDescCond);
338 ca_cond_free(g_threadCond);
340 g_deviceDescCond = NULL;
345 (*g_jvm)->DetachCurrentThread(g_jvm);
349 CAResult_t CALEClientDestroyJniInterface()
351 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
355 OIC_LOG(ERROR, TAG, "g_jvm is null");
356 return CA_STATUS_FAILED;
359 bool isAttached = false;
361 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
364 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
365 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
369 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
370 return CA_STATUS_FAILED;
375 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
376 if (!jni_LeInterface)
378 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
382 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
383 "destroyLeInterface",
385 if (!jni_InterfaceDestroyMethod)
387 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
391 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
393 if ((*env)->ExceptionCheck(env))
395 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
396 (*env)->ExceptionDescribe(env);
397 (*env)->ExceptionClear(env);
401 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
405 (*g_jvm)->DetachCurrentThread(g_jvm);
414 (*g_jvm)->DetachCurrentThread(g_jvm);
417 return CA_STATUS_FAILED;
420 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
422 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
423 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
427 CAResult_t res = CALEClientDisconnect(env, gatt);
428 if (CA_STATUS_OK != res)
430 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
433 CALEClientUpdateSendCnt(env);
436 CAResult_t CALEClientSendUnicastMessage(const char* address,
438 const uint32_t dataLen)
440 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
441 VERIFY_NON_NULL(address, TAG, "address is null");
442 VERIFY_NON_NULL(data, TAG, "data is null");
444 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
447 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
448 const uint32_t dataLen)
450 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
451 VERIFY_NON_NULL(data, TAG, "data is null");
455 OIC_LOG(ERROR, TAG, "g_jvm is null");
456 return CA_STATUS_FAILED;
459 bool isAttached = false;
461 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
464 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
465 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
469 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
470 return CA_STATUS_FAILED;
475 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
476 if (CA_STATUS_OK != ret)
478 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
483 (*g_jvm)->DetachCurrentThread(g_jvm);
489 CAResult_t CALEClientStartUnicastServer(const char* address)
491 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
493 return CA_NOT_SUPPORTED;
496 CAResult_t CALEClientStartMulticastServer()
498 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
500 if (g_isStartedMulticastServer)
502 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
503 return CA_STATUS_FAILED;
508 OIC_LOG(ERROR, TAG, "g_jvm is null");
509 return CA_STATUS_FAILED;
512 bool isAttached = false;
514 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
517 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
518 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
522 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
523 return CA_STATUS_FAILED;
528 g_isStartedMulticastServer = true;
529 CAResult_t ret = CALEClientStartScan();
530 if (CA_STATUS_OK != ret)
532 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
537 (*g_jvm)->DetachCurrentThread(g_jvm);
543 void CALEClientStopUnicastServer()
545 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
548 void CALEClientStopMulticastServer()
550 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
551 g_isStartedMulticastServer = false;
552 CAResult_t res = CALEClientStopScan();
553 if (CA_STATUS_OK != res)
555 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
560 void CALEClientSetCallback(CAPacketReceiveCallback callback)
562 g_packetReceiveCallback = callback;
565 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
567 g_clientErrorCallback = callback;
570 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
571 const uint32_t dataLen)
573 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
575 VERIFY_NON_NULL(address, TAG, "address is null");
576 VERIFY_NON_NULL(data, TAG, "data is null");
580 OIC_LOG(ERROR, TAG, "g_jvm is null");
581 return CA_STATUS_FAILED;
584 bool isAttached = false;
586 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
589 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
590 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
593 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
594 return CA_STATUS_FAILED;
599 ca_mutex_lock(g_threadSendMutex);
601 CAResult_t ret = CA_STATUS_OK;
602 if (g_context && g_deviceList)
604 uint32_t length = u_arraylist_length(g_deviceList);
605 for (uint32_t index = 0; index < length; index++)
607 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
610 OIC_LOG(ERROR, TAG, "jarrayObj is null");
614 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
617 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
621 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
624 OIC_LOG(ERROR, TAG, "setAddress is null");
628 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
630 if (!strcmp(setAddress, address))
632 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
634 // connect to gatt server
635 ret = CALEClientStopScan();
636 if (CA_STATUS_OK != ret)
638 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
644 (*env)->DeleteGlobalRef(env, g_sendBuffer);
646 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
647 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
648 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
650 ret = CALEClientSendData(env, jarrayObj);
651 if (CA_STATUS_OK != ret)
653 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
657 OIC_LOG(INFO, TAG, "wake up");
660 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
666 (*g_jvm)->DetachCurrentThread(g_jvm);
669 // start LE Scan again
670 ret = CALEClientStartScan();
671 if (CA_STATUS_OK != ret)
673 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
674 ca_mutex_unlock(g_threadSendMutex);
678 ca_mutex_unlock(g_threadSendMutex);
679 OIC_LOG(INFO, TAG, "unicast - send success");
685 // start LE Scan again
686 ret = CALEClientStartScan();
687 if (CA_STATUS_OK != ret)
689 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
690 ca_mutex_unlock(g_threadSendMutex);
693 (*g_jvm)->DetachCurrentThread(g_jvm);
700 (*g_jvm)->DetachCurrentThread(g_jvm);
703 if (g_clientErrorCallback)
705 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
707 ca_mutex_unlock(g_threadSendMutex);
708 return CA_SEND_FAILED;
711 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
712 const uint32_t dataLen)
714 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
715 VERIFY_NON_NULL(data, TAG, "data is null");
716 VERIFY_NON_NULL(env, TAG, "env is null");
720 OIC_LOG(ERROR, TAG, "g_deviceList is null");
721 return CA_STATUS_FAILED;
724 ca_mutex_lock(g_threadSendMutex);
726 CALEClientSetSendFinishFlag(false);
728 OIC_LOG(DEBUG, TAG, "set byteArray for data");
731 (*env)->DeleteGlobalRef(env, g_sendBuffer);
734 if (0 == u_arraylist_length(g_deviceList))
736 // Wait for LE peripherals to be discovered.
738 // Number of times to wait for discovery to complete.
739 static size_t const RETRIES = 5;
741 static uint64_t const TIMEOUT =
742 2 * MICROSECS_PER_SEC; // Microseconds
744 bool devicesDiscovered = false;
746 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
749 if (ca_cond_wait_for(g_deviceDescCond,
753 devicesDiscovered = true;
757 if (!devicesDiscovered)
763 // connect to gatt server
764 CAResult_t res = CALEClientStopScan();
765 if (CA_STATUS_OK != res)
767 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
768 ca_mutex_unlock(g_threadSendMutex);
771 uint32_t length = u_arraylist_length(g_deviceList);
772 g_targetCnt = length;
774 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
775 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
776 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
778 for (uint32_t index = 0; index < length; index++)
780 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
783 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
787 res = CALEClientSendData(env, jarrayObj);
788 if (res != CA_STATUS_OK)
790 OIC_LOG(ERROR, TAG, "BT device - send has failed");
793 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
796 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
800 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
803 OIC_LOG(ERROR, TAG, "address is not available");
807 (*env)->ReleaseStringUTFChars(env, jni_address, address);
810 OIC_LOG(DEBUG, TAG, "connection routine is finished");
812 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
813 if (!g_isFinishedSendData)
815 ca_mutex_lock(g_threadMutex);
816 ca_cond_wait(g_threadCond, g_threadMutex);
817 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
818 ca_mutex_unlock(g_threadMutex);
821 // start LE Scan again
822 res = CALEClientStartScan();
823 if (CA_STATUS_OK != res)
825 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
826 ca_mutex_unlock(g_threadSendMutex);
830 ca_mutex_unlock(g_threadSendMutex);
831 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
835 res = CALEClientStartScan();
836 if (CA_STATUS_OK != res)
838 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
839 ca_mutex_unlock(g_threadSendMutex);
843 ca_mutex_unlock(g_threadSendMutex);
844 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
845 return CA_SEND_FAILED;
848 CAResult_t CALECheckSendState(const char* address)
850 VERIFY_NON_NULL(address, TAG, "address is null");
852 ca_mutex_lock(g_deviceStateListMutex);
853 CALEState_t* state = CALEClientGetStateInfo(address);
856 OIC_LOG(ERROR, TAG, "state is null");
857 ca_mutex_unlock(g_deviceStateListMutex);
858 return CA_SEND_FAILED;
861 if (STATE_SEND_SUCCESS != state->sendState)
863 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
864 ca_mutex_unlock(g_deviceStateListMutex);
865 return CA_SEND_FAILED;
867 ca_mutex_unlock(g_deviceStateListMutex);
871 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
873 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
874 VERIFY_NON_NULL(device, TAG, "device is null");
875 VERIFY_NON_NULL(env, TAG, "env is null");
877 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
880 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
881 return CA_STATUS_FAILED;
884 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
887 OIC_LOG(ERROR, TAG, "address is not available");
888 return CA_STATUS_FAILED;
891 ca_mutex_lock(g_deviceStateListMutex);
892 CALEState_t* state = CALEClientGetStateInfo(address);
893 ca_mutex_unlock(g_deviceStateListMutex);
896 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
897 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
898 if (CA_STATUS_OK != ret)
900 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
901 (*env)->ReleaseStringUTFChars(env, jni_address, address);
907 if (STATE_CONNECTED == state->connectedState)
909 OIC_LOG(INFO, TAG, "GATT has already connected");
910 jobject gatt = CALEClientGetGattObjInList(env, address);
913 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
914 (*env)->ReleaseStringUTFChars(env, jni_address, address);
915 return CA_STATUS_FAILED;
918 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
919 if (CA_STATUS_OK != ret)
921 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
922 (*env)->ReleaseStringUTFChars(env, jni_address, address);
928 OIC_LOG(DEBUG, TAG, "start to connect LE");
929 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
930 if (CA_STATUS_OK != ret)
932 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
933 (*env)->ReleaseStringUTFChars(env, jni_address, address);
939 (*env)->ReleaseStringUTFChars(env, jni_address, address);
943 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
945 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
946 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
948 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
949 if (!jni_cid_gattdevice_list)
951 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
955 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
956 "()Landroid/bluetooth/BluetoothDevice;");
957 if (!jni_mid_getDevice)
959 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
963 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
966 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
970 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
973 OIC_LOG(ERROR, TAG, "jni_address is null");
983 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
986 OIC_LOG(DEBUG, TAG, "Gatt Close");
987 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
988 VERIFY_NON_NULL(env, TAG, "env is null");
990 // get BluetoothGatt class
991 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
992 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
993 if (!jni_cid_BluetoothGatt)
995 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
996 return CA_STATUS_FAILED;
999 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1000 if (!jni_mid_closeGatt)
1002 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1003 return CA_STATUS_OK;
1006 // call disconnect gatt method
1007 OIC_LOG(DEBUG, TAG, "request to close GATT");
1008 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1010 if ((*env)->ExceptionCheck(env))
1012 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1013 (*env)->ExceptionDescribe(env);
1014 (*env)->ExceptionClear(env);
1015 return CA_STATUS_FAILED;
1018 return CA_STATUS_OK;
1021 CAResult_t CALEClientStartScan()
1023 if (!g_isStartedMulticastServer)
1025 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1026 return CA_STATUS_FAILED;
1029 if (!g_isStartedLEClient)
1031 OIC_LOG(ERROR, TAG, "LE client is not started");
1032 return CA_STATUS_FAILED;
1037 OIC_LOG(ERROR, TAG, "g_jvm is null");
1038 return CA_STATUS_FAILED;
1041 if (g_isStartedScan)
1043 OIC_LOG(INFO, TAG, "scanning is already started");
1044 return CA_STATUS_OK;
1047 bool isAttached = false;
1049 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1052 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1054 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1057 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1058 return CA_STATUS_FAILED;
1063 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1065 CAResult_t ret = CA_STATUS_OK;
1066 // scan gatt server with UUID
1067 if (g_leScanCallback && g_uuidList)
1070 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1071 if(CA_STATUS_OK != ret)
1073 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
1076 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1077 if (CA_STATUS_OK != ret)
1079 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
1086 (*g_jvm)->DetachCurrentThread(g_jvm);
1092 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1094 VERIFY_NON_NULL(callback, TAG, "callback is null");
1095 VERIFY_NON_NULL(env, TAG, "env is null");
1097 if (!CALEIsEnableBTAdapter(env))
1099 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1100 return CA_ADAPTER_NOT_ENABLED;
1103 // get default bt adapter class
1104 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1105 if (!jni_cid_BTAdapter)
1107 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1108 return CA_STATUS_FAILED;
1111 // get remote bt adapter method
1112 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1113 "getDefaultAdapter",
1114 METHODID_OBJECTNONPARAM);
1115 if (!jni_mid_getDefaultAdapter)
1117 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1118 return CA_STATUS_FAILED;
1121 // get start le scan method
1122 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1123 "(Landroid/bluetooth/BluetoothAdapter$"
1124 "LeScanCallback;)Z");
1125 if (!jni_mid_startLeScan)
1127 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1128 return CA_STATUS_FAILED;
1131 // gat bt adapter object
1132 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1133 jni_mid_getDefaultAdapter);
1134 if (!jni_obj_BTAdapter)
1136 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1137 return CA_STATUS_FAILED;
1140 // call start le scan method
1141 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1142 jni_mid_startLeScan, callback);
1143 if (!jni_obj_startLeScan)
1145 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1146 return CA_STATUS_FAILED;
1150 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1151 CALEClientSetScanFlag(true);
1154 return CA_STATUS_OK;
1157 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1159 VERIFY_NON_NULL(callback, TAG, "callback is null");
1160 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1161 VERIFY_NON_NULL(env, TAG, "env is null");
1163 if (!CALEIsEnableBTAdapter(env))
1165 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1166 return CA_ADAPTER_NOT_ENABLED;
1169 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1170 if (!jni_cid_BTAdapter)
1172 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1173 return CA_STATUS_FAILED;
1176 // get remote bt adapter method
1177 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1178 "getDefaultAdapter",
1179 METHODID_OBJECTNONPARAM);
1180 if (!jni_mid_getDefaultAdapter)
1182 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1183 return CA_STATUS_FAILED;
1186 // get start le scan method
1187 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1188 "([Ljava/util/UUID;Landroid/bluetooth/"
1189 "BluetoothAdapter$LeScanCallback;)Z");
1190 if (!jni_mid_startLeScan)
1192 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1193 return CA_STATUS_FAILED;
1196 // get bt adapter object
1197 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1198 jni_mid_getDefaultAdapter);
1199 if (!jni_obj_BTAdapter)
1201 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1202 return CA_STATUS_FAILED;
1205 // call start le scan method
1206 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1207 jni_mid_startLeScan, uuids, callback);
1208 if (!jni_obj_startLeScan)
1210 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1211 return CA_STATUS_FAILED;
1215 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1216 CALEClientSetScanFlag(true);
1219 return CA_STATUS_OK;
1222 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1224 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1225 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1228 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1231 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1235 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1236 "(Ljava/lang/String;)"
1237 "Ljava/util/UUID;");
1238 if (!jni_mid_fromString)
1240 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1244 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1245 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1249 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1253 return jni_obj_uuid;
1256 CAResult_t CALEClientStopScan()
1260 OIC_LOG(ERROR, TAG, "g_jvm is null");
1261 return CA_STATUS_FAILED;
1264 if (!g_isStartedScan)
1266 OIC_LOG(INFO, TAG, "scanning is already stopped");
1267 return CA_STATUS_OK;
1270 bool isAttached = false;
1272 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1275 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1276 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1279 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1280 return CA_STATUS_FAILED;
1285 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1286 if (CA_STATUS_OK != ret)
1288 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1292 CALEClientSetScanFlag(false);
1297 (*g_jvm)->DetachCurrentThread(g_jvm);
1303 void CALEClientSetScanFlag(bool flag)
1305 ca_mutex_lock(g_scanMutex);
1306 g_isStartedScan = flag;
1307 ca_mutex_unlock(g_scanMutex);
1310 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1312 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
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(ERROR, 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 return CA_STATUS_FAILED;
1340 // get start le scan method
1341 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1342 "(Landroid/bluetooth/"
1343 "BluetoothAdapter$LeScanCallback;)V");
1344 if (!jni_mid_stopLeScan)
1346 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1347 return CA_STATUS_FAILED;
1350 // gat bt adapter object
1351 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1352 jni_mid_getDefaultAdapter);
1353 if (!jni_obj_BTAdapter)
1355 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1356 return CA_STATUS_FAILED;
1359 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1360 // call start le scan method
1361 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1362 if ((*env)->ExceptionCheck(env))
1364 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1365 (*env)->ExceptionDescribe(env);
1366 (*env)->ExceptionClear(env);
1367 return CA_STATUS_FAILED;
1370 return CA_STATUS_OK;
1373 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1376 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1377 VERIFY_NON_NULL(env, TAG, "env is null");
1378 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1379 VERIFY_NON_NULL(callback, TAG, "callback is null");
1381 if (!CALEIsEnableBTAdapter(env))
1383 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1384 return CA_ADAPTER_NOT_ENABLED;
1387 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1390 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1391 return CA_STATUS_FAILED;
1394 // get BluetoothDevice class
1395 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1396 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1397 if (!jni_cid_BluetoothDevice)
1399 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1400 return CA_STATUS_FAILED;
1403 // get connectGatt method
1404 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1405 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1406 "(Landroid/content/Context;ZLandroid/"
1407 "bluetooth/BluetoothGattCallback;)"
1408 "Landroid/bluetooth/BluetoothGatt;");
1409 if (!jni_mid_connectGatt)
1411 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1412 return CA_STATUS_FAILED;
1415 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1416 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1417 jni_mid_connectGatt,
1419 autoconnect, callback);
1420 if (!jni_obj_connectGatt)
1422 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1423 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1424 CALEClientUpdateSendCnt(env);
1425 return CA_STATUS_FAILED;
1429 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1431 return CA_STATUS_OK;
1434 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1436 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1437 VERIFY_NON_NULL(env, TAG, "env is null");
1438 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1440 if (!CALEIsEnableBTAdapter(env))
1442 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1443 return CA_ADAPTER_NOT_ENABLED;
1446 // get BluetoothGatt class
1447 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1448 if (!jni_cid_BluetoothGatt)
1450 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1451 return CA_STATUS_FAILED;
1454 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1455 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1456 "disconnect", "()V");
1457 if (!jni_mid_disconnectGatt)
1459 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1460 return CA_STATUS_FAILED;
1463 // call disconnect gatt method
1464 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1465 if ((*env)->ExceptionCheck(env))
1467 OIC_LOG(ERROR, TAG, "disconnect has failed");
1468 (*env)->ExceptionDescribe(env);
1469 (*env)->ExceptionClear(env);
1470 return CA_STATUS_FAILED;
1473 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1475 return CA_STATUS_OK;
1478 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1480 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1481 VERIFY_NON_NULL(env, TAG, "env is null");
1483 if (!g_gattObjectList)
1485 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1486 return CA_STATUS_FAILED;
1489 uint32_t length = u_arraylist_length(g_gattObjectList);
1490 for (uint32_t index = 0; index < length; index++)
1492 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1495 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1498 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1499 if (CA_STATUS_OK != res)
1501 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1506 OICFree(g_gattObjectList);
1507 g_gattObjectList = NULL;
1509 return CA_STATUS_OK;
1512 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1514 VERIFY_NON_NULL(env, TAG, "env is null");
1515 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1517 if (!CALEIsEnableBTAdapter(env))
1519 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1520 return CA_ADAPTER_NOT_ENABLED;
1523 // get BluetoothGatt class
1524 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1525 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1526 if (!jni_cid_BluetoothGatt)
1528 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1529 return CA_STATUS_FAILED;
1532 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1533 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1534 "discoverServices", "()Z");
1535 if (!jni_mid_discoverServices)
1537 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1538 return CA_STATUS_FAILED;
1540 // call disconnect gatt method
1541 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1542 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1545 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1546 return CA_STATUS_FAILED;
1549 return CA_STATUS_OK;
1552 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1554 VERIFY_NON_NULL(env, TAG, "env is null");
1555 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1558 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1559 if (!jni_obj_character)
1561 CALEClientSendFinish(env, gatt);
1562 return CA_STATUS_FAILED;
1565 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1566 if (CA_STATUS_OK != ret)
1568 CALEClientSendFinish(env, gatt);
1572 return CA_STATUS_OK;
1575 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1576 jobject gattCharacteristic)
1578 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1579 VERIFY_NON_NULL(env, TAG, "env is null");
1580 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1581 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1583 if (!CALEIsEnableBTAdapter(env))
1585 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1586 return CA_STATUS_FAILED;
1589 // get BluetoothGatt class
1590 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1591 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1592 if (!jni_cid_BluetoothGatt)
1594 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1595 return CA_STATUS_FAILED;
1598 OIC_LOG(DEBUG, TAG, "write characteristic method");
1599 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1600 "writeCharacteristic",
1601 "(Landroid/bluetooth/"
1602 "BluetoothGattCharacteristic;)Z");
1603 if (!jni_mid_writeCharacteristic)
1605 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1606 return CA_STATUS_FAILED;
1609 // call disconnect gatt method
1610 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1611 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1612 jni_mid_writeCharacteristic,
1613 gattCharacteristic);
1616 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1620 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1621 return CA_STATUS_FAILED;
1624 return CA_STATUS_OK;
1627 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1629 VERIFY_NON_NULL(env, TAG, "env is null");
1630 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1632 if (!CALEIsEnableBTAdapter(env))
1634 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1635 return CA_STATUS_FAILED;
1638 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1639 if (!jni_cid_BluetoothGatt)
1641 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1642 return CA_STATUS_FAILED;
1645 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1648 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1649 return CA_STATUS_FAILED;
1652 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1653 if (!jni_obj_GattCharacteristic)
1655 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1656 return CA_STATUS_FAILED;
1659 OIC_LOG(DEBUG, TAG, "read characteristic method");
1660 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1661 "readCharacteristic",
1662 "(Landroid/bluetooth/"
1663 "BluetoothGattCharacteristic;)Z");
1664 if (!jni_mid_readCharacteristic)
1666 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1667 return CA_STATUS_FAILED;
1670 // call disconnect gatt method
1671 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1672 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1673 jni_obj_GattCharacteristic);
1676 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1680 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1681 return CA_STATUS_FAILED;
1684 return CA_STATUS_OK;
1687 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1688 jobject characteristic)
1690 VERIFY_NON_NULL(env, TAG, "env is null");
1691 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1692 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1694 if (!CALEIsEnableBTAdapter(env))
1696 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1697 return CA_ADAPTER_NOT_ENABLED;
1700 // get BluetoothGatt class
1701 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1702 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1703 if (!jni_cid_BluetoothGatt)
1705 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1706 return CA_STATUS_FAILED;
1709 // set Characteristic Notification
1710 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1711 "setCharacteristicNotification",
1712 "(Landroid/bluetooth/"
1713 "BluetoothGattCharacteristic;Z)Z");
1714 if (!jni_mid_setNotification)
1716 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1717 return CA_STATUS_FAILED;
1720 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1721 characteristic, JNI_TRUE);
1722 if (JNI_TRUE == ret)
1724 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1728 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1729 return CA_STATUS_FAILED;
1732 return CA_STATUS_OK;
1735 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1737 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1738 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1739 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1741 if (!CALEIsEnableBTAdapter(env))
1743 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1747 // get BluetoothGatt class
1748 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1749 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1750 if (!jni_cid_BluetoothGatt)
1752 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1756 jmethodID jni_mid_getService = (*env)->GetMethodID(
1757 env, jni_cid_BluetoothGatt, "getService",
1758 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1759 if (!jni_mid_getService)
1761 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1765 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1766 if (!jni_obj_service_uuid)
1768 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1772 // get bluetooth gatt service
1773 OIC_LOG(DEBUG, TAG, "request to get service");
1774 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1775 jni_obj_service_uuid);
1776 if (!jni_obj_gattService)
1778 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1782 // get bluetooth gatt service class
1783 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1784 env, "android/bluetooth/BluetoothGattService");
1785 if (!jni_cid_BluetoothGattService)
1787 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1791 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1792 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1793 "getCharacteristic",
1794 "(Ljava/util/UUID;)"
1795 "Landroid/bluetooth/"
1796 "BluetoothGattCharacteristic;");
1797 if (!jni_mid_getCharacteristic)
1799 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1803 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1806 OIC_LOG(ERROR, TAG, "uuid is null");
1810 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1811 if (!jni_obj_tx_uuid)
1813 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1814 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1818 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1819 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1820 jni_mid_getCharacteristic,
1823 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1824 return jni_obj_GattCharacteristic;
1827 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1829 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1830 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1831 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1832 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1834 if (!CALEIsEnableBTAdapter(env))
1836 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1840 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1843 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1847 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1848 if (!jni_obj_GattCharacteristic)
1850 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1854 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1855 "/BluetoothGattCharacteristic");
1856 if (!jni_cid_BTGattCharacteristic)
1858 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1862 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1863 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1865 if (!jni_mid_setValue)
1867 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1871 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1873 if (JNI_TRUE == ret)
1875 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1879 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1884 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1885 "setWriteType", "(I)V");
1886 if (!jni_mid_setWriteType)
1888 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1892 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1893 "WRITE_TYPE_NO_RESPONSE", "I");
1894 if (!jni_fid_no_response)
1896 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1900 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1901 jni_fid_no_response);
1903 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1905 return jni_obj_GattCharacteristic;
1908 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1910 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1911 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1913 if (!CALEIsEnableBTAdapter(env))
1915 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1919 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1920 "BluetoothGattCharacteristic");
1921 if (!jni_cid_BTGattCharacteristic)
1923 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1927 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1928 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1930 if (!jni_mid_getValue)
1932 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1936 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1938 return jni_obj_data_array;
1941 CAResult_t CALEClientCreateUUIDList()
1945 OIC_LOG(ERROR, TAG, "g_jvm is null");
1946 return CA_STATUS_FAILED;
1949 bool isAttached = false;
1951 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1954 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1955 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1959 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1960 return CA_STATUS_FAILED;
1965 // create new object array
1966 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1967 if (!jni_cid_uuid_list)
1969 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1973 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1974 jni_cid_uuid_list, NULL);
1975 if (!jni_obj_uuid_list)
1977 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1982 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1985 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1988 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1990 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1994 (*g_jvm)->DetachCurrentThread(g_jvm);
1997 return CA_STATUS_OK;
2004 (*g_jvm)->DetachCurrentThread(g_jvm);
2006 return CA_STATUS_FAILED;
2009 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2010 jobject characteristic)
2012 VERIFY_NON_NULL(env, TAG, "env is null");
2013 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2014 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2016 if (!CALEIsEnableBTAdapter(env))
2018 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
2019 return CA_ADAPTER_NOT_ENABLED;
2022 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2023 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2024 "BluetoothGattCharacteristic");
2025 if (!jni_cid_BTGattCharacteristic)
2027 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2028 return CA_STATUS_FAILED;
2031 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2032 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2034 "(Ljava/util/UUID;)Landroid/bluetooth/"
2035 "BluetoothGattDescriptor;");
2036 if (!jni_mid_getDescriptor)
2038 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2039 return CA_STATUS_FAILED;
2042 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2043 if (!jni_obj_cc_uuid)
2045 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2046 return CA_STATUS_FAILED;
2049 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2050 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2051 jni_mid_getDescriptor, jni_obj_cc_uuid);
2052 if (!jni_obj_descriptor)
2054 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2055 return CA_NOT_SUPPORTED;
2058 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2059 jclass jni_cid_descriptor = (*env)->FindClass(env,
2060 "android/bluetooth/BluetoothGattDescriptor");
2061 if (!jni_cid_descriptor)
2063 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2064 return CA_STATUS_FAILED;
2067 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2068 if (!jni_mid_setValue)
2070 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2071 return CA_STATUS_FAILED;
2074 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2075 "ENABLE_NOTIFICATION_VALUE", "[B");
2076 if (!jni_fid_NotiValue)
2078 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2079 return CA_STATUS_FAILED;
2082 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2084 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2085 env, jni_obj_descriptor, jni_mid_setValue,
2086 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2089 OIC_LOG(DEBUG, TAG, "setValue success");
2093 OIC_LOG(ERROR, TAG, "setValue has failed");
2094 return CA_STATUS_FAILED;
2097 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2100 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2101 return CA_STATUS_FAILED;
2104 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2105 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2106 "(Landroid/bluetooth/"
2107 "BluetoothGattDescriptor;)Z");
2108 if (!jni_mid_writeDescriptor)
2110 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2111 return CA_STATUS_FAILED;
2114 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2115 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2116 jni_obj_descriptor);
2119 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2123 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2124 return CA_STATUS_FAILED;
2127 return CA_STATUS_OK;
2130 void CALEClientCreateScanDeviceList(JNIEnv *env)
2132 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2133 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2135 ca_mutex_lock(g_deviceListMutex);
2136 // create new object array
2137 if (g_deviceList == NULL)
2139 OIC_LOG(DEBUG, TAG, "Create device list");
2141 g_deviceList = u_arraylist_create();
2143 ca_mutex_unlock(g_deviceListMutex);
2146 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2148 VERIFY_NON_NULL(device, TAG, "device is null");
2149 VERIFY_NON_NULL(env, TAG, "env is null");
2151 ca_mutex_lock(g_deviceListMutex);
2155 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2156 ca_mutex_unlock(g_deviceListMutex);
2157 return CA_STATUS_FAILED;
2160 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2161 if (!jni_remoteAddress)
2163 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2164 ca_mutex_unlock(g_deviceListMutex);
2165 return CA_STATUS_FAILED;
2168 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2171 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2172 ca_mutex_unlock(g_deviceListMutex);
2173 return CA_STATUS_FAILED;
2176 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2178 jobject gdevice = (*env)->NewGlobalRef(env, device);
2179 u_arraylist_add(g_deviceList, gdevice);
2180 ca_cond_signal(g_deviceDescCond);
2181 OIC_LOG_V(DEBUG, TAG, "Added this Device[%s] in the List", remoteAddress);
2183 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2185 ca_mutex_unlock(g_deviceListMutex);
2187 return CA_STATUS_OK;
2190 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2192 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2193 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2197 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2201 uint32_t length = u_arraylist_length(g_deviceList);
2202 for (uint32_t index = 0; index < length; index++)
2204 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2207 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2211 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2212 if (!jni_setAddress)
2214 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2218 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2221 OIC_LOG(ERROR, TAG, "setAddress is null");
2225 if (!strcmp(remoteAddress, setAddress))
2227 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2231 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2234 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2239 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2241 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2242 VERIFY_NON_NULL(env, TAG, "env is null");
2244 ca_mutex_lock(g_deviceListMutex);
2248 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2249 ca_mutex_unlock(g_deviceListMutex);
2250 return CA_STATUS_FAILED;
2253 uint32_t length = u_arraylist_length(g_deviceList);
2254 for (uint32_t index = 0; index < length; index++)
2256 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2259 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2262 (*env)->DeleteGlobalRef(env, jarrayObj);
2265 OICFree(g_deviceList);
2266 g_deviceList = NULL;
2268 ca_mutex_unlock(g_deviceListMutex);
2269 return CA_STATUS_OK;
2272 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2274 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2275 VERIFY_NON_NULL(address, TAG, "address is null");
2276 VERIFY_NON_NULL(env, TAG, "env is null");
2278 ca_mutex_lock(g_deviceListMutex);
2282 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2283 ca_mutex_unlock(g_deviceListMutex);
2284 return CA_STATUS_FAILED;
2287 uint32_t length = u_arraylist_length(g_deviceList);
2288 for (uint32_t index = 0; index < length; index++)
2290 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2293 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2294 ca_mutex_unlock(g_deviceListMutex);
2295 return CA_STATUS_FAILED;
2298 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2299 if (!jni_setAddress)
2301 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2302 ca_mutex_unlock(g_deviceListMutex);
2303 return CA_STATUS_FAILED;
2306 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2309 OIC_LOG(ERROR, TAG, "setAddress is null");
2310 ca_mutex_unlock(g_deviceListMutex);
2311 return CA_STATUS_FAILED;
2314 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2317 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2318 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2319 ca_mutex_unlock(g_deviceListMutex);
2320 return CA_STATUS_FAILED;
2323 if (!strcmp(setAddress, remoteAddress))
2325 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2326 (*env)->DeleteGlobalRef(env, jarrayObj);
2327 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2328 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2330 if (NULL == u_arraylist_remove(g_deviceList, index))
2332 OIC_LOG(ERROR, TAG, "List removal failed.");
2333 ca_mutex_unlock(g_deviceListMutex);
2334 return CA_STATUS_FAILED;
2336 ca_mutex_unlock(g_deviceListMutex);
2337 return CA_STATUS_OK;
2339 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2340 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2343 ca_mutex_unlock(g_deviceListMutex);
2344 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2346 return CA_STATUS_OK;
2353 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2355 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2356 VERIFY_NON_NULL(env, TAG, "env is null");
2357 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2359 ca_mutex_lock(g_gattObjectMutex);
2361 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2362 if (!jni_remoteAddress)
2364 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2365 ca_mutex_unlock(g_gattObjectMutex);
2366 return CA_STATUS_FAILED;
2369 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2372 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2373 ca_mutex_unlock(g_gattObjectMutex);
2374 return CA_STATUS_FAILED;
2377 if (!CALEClientIsGattObjInList(env, remoteAddress))
2379 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2380 u_arraylist_add(g_gattObjectList, newGatt);
2381 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2384 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2385 ca_mutex_unlock(g_gattObjectMutex);
2386 return CA_STATUS_OK;
2389 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2391 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2392 VERIFY_NON_NULL(env, TAG, "env is null");
2393 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2395 uint32_t length = u_arraylist_length(g_gattObjectList);
2396 for (uint32_t index = 0; index < length; index++)
2399 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2402 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2406 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2407 if (!jni_setAddress)
2409 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2413 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2416 OIC_LOG(ERROR, TAG, "setAddress is null");
2420 if (!strcmp(remoteAddress, setAddress))
2422 OIC_LOG(DEBUG, TAG, "the device is already set");
2423 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2428 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2433 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2437 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2439 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2440 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2441 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2443 ca_mutex_lock(g_gattObjectMutex);
2444 uint32_t length = u_arraylist_length(g_gattObjectList);
2445 for (uint32_t index = 0; index < length; index++)
2447 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2450 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2451 ca_mutex_unlock(g_gattObjectMutex);
2455 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2456 if (!jni_setAddress)
2458 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2459 ca_mutex_unlock(g_gattObjectMutex);
2463 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2466 OIC_LOG(ERROR, TAG, "setAddress is null");
2467 ca_mutex_unlock(g_gattObjectMutex);
2471 if (!strcmp(remoteAddress, setAddress))
2473 OIC_LOG(DEBUG, TAG, "the device is already set");
2474 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2475 ca_mutex_unlock(g_gattObjectMutex);
2478 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2481 ca_mutex_unlock(g_gattObjectMutex);
2482 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2486 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2488 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2489 VERIFY_NON_NULL(env, TAG, "env is null");
2491 ca_mutex_lock(g_gattObjectMutex);
2492 if (!g_gattObjectList)
2494 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2495 ca_mutex_unlock(g_gattObjectMutex);
2496 return CA_STATUS_FAILED;
2499 uint32_t length = u_arraylist_length(g_gattObjectList);
2500 for (uint32_t index = 0; index < length; index++)
2502 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2505 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2508 (*env)->DeleteGlobalRef(env, jarrayObj);
2511 OICFree(g_gattObjectList);
2512 g_gattObjectList = NULL;
2513 ca_mutex_unlock(g_gattObjectMutex);
2514 return CA_STATUS_OK;
2517 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2519 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2520 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2521 VERIFY_NON_NULL(env, TAG, "env is null");
2523 ca_mutex_lock(g_gattObjectMutex);
2524 if (!g_gattObjectList)
2526 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2527 ca_mutex_unlock(g_gattObjectMutex);
2528 return CA_STATUS_FAILED;
2531 uint32_t length = u_arraylist_length(g_gattObjectList);
2532 for (uint32_t index = 0; index < length; index++)
2534 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2537 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2538 ca_mutex_unlock(g_gattObjectMutex);
2539 return CA_STATUS_FAILED;
2542 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2543 if (!jni_setAddress)
2545 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2546 ca_mutex_unlock(g_gattObjectMutex);
2547 return CA_STATUS_FAILED;
2550 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2553 OIC_LOG(ERROR, TAG, "setAddress is null");
2554 ca_mutex_unlock(g_gattObjectMutex);
2555 return CA_STATUS_FAILED;
2558 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2559 if (!jni_remoteAddress)
2561 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2562 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2563 ca_mutex_unlock(g_gattObjectMutex);
2564 return CA_STATUS_FAILED;
2567 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2570 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2571 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2572 ca_mutex_unlock(g_gattObjectMutex);
2573 return CA_STATUS_FAILED;
2576 if (!strcmp(setAddress, remoteAddress))
2578 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2579 (*env)->DeleteGlobalRef(env, jarrayObj);
2580 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2581 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2583 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2585 OIC_LOG(ERROR, TAG, "List removal failed.");
2586 ca_mutex_unlock(g_gattObjectMutex);
2587 return CA_STATUS_FAILED;
2589 ca_mutex_unlock(g_gattObjectMutex);
2590 return CA_STATUS_OK;
2592 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2593 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2596 ca_mutex_unlock(g_gattObjectMutex);
2597 OIC_LOG(DEBUG, TAG, "there are no target object");
2598 return CA_STATUS_OK;
2601 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2603 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2604 VERIFY_NON_NULL(addr, TAG, "addr is null");
2605 VERIFY_NON_NULL(env, TAG, "env is null");
2607 ca_mutex_lock(g_gattObjectMutex);
2608 if (!g_gattObjectList)
2610 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2611 ca_mutex_unlock(g_gattObjectMutex);
2612 return CA_STATUS_FAILED;
2615 uint32_t length = u_arraylist_length(g_gattObjectList);
2616 for (uint32_t index = 0; index < length; index++)
2618 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2621 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2622 ca_mutex_unlock(g_gattObjectMutex);
2623 return CA_STATUS_FAILED;
2626 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2627 if (!jni_setAddress)
2629 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2630 ca_mutex_unlock(g_gattObjectMutex);
2631 return CA_STATUS_FAILED;
2634 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2637 OIC_LOG(ERROR, TAG, "setAddress is null");
2638 ca_mutex_unlock(g_gattObjectMutex);
2639 return CA_STATUS_FAILED;
2642 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2645 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2646 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2647 ca_mutex_unlock(g_gattObjectMutex);
2648 return CA_STATUS_FAILED;
2651 if (!strcmp(setAddress, remoteAddress))
2653 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2654 (*env)->DeleteGlobalRef(env, jarrayObj);
2656 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2657 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2658 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2660 OIC_LOG(ERROR, TAG, "List removal failed.");
2661 ca_mutex_unlock(g_gattObjectMutex);
2662 return CA_STATUS_FAILED;
2664 ca_mutex_unlock(g_gattObjectMutex);
2665 return CA_STATUS_OK;
2667 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2668 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2671 ca_mutex_unlock(g_gattObjectMutex);
2672 OIC_LOG(DEBUG, TAG, "there are no target object");
2673 return CA_STATUS_FAILED;
2680 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2681 uint16_t notificationState, uint16_t sendState)
2683 VERIFY_NON_NULL(address, TAG, "address is null");
2685 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2688 OIC_LOG(ERROR, TAG, "out of memory");
2689 return CA_MEMORY_ALLOC_FAILED;
2692 if (strlen(address) > CA_MACADDR_SIZE)
2694 OIC_LOG(ERROR, TAG, "address is not proper");
2696 return CA_STATUS_FAILED;
2699 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2700 newstate->connectedState = connectedState;
2701 newstate->notificationState = notificationState;
2702 newstate->sendState = sendState;
2703 return CALEClientAddDeviceStateToList(newstate);
2706 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2708 VERIFY_NON_NULL(state, TAG, "state is null");
2710 ca_mutex_lock(g_deviceStateListMutex);
2712 if (!g_deviceStateList)
2714 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2715 ca_mutex_unlock(g_deviceStateListMutex);
2716 return CA_STATUS_FAILED;
2719 if (CALEClientIsDeviceInList(state->address))
2721 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2724 OIC_LOG(ERROR, TAG, "curState is null");
2725 ca_mutex_unlock(g_deviceStateListMutex);
2726 return CA_STATUS_FAILED;
2729 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2731 state->notificationState = curState->notificationState;
2734 // delete previous state for update new state
2735 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2736 if (CA_STATUS_OK != res)
2738 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2739 ca_mutex_unlock(g_deviceStateListMutex);
2743 u_arraylist_add(g_deviceStateList, state); // update new state
2744 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2745 state->connectedState, state->notificationState);
2747 ca_mutex_unlock(g_deviceStateListMutex);
2748 return CA_STATUS_OK;
2751 bool CALEClientIsDeviceInList(const char* remoteAddress)
2753 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2755 if (!g_deviceStateList)
2757 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2761 uint32_t length = u_arraylist_length(g_deviceStateList);
2762 for (uint32_t index = 0; index < length; index++)
2764 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2767 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2771 if (!strcmp(remoteAddress, state->address))
2773 OIC_LOG(DEBUG, TAG, "the device is already set");
2782 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2786 CAResult_t CALEClientRemoveAllDeviceState()
2788 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2790 ca_mutex_lock(g_deviceStateListMutex);
2791 if (!g_deviceStateList)
2793 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2794 ca_mutex_unlock(g_deviceStateListMutex);
2795 return CA_STATUS_FAILED;
2798 uint32_t length = u_arraylist_length(g_deviceStateList);
2799 for (uint32_t index = 0; index < length; index++)
2801 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2804 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2810 OICFree(g_deviceStateList);
2811 g_deviceStateList = NULL;
2812 ca_mutex_unlock(g_deviceStateListMutex);
2814 return CA_STATUS_OK;
2817 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2819 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2820 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2822 if (!g_deviceStateList)
2824 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2825 return CA_STATUS_FAILED;
2828 uint32_t length = u_arraylist_length(g_deviceStateList);
2829 for (uint32_t index = 0; index < length; index++)
2831 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2834 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2838 if (!strcmp(state->address, remoteAddress))
2840 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2843 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2845 OIC_LOG(ERROR, TAG, "List removal failed.");
2846 return CA_STATUS_FAILED;
2849 return CA_STATUS_OK;
2853 return CA_STATUS_FAILED;
2856 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2858 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2859 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2861 if (!g_deviceStateList)
2863 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2867 uint32_t length = u_arraylist_length(g_deviceStateList);
2868 for (uint32_t index = 0; index < length; index++)
2870 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2873 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2877 if (!strcmp(state->address, remoteAddress))
2879 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2886 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2888 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2889 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2891 ca_mutex_lock(g_deviceStateListMutex);
2892 if (!g_deviceStateList)
2894 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2895 ca_mutex_unlock(g_deviceStateListMutex);
2899 uint32_t length = u_arraylist_length(g_deviceStateList);
2900 for (uint32_t index = 0; index < length; index++)
2902 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2905 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2909 if (!strcmp(state->address, remoteAddress))
2911 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2913 if (STATE_CONNECTED == state->connectedState)
2915 ca_mutex_unlock(g_deviceStateListMutex);
2920 ca_mutex_unlock(g_deviceStateListMutex);
2925 ca_mutex_unlock(g_deviceStateListMutex);
2929 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2931 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2932 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2934 ca_mutex_lock(g_deviceStateListMutex);
2935 if (!g_deviceStateList)
2937 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2938 ca_mutex_unlock(g_deviceStateListMutex);
2942 uint32_t length = u_arraylist_length(g_deviceStateList);
2943 for (uint32_t index = 0; index < length; index++)
2945 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2948 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2952 if (!strcmp(state->address, remoteAddress))
2954 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2956 if (STATE_CHARACTER_SET == state->notificationState)
2958 ca_mutex_unlock(g_deviceStateListMutex);
2963 ca_mutex_unlock(g_deviceStateListMutex);
2969 ca_mutex_unlock(g_deviceStateListMutex);
2973 void CALEClientCreateDeviceList()
2975 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2977 // create new object array
2978 if (!g_gattObjectList)
2980 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2982 g_gattObjectList = u_arraylist_create();
2985 if (!g_deviceStateList)
2987 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2989 g_deviceStateList = u_arraylist_create();
2994 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2996 g_deviceList = u_arraylist_create();
3001 * Check Sent Count for remove g_sendBuffer
3003 void CALEClientUpdateSendCnt(JNIEnv *env)
3005 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3007 ca_mutex_lock(g_threadMutex);
3011 if (g_targetCnt <= g_currentSentCnt)
3014 g_currentSentCnt = 0;
3018 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3019 g_sendBuffer = NULL;
3021 // notity the thread
3022 ca_cond_signal(g_threadCond);
3023 CALEClientSetSendFinishFlag(true);
3024 OIC_LOG(DEBUG, TAG, "set signal for send data");
3027 ca_mutex_unlock(g_threadMutex);
3030 CAResult_t CALEClientInitGattMutexVaraibles()
3032 if (NULL == g_bleReqRespClientCbMutex)
3034 g_bleReqRespClientCbMutex = ca_mutex_new();
3035 if (NULL == g_bleReqRespClientCbMutex)
3037 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3038 return CA_STATUS_FAILED;
3042 if (NULL == g_bleServerBDAddressMutex)
3044 g_bleServerBDAddressMutex = ca_mutex_new();
3045 if (NULL == g_bleServerBDAddressMutex)
3047 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3048 return CA_STATUS_FAILED;
3052 if (NULL == g_threadMutex)
3054 g_threadMutex = ca_mutex_new();
3055 if (NULL == g_threadMutex)
3057 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3058 return CA_STATUS_FAILED;
3062 if (NULL == g_threadSendMutex)
3064 g_threadSendMutex = ca_mutex_new();
3065 if (NULL == g_threadSendMutex)
3067 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3068 return CA_STATUS_FAILED;
3072 if (NULL == g_deviceListMutex)
3074 g_deviceListMutex = ca_mutex_new();
3075 if (NULL == g_deviceListMutex)
3077 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3078 return CA_STATUS_FAILED;
3082 if (NULL == g_gattObjectMutex)
3084 g_gattObjectMutex = ca_mutex_new();
3085 if (NULL == g_gattObjectMutex)
3087 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3088 return CA_STATUS_FAILED;
3092 if (NULL == g_deviceStateListMutex)
3094 g_deviceStateListMutex = ca_mutex_new();
3095 if (NULL == g_deviceStateListMutex)
3097 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3098 return CA_STATUS_FAILED;
3102 if (NULL == g_SendFinishMutex)
3104 g_SendFinishMutex = ca_mutex_new();
3105 if (NULL == g_SendFinishMutex)
3107 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3108 return CA_STATUS_FAILED;
3112 if (NULL == g_scanMutex)
3114 g_scanMutex = ca_mutex_new();
3115 if (NULL == g_scanMutex)
3117 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3118 return CA_STATUS_FAILED;
3122 return CA_STATUS_OK;
3125 void CALEClientTerminateGattMutexVariables()
3127 ca_mutex_free(g_bleReqRespClientCbMutex);
3128 g_bleReqRespClientCbMutex = NULL;
3130 ca_mutex_free(g_bleServerBDAddressMutex);
3131 g_bleServerBDAddressMutex = NULL;
3133 ca_mutex_free(g_threadMutex);
3134 g_threadMutex = NULL;
3136 ca_mutex_free(g_threadSendMutex);
3137 g_threadSendMutex = NULL;
3139 ca_mutex_free(g_deviceListMutex);
3140 g_deviceListMutex = NULL;
3142 ca_mutex_free(g_SendFinishMutex);
3143 g_SendFinishMutex = NULL;
3145 ca_mutex_free(g_scanMutex);
3149 void CALEClientSetSendFinishFlag(bool flag)
3151 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3153 ca_mutex_lock(g_SendFinishMutex);
3154 g_isFinishedSendData = flag;
3155 ca_mutex_unlock(g_SendFinishMutex);
3162 CAResult_t CAStartLEGattClient()
3164 CAResult_t res = CALEClientStartMulticastServer();
3165 if (CA_STATUS_OK != res)
3167 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3171 g_isStartedLEClient = true;
3177 void CAStopLEGattClient()
3179 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3183 OIC_LOG(ERROR, TAG, "g_jvm is null");
3187 bool isAttached = false;
3189 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3192 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3193 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3197 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3203 CAResult_t ret = CALEClientDisconnectAll(env);
3204 if (CA_STATUS_OK != ret)
3206 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3209 ret = CALEClientStopScan();
3210 if(CA_STATUS_OK != ret)
3212 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3215 ca_cond_signal(g_threadCond);
3219 (*g_jvm)->DetachCurrentThread(g_jvm);
3224 CAResult_t CAInitializeLEGattClient()
3226 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3227 CALEClientInitialize();
3228 return CA_STATUS_OK;
3231 void CATerminateLEGattClient()
3233 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3234 CALEClientTerminate();
3237 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3238 uint32_t dataLen, CALETransferType_t type,
3241 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3242 VERIFY_NON_NULL(data, TAG, "data is null");
3243 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3245 if (LE_UNICAST != type || position < 0)
3247 OIC_LOG(ERROR, TAG, "this request is not unicast");
3248 return CA_STATUS_INVALID_PARAM;
3251 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3254 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3256 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3257 VERIFY_NON_NULL(data, TAG, "data is null");
3259 return CALEClientSendMulticastMessage(data, dataLen);
3262 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3264 ca_mutex_lock(g_bleReqRespClientCbMutex);
3265 g_CABLEClientDataReceivedCallback = callback;
3266 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3269 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3271 OIC_LOG(INFO, TAG, "CASetLEClientThreadPoolHandle is not support");
3274 CAResult_t CAGetLEAddress(char **local_address)
3276 VERIFY_NON_NULL(local_address, TAG, "local_address");
3277 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3278 return CA_NOT_SUPPORTED;
3281 JNIEXPORT void JNICALL
3282 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3285 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3286 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3287 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3288 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3290 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3293 JNIEXPORT void JNICALL
3294 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3297 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3298 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3299 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3300 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3302 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3305 JNIEXPORT void JNICALL
3306 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3309 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3310 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3311 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3313 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3314 if (CA_STATUS_OK != res)
3316 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3321 * Class: org_iotivity_ca_jar_caleinterface
3322 * Method: CALeGattConnectionStateChangeCallback
3323 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3325 JNIEXPORT void JNICALL
3326 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3332 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3334 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3335 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3336 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3338 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3340 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3346 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3349 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3350 STATE_CHARACTER_NO_CHANGE,
3352 if (CA_STATUS_OK != res)
3354 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3355 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3358 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3361 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3362 if (CA_STATUS_OK != res)
3364 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3368 res = CALEClientDiscoverServices(env, gatt);
3369 if (CA_STATUS_OK != res)
3371 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3375 else // le disconnected
3377 CAResult_t res = CALEClientStartScan();
3378 if (CA_STATUS_OK != res)
3380 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3384 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3387 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3391 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3394 res = CALEClientRemoveDeviceState(address);
3395 if (CA_STATUS_OK != res)
3397 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3401 res = CALEClientRemoveGattObjForAddr(env, jni_address);
3402 if (CA_STATUS_OK != res)
3404 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
3408 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3411 res = CALEClientGattClose(env, gatt);
3412 if (CA_STATUS_OK != res)
3414 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3422 CALEClientSendFinish(env, gatt);
3427 * Class: org_iotivity_ca_jar_caleinterface
3428 * Method: CALeGattServicesDiscoveredCallback
3429 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3431 JNIEXPORT void JNICALL
3432 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3437 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3438 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3439 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3440 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3442 if (0 != status) // discovery error
3444 CALEClientSendFinish(env, gatt);
3448 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3451 CALEClientSendFinish(env, gatt);
3455 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3458 CALEClientSendFinish(env, gatt);
3462 if (!CALEClientIsSetCharacteristic(address))
3464 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3467 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3471 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3472 if (!jni_obj_GattCharacteristic)
3474 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3478 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3479 jni_obj_GattCharacteristic);
3480 if (CA_STATUS_OK != res)
3482 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3486 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3487 if (CA_STATUS_OK != res)
3489 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
3490 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3491 if (CA_STATUS_OK != res)
3493 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3498 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3500 if (CA_STATUS_OK != res)
3502 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3508 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3509 if (CA_STATUS_OK != res)
3511 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3515 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3520 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3521 CALEClientSendFinish(env, gatt);
3526 * Class: org_iotivity_ca_jar_caleinterface
3527 * Method: CALeGattCharacteristicWritjclasseCallback
3528 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3530 JNIEXPORT void JNICALL
3531 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3532 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3535 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3536 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3537 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3538 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3541 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3543 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3545 // send success & signal
3546 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3552 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3558 if (GATT_SUCCESS != status) // error case
3560 OIC_LOG(ERROR, TAG, "send failure");
3561 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3563 if (CA_STATUS_OK != res)
3565 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3568 if (g_clientErrorCallback)
3570 jint length = (*env)->GetArrayLength(env, data);
3571 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
3574 CALEClientSendFinish(env, gatt);
3578 OIC_LOG(DEBUG, TAG, "send success");
3579 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3580 STATE_SEND_SUCCESS);
3581 if (CA_STATUS_OK != res)
3583 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3585 CALEClientUpdateSendCnt(env);
3588 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3594 CALEClientSendFinish(env, gatt);
3599 * Class: org_iotivity_ca_jar_caleinterface
3600 * Method: CALeGattCharacteristicChangedCallback
3601 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3603 JNIEXPORT void JNICALL
3604 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3605 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3607 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3608 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3609 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3610 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3611 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3613 // get Byte Array and convert to uint8_t*
3614 jint length = (*env)->GetArrayLength(env, data);
3617 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3619 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3620 jni_byte_responseData);
3622 uint8_t* receivedData = OICMalloc(length);
3625 OIC_LOG(ERROR, TAG, "receivedData is null");
3629 memcpy(receivedData, jni_byte_responseData, length);
3630 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3632 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3635 OIC_LOG(ERROR, TAG, "jni_address is null");
3636 OICFree(receivedData);
3640 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3643 OIC_LOG(ERROR, TAG, "address is null");
3644 OICFree(receivedData);
3648 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3649 receivedData, length);
3651 ca_mutex_lock(g_bleServerBDAddressMutex);
3652 uint32_t sentLength = 0;
3653 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3655 ca_mutex_unlock(g_bleServerBDAddressMutex);
3657 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3661 * Class: org_iotivity_ca_jar_caleinterface
3662 * Method: CALeGattDescriptorWriteCallback
3663 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3665 JNIEXPORT void JNICALL
3666 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3670 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3671 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3672 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3673 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3675 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3676 if (CA_STATUS_OK != res)
3678 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3686 CALEClientSendFinish(env, gatt);