1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
46 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
47 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
48 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
50 static ca_thread_pool_t g_threadPoolHandle = NULL;
53 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
54 static u_arraylist_t *g_gattObjectList = NULL;
55 static u_arraylist_t *g_deviceStateList = NULL;
57 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
58 static CABLEErrorHandleCallback g_clientErrorCallback;
59 static jobject g_leScanCallback = NULL;
60 static jobject g_leGattCallback = NULL;
61 static jobject g_context = NULL;
62 static jobjectArray g_uuidList = NULL;
64 // it will be prevent to start send logic when adapter has stopped.
65 static bool g_isStartedLEClient = false;
66 static bool g_isStartedMulticastServer = false;
67 static bool g_isStartedScan = false;
69 static jbyteArray g_sendBuffer = NULL;
70 static uint32_t g_targetCnt = 0;
71 static uint32_t g_currentSentCnt = 0;
72 static bool g_isFinishedSendData = false;
73 static ca_mutex g_SendFinishMutex = NULL;
74 static ca_mutex g_threadMutex = NULL;
75 static ca_cond g_threadCond = NULL;
76 static ca_cond g_deviceDescCond = NULL;
78 static ca_mutex g_threadSendMutex = NULL;
79 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
80 static ca_cond g_threadWriteCharacteristicCond = NULL;
81 static bool g_isSignalSetFlag = false;
83 static ca_mutex g_bleReqRespClientCbMutex = NULL;
84 static ca_mutex g_bleServerBDAddressMutex = NULL;
86 static ca_mutex g_deviceListMutex = NULL;
87 static ca_mutex g_gattObjectMutex = NULL;
88 static ca_mutex g_deviceStateListMutex = NULL;
90 static ca_mutex g_scanMutex = NULL;
92 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
95 void CALEClientJniInit()
97 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
98 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
101 void CALEClientJNISetContext()
103 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
104 g_context = (jobject) CANativeJNIGetContext();
107 CAResult_t CALECreateJniInterfaceObject()
109 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
113 OIC_LOG(ERROR, TAG, "g_context is null");
114 return CA_STATUS_FAILED;
119 OIC_LOG(ERROR, TAG, "g_jvm is null");
120 return CA_STATUS_FAILED;
123 bool isAttached = false;
125 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
128 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
129 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
133 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
134 return CA_STATUS_FAILED;
139 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
140 if (!jni_LEInterface)
142 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
146 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
147 "(Landroid/content/Context;)V");
148 if (!LeInterfaceConstructorMethod)
150 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
154 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
155 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
159 (*g_jvm)->DetachCurrentThread(g_jvm);
168 (*g_jvm)->DetachCurrentThread(g_jvm);
171 return CA_STATUS_FAILED;
174 CAResult_t CALEClientInitialize()
176 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
182 OIC_LOG(ERROR, TAG, "g_jvm is null");
183 return CA_STATUS_FAILED;
186 bool isAttached = false;
188 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
191 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
192 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
196 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
197 return CA_STATUS_FAILED;
202 CAResult_t ret = CALECheckPlatformVersion(env, 18);
203 if (CA_STATUS_OK != ret)
205 OIC_LOG(ERROR, TAG, "it is not supported");
209 (*g_jvm)->DetachCurrentThread(g_jvm);
215 ret = CALEClientInitGattMutexVaraibles();
216 if (CA_STATUS_OK != ret)
218 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
219 CALEClientTerminateGattMutexVariables();
223 (*g_jvm)->DetachCurrentThread(g_jvm);
229 g_deviceDescCond = ca_cond_new();
231 // init mutex for send logic
232 g_threadCond = ca_cond_new();
233 g_threadWriteCharacteristicCond = ca_cond_new();
235 CALEClientCreateDeviceList();
236 CALEClientJNISetContext();
238 ret = CALEClientCreateUUIDList();
239 if (CA_STATUS_OK != ret)
241 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
245 (*g_jvm)->DetachCurrentThread(g_jvm);
251 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
252 if (CA_STATUS_OK != ret)
254 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
258 (*g_jvm)->DetachCurrentThread(g_jvm);
263 g_isStartedLEClient = true;
267 (*g_jvm)->DetachCurrentThread(g_jvm);
273 void CALEClientTerminate()
275 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
279 OIC_LOG(ERROR, TAG, "g_jvm is null");
283 bool isAttached = false;
285 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
288 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
289 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
293 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
299 if (g_leScanCallback)
301 (*env)->DeleteGlobalRef(env, g_leScanCallback);
304 if (g_leGattCallback)
306 (*env)->DeleteGlobalRef(env, g_leGattCallback);
311 (*env)->DeleteGlobalRef(env, g_sendBuffer);
316 (*env)->DeleteGlobalRef(env, g_uuidList);
319 CAResult_t ret = CALEClientRemoveAllDeviceState();
320 if (CA_STATUS_OK != ret)
322 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
325 ret = CALEClientRemoveAllScanDevices(env);
326 if (CA_STATUS_OK != ret)
328 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
331 ret = CALEClientRemoveAllGattObjs(env);
332 if (CA_STATUS_OK != ret)
334 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
337 g_isStartedMulticastServer = false;
338 CALEClientSetScanFlag(false);
339 CALEClientSetSendFinishFlag(false);
341 CALEClientTerminateGattMutexVariables();
342 CALEClientDestroyJniInterface();
344 ca_cond_free(g_deviceDescCond);
345 ca_cond_free(g_threadCond);
346 ca_cond_free(g_threadWriteCharacteristicCond);
348 g_deviceDescCond = NULL;
350 g_threadWriteCharacteristicCond = NULL;
351 g_isSignalSetFlag = false;
355 (*g_jvm)->DetachCurrentThread(g_jvm);
359 CAResult_t CALEClientDestroyJniInterface()
361 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
365 OIC_LOG(ERROR, TAG, "g_jvm is null");
366 return CA_STATUS_FAILED;
369 bool isAttached = false;
371 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
374 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
375 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
379 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
380 return CA_STATUS_FAILED;
385 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
386 if (!jni_LeInterface)
388 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
392 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
393 "destroyLeInterface",
395 if (!jni_InterfaceDestroyMethod)
397 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
401 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
403 if ((*env)->ExceptionCheck(env))
405 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
406 (*env)->ExceptionDescribe(env);
407 (*env)->ExceptionClear(env);
411 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
415 (*g_jvm)->DetachCurrentThread(g_jvm);
424 (*g_jvm)->DetachCurrentThread(g_jvm);
427 return CA_STATUS_FAILED;
430 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
432 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
433 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
437 CAResult_t res = CALEClientDisconnect(env, gatt);
438 if (CA_STATUS_OK != res)
440 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
443 CALEClientUpdateSendCnt(env);
446 CAResult_t CALEClientSendUnicastMessage(const char* address,
448 const uint32_t dataLen)
450 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
451 VERIFY_NON_NULL(address, TAG, "address is null");
452 VERIFY_NON_NULL(data, TAG, "data is null");
454 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
457 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
458 const uint32_t dataLen)
460 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
461 VERIFY_NON_NULL(data, TAG, "data is null");
465 OIC_LOG(ERROR, TAG, "g_jvm is null");
466 return CA_STATUS_FAILED;
469 bool isAttached = false;
471 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
474 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
475 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
479 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
480 return CA_STATUS_FAILED;
485 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
486 if (CA_STATUS_OK != ret)
488 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
493 (*g_jvm)->DetachCurrentThread(g_jvm);
499 CAResult_t CALEClientStartUnicastServer(const char* address)
501 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
503 return CA_NOT_SUPPORTED;
506 CAResult_t CALEClientStartMulticastServer()
508 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
510 if (g_isStartedMulticastServer)
512 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
513 return CA_STATUS_FAILED;
518 OIC_LOG(ERROR, TAG, "g_jvm is null");
519 return CA_STATUS_FAILED;
522 bool isAttached = false;
524 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
527 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
528 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
532 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
533 return CA_STATUS_FAILED;
538 g_isStartedMulticastServer = true;
539 CAResult_t ret = CALEClientStartScan();
540 if (CA_STATUS_OK != ret)
542 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
547 (*g_jvm)->DetachCurrentThread(g_jvm);
553 void CALEClientStopUnicastServer()
555 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
558 void CALEClientStopMulticastServer()
560 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
561 g_isStartedMulticastServer = false;
562 CAResult_t res = CALEClientStopScan();
563 if (CA_STATUS_OK != res)
565 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
570 void CALEClientSetCallback(CAPacketReceiveCallback callback)
572 g_packetReceiveCallback = callback;
575 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
577 g_clientErrorCallback = callback;
580 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
581 const uint32_t dataLen)
583 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
585 VERIFY_NON_NULL(address, TAG, "address is null");
586 VERIFY_NON_NULL(data, TAG, "data is null");
590 OIC_LOG(ERROR, TAG, "g_jvm is null");
591 return CA_STATUS_FAILED;
594 bool isAttached = false;
596 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
599 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
600 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
603 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
604 return CA_STATUS_FAILED;
609 ca_mutex_lock(g_threadSendMutex);
611 CAResult_t ret = CA_STATUS_OK;
612 if (g_context && g_deviceList)
614 uint32_t length = u_arraylist_length(g_deviceList);
615 for (uint32_t index = 0; index < length; index++)
617 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
620 OIC_LOG(ERROR, TAG, "jarrayObj is null");
624 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
627 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
631 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
634 OIC_LOG(ERROR, TAG, "setAddress is null");
638 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
640 if (!strcmp(setAddress, address))
642 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
644 // connect to gatt server
645 ret = CALEClientStopScan();
646 if (CA_STATUS_OK != ret)
648 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
654 (*env)->DeleteGlobalRef(env, g_sendBuffer);
657 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
658 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
659 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
661 ret = CALEClientSendData(env, jarrayObj);
662 if (CA_STATUS_OK != ret)
664 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
668 OIC_LOG(INFO, TAG, "wake up");
671 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
677 (*g_jvm)->DetachCurrentThread(g_jvm);
680 // start LE Scan again
681 ret = CALEClientStartScan();
682 if (CA_STATUS_OK != ret)
684 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
685 ca_mutex_unlock(g_threadSendMutex);
689 ca_mutex_unlock(g_threadSendMutex);
690 OIC_LOG(INFO, TAG, "unicast - send success");
696 // start LE Scan again
697 ret = CALEClientStartScan();
698 if (CA_STATUS_OK != ret)
700 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
701 ca_mutex_unlock(g_threadSendMutex);
704 (*g_jvm)->DetachCurrentThread(g_jvm);
711 (*g_jvm)->DetachCurrentThread(g_jvm);
714 if (g_clientErrorCallback)
716 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
718 ca_mutex_unlock(g_threadSendMutex);
719 return CA_SEND_FAILED;
722 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
723 const uint32_t dataLen)
725 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
726 VERIFY_NON_NULL(data, TAG, "data is null");
727 VERIFY_NON_NULL(env, TAG, "env is null");
731 OIC_LOG(ERROR, TAG, "g_deviceList is null");
732 return CA_STATUS_FAILED;
735 ca_mutex_lock(g_threadSendMutex);
737 CALEClientSetSendFinishFlag(false);
739 OIC_LOG(DEBUG, TAG, "set byteArray for data");
742 (*env)->DeleteGlobalRef(env, g_sendBuffer);
746 if (0 == u_arraylist_length(g_deviceList))
748 // Wait for LE peripherals to be discovered.
750 // Number of times to wait for discovery to complete.
751 static size_t const RETRIES = 5;
753 static uint64_t const TIMEOUT =
754 2 * MICROSECS_PER_SEC; // Microseconds
756 bool devicesDiscovered = false;
758 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
761 if (ca_cond_wait_for(g_deviceDescCond,
765 devicesDiscovered = true;
769 if (!devicesDiscovered)
775 // connect to gatt server
776 CAResult_t res = CALEClientStopScan();
777 if (CA_STATUS_OK != res)
779 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
780 ca_mutex_unlock(g_threadSendMutex);
783 uint32_t length = u_arraylist_length(g_deviceList);
784 g_targetCnt = length;
786 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
787 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
788 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
790 for (uint32_t index = 0; index < length; index++)
792 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
795 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
799 res = CALEClientSendData(env, jarrayObj);
800 if (res != CA_STATUS_OK)
802 OIC_LOG(ERROR, TAG, "BT device - send has failed");
805 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
808 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
812 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
815 OIC_LOG(ERROR, TAG, "address is not available");
819 (*env)->ReleaseStringUTFChars(env, jni_address, address);
822 OIC_LOG(DEBUG, TAG, "connection routine is finished");
824 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
825 if (!g_isFinishedSendData)
827 ca_mutex_lock(g_threadMutex);
828 ca_cond_wait(g_threadCond, g_threadMutex);
829 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
830 ca_mutex_unlock(g_threadMutex);
833 // start LE Scan again
834 res = CALEClientStartScan();
835 if (CA_STATUS_OK != res)
837 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
838 ca_mutex_unlock(g_threadSendMutex);
842 ca_mutex_unlock(g_threadSendMutex);
843 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
847 res = CALEClientStartScan();
848 if (CA_STATUS_OK != res)
850 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
851 ca_mutex_unlock(g_threadSendMutex);
855 ca_mutex_unlock(g_threadSendMutex);
856 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
857 return CA_SEND_FAILED;
860 CAResult_t CALECheckSendState(const char* address)
862 VERIFY_NON_NULL(address, TAG, "address is null");
864 ca_mutex_lock(g_deviceStateListMutex);
865 CALEState_t* state = CALEClientGetStateInfo(address);
868 OIC_LOG(ERROR, TAG, "state is null");
869 ca_mutex_unlock(g_deviceStateListMutex);
870 return CA_SEND_FAILED;
873 if (STATE_SEND_SUCCESS != state->sendState)
875 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
876 ca_mutex_unlock(g_deviceStateListMutex);
877 return CA_SEND_FAILED;
879 ca_mutex_unlock(g_deviceStateListMutex);
883 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
885 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
886 VERIFY_NON_NULL(device, TAG, "device is null");
887 VERIFY_NON_NULL(env, TAG, "env is null");
889 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
892 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
893 return CA_STATUS_FAILED;
896 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
899 OIC_LOG(ERROR, TAG, "address is not available");
900 return CA_STATUS_FAILED;
903 ca_mutex_lock(g_deviceStateListMutex);
904 CALEState_t* state = CALEClientGetStateInfo(address);
905 ca_mutex_unlock(g_deviceStateListMutex);
908 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
909 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
910 if (CA_STATUS_OK != ret)
912 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
913 (*env)->ReleaseStringUTFChars(env, jni_address, address);
919 if (STATE_CONNECTED == state->connectedState)
921 OIC_LOG(INFO, TAG, "GATT has already connected");
922 jobject gatt = CALEClientGetGattObjInList(env, address);
925 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
926 (*env)->ReleaseStringUTFChars(env, jni_address, address);
927 return CA_STATUS_FAILED;
930 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
931 if (CA_STATUS_OK != ret)
933 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
934 (*env)->ReleaseStringUTFChars(env, jni_address, address);
940 OIC_LOG(DEBUG, TAG, "start to connect LE");
941 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
942 if (CA_STATUS_OK != ret)
944 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
945 (*env)->ReleaseStringUTFChars(env, jni_address, address);
951 (*env)->ReleaseStringUTFChars(env, jni_address, address);
955 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
957 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
958 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
960 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
961 if (!jni_cid_gattdevice_list)
963 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
967 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
968 "()Landroid/bluetooth/BluetoothDevice;");
969 if (!jni_mid_getDevice)
971 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
975 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
978 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
982 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
985 OIC_LOG(ERROR, TAG, "jni_address is null");
995 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
998 OIC_LOG(DEBUG, TAG, "Gatt Close");
999 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1000 VERIFY_NON_NULL(env, TAG, "env is null");
1002 // get BluetoothGatt class
1003 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1004 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1005 if (!jni_cid_BluetoothGatt)
1007 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1008 return CA_STATUS_FAILED;
1011 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1012 if (!jni_mid_closeGatt)
1014 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1015 return CA_STATUS_OK;
1018 // call disconnect gatt method
1019 OIC_LOG(DEBUG, TAG, "request to close GATT");
1020 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1022 if ((*env)->ExceptionCheck(env))
1024 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1025 (*env)->ExceptionDescribe(env);
1026 (*env)->ExceptionClear(env);
1027 return CA_STATUS_FAILED;
1030 return CA_STATUS_OK;
1033 CAResult_t CALEClientStartScan()
1035 if (!g_isStartedMulticastServer)
1037 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1038 return CA_STATUS_FAILED;
1041 if (!g_isStartedLEClient)
1043 OIC_LOG(ERROR, TAG, "LE client is not started");
1044 return CA_STATUS_FAILED;
1049 OIC_LOG(ERROR, TAG, "g_jvm is null");
1050 return CA_STATUS_FAILED;
1053 if (g_isStartedScan)
1055 OIC_LOG(INFO, TAG, "scanning is already started");
1056 return CA_STATUS_OK;
1059 bool isAttached = false;
1061 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1064 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1066 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1069 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1070 return CA_STATUS_FAILED;
1075 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1077 CAResult_t ret = CA_STATUS_OK;
1078 // scan gatt server with UUID
1079 if (g_leScanCallback && g_uuidList)
1082 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1083 if(CA_STATUS_OK != ret)
1085 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
1088 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1089 if (CA_STATUS_OK != ret)
1091 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
1098 (*g_jvm)->DetachCurrentThread(g_jvm);
1104 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1106 VERIFY_NON_NULL(callback, TAG, "callback is null");
1107 VERIFY_NON_NULL(env, TAG, "env is null");
1109 if (!CALEIsEnableBTAdapter(env))
1111 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1112 return CA_ADAPTER_NOT_ENABLED;
1115 // get default bt adapter class
1116 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1117 if (!jni_cid_BTAdapter)
1119 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1120 return CA_STATUS_FAILED;
1123 // get remote bt adapter method
1124 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1125 "getDefaultAdapter",
1126 METHODID_OBJECTNONPARAM);
1127 if (!jni_mid_getDefaultAdapter)
1129 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1130 return CA_STATUS_FAILED;
1133 // get start le scan method
1134 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1135 "(Landroid/bluetooth/BluetoothAdapter$"
1136 "LeScanCallback;)Z");
1137 if (!jni_mid_startLeScan)
1139 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1140 return CA_STATUS_FAILED;
1143 // gat bt adapter object
1144 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1145 jni_mid_getDefaultAdapter);
1146 if (!jni_obj_BTAdapter)
1148 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1149 return CA_STATUS_FAILED;
1152 // call start le scan method
1153 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1154 jni_mid_startLeScan, callback);
1155 if (!jni_obj_startLeScan)
1157 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1158 return CA_STATUS_FAILED;
1162 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1163 CALEClientSetScanFlag(true);
1166 return CA_STATUS_OK;
1169 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1171 VERIFY_NON_NULL(callback, TAG, "callback is null");
1172 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1173 VERIFY_NON_NULL(env, TAG, "env is null");
1175 if (!CALEIsEnableBTAdapter(env))
1177 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1178 return CA_ADAPTER_NOT_ENABLED;
1181 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1182 if (!jni_cid_BTAdapter)
1184 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1185 return CA_STATUS_FAILED;
1188 // get remote bt adapter method
1189 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1190 "getDefaultAdapter",
1191 METHODID_OBJECTNONPARAM);
1192 if (!jni_mid_getDefaultAdapter)
1194 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1195 return CA_STATUS_FAILED;
1198 // get start le scan method
1199 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1200 "([Ljava/util/UUID;Landroid/bluetooth/"
1201 "BluetoothAdapter$LeScanCallback;)Z");
1202 if (!jni_mid_startLeScan)
1204 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1205 return CA_STATUS_FAILED;
1208 // get bt adapter object
1209 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1210 jni_mid_getDefaultAdapter);
1211 if (!jni_obj_BTAdapter)
1213 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1214 return CA_STATUS_FAILED;
1217 // call start le scan method
1218 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1219 jni_mid_startLeScan, uuids, callback);
1220 if (!jni_obj_startLeScan)
1222 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1223 return CA_STATUS_FAILED;
1227 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1228 CALEClientSetScanFlag(true);
1231 return CA_STATUS_OK;
1234 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1236 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1237 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1240 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1243 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1247 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1248 "(Ljava/lang/String;)"
1249 "Ljava/util/UUID;");
1250 if (!jni_mid_fromString)
1252 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1256 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1257 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1261 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1265 return jni_obj_uuid;
1268 CAResult_t CALEClientStopScan()
1272 OIC_LOG(ERROR, TAG, "g_jvm is null");
1273 return CA_STATUS_FAILED;
1276 if (!g_isStartedScan)
1278 OIC_LOG(INFO, TAG, "scanning is already stopped");
1279 return CA_STATUS_OK;
1282 bool isAttached = false;
1284 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1287 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1288 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1291 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1292 return CA_STATUS_FAILED;
1297 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1298 if (CA_STATUS_OK != ret)
1300 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1304 CALEClientSetScanFlag(false);
1309 (*g_jvm)->DetachCurrentThread(g_jvm);
1315 void CALEClientSetScanFlag(bool flag)
1317 ca_mutex_lock(g_scanMutex);
1318 g_isStartedScan = flag;
1319 ca_mutex_unlock(g_scanMutex);
1322 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1324 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1325 VERIFY_NON_NULL(callback, TAG, "callback is null");
1326 VERIFY_NON_NULL(env, TAG, "env is null");
1328 if (!CALEIsEnableBTAdapter(env))
1330 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1331 return CA_ADAPTER_NOT_ENABLED;
1334 // get default bt adapter class
1335 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1336 if (!jni_cid_BTAdapter)
1338 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1339 return CA_STATUS_FAILED;
1342 // get remote bt adapter method
1343 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1344 "getDefaultAdapter",
1345 METHODID_OBJECTNONPARAM);
1346 if (!jni_mid_getDefaultAdapter)
1348 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1349 return CA_STATUS_FAILED;
1352 // get start le scan method
1353 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1354 "(Landroid/bluetooth/"
1355 "BluetoothAdapter$LeScanCallback;)V");
1356 if (!jni_mid_stopLeScan)
1358 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1359 return CA_STATUS_FAILED;
1362 // gat bt adapter object
1363 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1364 jni_mid_getDefaultAdapter);
1365 if (!jni_obj_BTAdapter)
1367 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1368 return CA_STATUS_FAILED;
1371 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1372 // call start le scan method
1373 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1374 if ((*env)->ExceptionCheck(env))
1376 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1377 (*env)->ExceptionDescribe(env);
1378 (*env)->ExceptionClear(env);
1379 return CA_STATUS_FAILED;
1382 return CA_STATUS_OK;
1385 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1388 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1389 VERIFY_NON_NULL(env, TAG, "env is null");
1390 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1391 VERIFY_NON_NULL(callback, TAG, "callback is null");
1393 if (!CALEIsEnableBTAdapter(env))
1395 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1396 return CA_ADAPTER_NOT_ENABLED;
1399 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1402 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1403 return CA_STATUS_FAILED;
1406 // get BluetoothDevice class
1407 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1408 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1409 if (!jni_cid_BluetoothDevice)
1411 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1412 return CA_STATUS_FAILED;
1415 // get connectGatt method
1416 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1417 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1418 "(Landroid/content/Context;ZLandroid/"
1419 "bluetooth/BluetoothGattCallback;)"
1420 "Landroid/bluetooth/BluetoothGatt;");
1421 if (!jni_mid_connectGatt)
1423 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1424 return CA_STATUS_FAILED;
1427 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1428 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1429 jni_mid_connectGatt,
1431 autoconnect, callback);
1432 if (!jni_obj_connectGatt)
1434 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1435 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1436 CALEClientUpdateSendCnt(env);
1437 return CA_STATUS_FAILED;
1441 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1443 return CA_STATUS_OK;
1446 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1448 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1449 VERIFY_NON_NULL(env, TAG, "env is null");
1450 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1452 if (!CALEIsEnableBTAdapter(env))
1454 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1455 return CA_ADAPTER_NOT_ENABLED;
1458 // get BluetoothGatt class
1459 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1460 if (!jni_cid_BluetoothGatt)
1462 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1463 return CA_STATUS_FAILED;
1466 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1467 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1468 "disconnect", "()V");
1469 if (!jni_mid_disconnectGatt)
1471 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1472 return CA_STATUS_FAILED;
1475 // call disconnect gatt method
1476 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1477 if ((*env)->ExceptionCheck(env))
1479 OIC_LOG(ERROR, TAG, "disconnect has failed");
1480 (*env)->ExceptionDescribe(env);
1481 (*env)->ExceptionClear(env);
1482 return CA_STATUS_FAILED;
1485 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1487 return CA_STATUS_OK;
1490 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1492 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1493 VERIFY_NON_NULL(env, TAG, "env is null");
1495 if (!g_gattObjectList)
1497 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1498 return CA_STATUS_FAILED;
1501 uint32_t length = u_arraylist_length(g_gattObjectList);
1502 for (uint32_t index = 0; index < length; index++)
1504 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1507 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1510 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1511 if (CA_STATUS_OK != res)
1513 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1518 OICFree(g_gattObjectList);
1519 g_gattObjectList = NULL;
1521 return CA_STATUS_OK;
1524 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1526 VERIFY_NON_NULL(env, TAG, "env is null");
1527 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1529 if (!CALEIsEnableBTAdapter(env))
1531 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1532 return CA_ADAPTER_NOT_ENABLED;
1535 // get BluetoothGatt class
1536 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1537 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1538 if (!jni_cid_BluetoothGatt)
1540 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1541 return CA_STATUS_FAILED;
1544 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1545 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1546 "discoverServices", "()Z");
1547 if (!jni_mid_discoverServices)
1549 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1550 return CA_STATUS_FAILED;
1552 // call disconnect gatt method
1553 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1554 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1557 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1558 return CA_STATUS_FAILED;
1561 return CA_STATUS_OK;
1564 static void CALEWriteCharacteristicThread(void* object)
1566 VERIFY_NON_NULL(object, TAG, "object is null");
1568 bool isAttached = false;
1570 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1573 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1574 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1578 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1584 jobject gatt = (jobject)object;
1585 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1586 if (CA_STATUS_OK != ret)
1588 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1593 (*g_jvm)->DetachCurrentThread(g_jvm);
1597 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1599 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1600 VERIFY_NON_NULL(env, TAG, "env is null");
1603 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1604 if (!jni_obj_character)
1606 CALEClientSendFinish(env, gatt);
1607 return CA_STATUS_FAILED;
1610 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1611 if (CA_STATUS_OK != ret)
1613 CALEClientSendFinish(env, gatt);
1614 return CA_STATUS_FAILED;
1617 // wait for callback for write Characteristic with success to sent data
1618 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1619 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1620 if (!g_isSignalSetFlag)
1622 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1623 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
1624 g_threadWriteCharacteristicMutex,
1625 WAIT_TIME_WRITE_CHARACTERISTIC))
1627 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1628 g_isSignalSetFlag = false;
1629 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1630 return CA_STATUS_FAILED;
1633 // reset flag set by writeCharacteristic Callback
1634 g_isSignalSetFlag = false;
1635 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1637 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
1638 return CA_STATUS_OK;
1641 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1643 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
1644 VERIFY_NON_NULL(env, TAG, "env is null");
1645 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1647 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
1648 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
1649 CALEWriteCharacteristicThread, (void*)gattParam))
1651 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
1652 return CA_STATUS_FAILED;
1655 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
1656 return CA_STATUS_OK;
1659 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1660 jobject gattCharacteristic)
1662 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1663 VERIFY_NON_NULL(env, TAG, "env is null");
1664 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1665 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1667 if (!CALEIsEnableBTAdapter(env))
1669 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1670 return CA_STATUS_FAILED;
1673 // get BluetoothGatt class
1674 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1675 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1676 if (!jni_cid_BluetoothGatt)
1678 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1679 return CA_STATUS_FAILED;
1682 OIC_LOG(DEBUG, TAG, "write characteristic method");
1683 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1684 "writeCharacteristic",
1685 "(Landroid/bluetooth/"
1686 "BluetoothGattCharacteristic;)Z");
1687 if (!jni_mid_writeCharacteristic)
1689 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1690 return CA_STATUS_FAILED;
1693 // call disconnect gatt method
1694 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1695 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1696 jni_mid_writeCharacteristic,
1697 gattCharacteristic);
1700 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
1704 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1705 return CA_STATUS_FAILED;
1708 return CA_STATUS_OK;
1711 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1713 VERIFY_NON_NULL(env, TAG, "env is null");
1714 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1716 if (!CALEIsEnableBTAdapter(env))
1718 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1719 return CA_STATUS_FAILED;
1722 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1723 if (!jni_cid_BluetoothGatt)
1725 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1726 return CA_STATUS_FAILED;
1729 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1732 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1733 return CA_STATUS_FAILED;
1736 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1737 if (!jni_obj_GattCharacteristic)
1739 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1740 return CA_STATUS_FAILED;
1743 OIC_LOG(DEBUG, TAG, "read characteristic method");
1744 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1745 "readCharacteristic",
1746 "(Landroid/bluetooth/"
1747 "BluetoothGattCharacteristic;)Z");
1748 if (!jni_mid_readCharacteristic)
1750 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1751 return CA_STATUS_FAILED;
1754 // call disconnect gatt method
1755 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1756 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1757 jni_obj_GattCharacteristic);
1760 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1764 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1765 return CA_STATUS_FAILED;
1768 return CA_STATUS_OK;
1771 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1772 jobject characteristic)
1774 VERIFY_NON_NULL(env, TAG, "env is null");
1775 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1776 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1778 if (!CALEIsEnableBTAdapter(env))
1780 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1781 return CA_ADAPTER_NOT_ENABLED;
1784 // get BluetoothGatt class
1785 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1786 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1787 if (!jni_cid_BluetoothGatt)
1789 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1790 return CA_STATUS_FAILED;
1793 // set Characteristic Notification
1794 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1795 "setCharacteristicNotification",
1796 "(Landroid/bluetooth/"
1797 "BluetoothGattCharacteristic;Z)Z");
1798 if (!jni_mid_setNotification)
1800 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1801 return CA_STATUS_FAILED;
1804 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1805 characteristic, JNI_TRUE);
1806 if (JNI_TRUE == ret)
1808 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1812 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1813 return CA_STATUS_FAILED;
1816 return CA_STATUS_OK;
1819 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1821 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1822 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1823 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1825 if (!CALEIsEnableBTAdapter(env))
1827 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1831 // get BluetoothGatt class
1832 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1833 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1834 if (!jni_cid_BluetoothGatt)
1836 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1840 jmethodID jni_mid_getService = (*env)->GetMethodID(
1841 env, jni_cid_BluetoothGatt, "getService",
1842 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1843 if (!jni_mid_getService)
1845 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1849 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1850 if (!jni_obj_service_uuid)
1852 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1856 // get bluetooth gatt service
1857 OIC_LOG(DEBUG, TAG, "request to get service");
1858 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1859 jni_obj_service_uuid);
1860 if (!jni_obj_gattService)
1862 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1866 // get bluetooth gatt service class
1867 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1868 env, "android/bluetooth/BluetoothGattService");
1869 if (!jni_cid_BluetoothGattService)
1871 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1875 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1876 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1877 "getCharacteristic",
1878 "(Ljava/util/UUID;)"
1879 "Landroid/bluetooth/"
1880 "BluetoothGattCharacteristic;");
1881 if (!jni_mid_getCharacteristic)
1883 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1887 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1890 OIC_LOG(ERROR, TAG, "uuid is null");
1894 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1895 if (!jni_obj_tx_uuid)
1897 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1898 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1902 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1903 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1904 jni_mid_getCharacteristic,
1907 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1908 return jni_obj_GattCharacteristic;
1911 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1913 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1914 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1915 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1916 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1918 if (!CALEIsEnableBTAdapter(env))
1920 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1924 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1927 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1931 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1932 if (!jni_obj_GattCharacteristic)
1934 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1938 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1939 "/BluetoothGattCharacteristic");
1940 if (!jni_cid_BTGattCharacteristic)
1942 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1946 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1947 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1949 if (!jni_mid_setValue)
1951 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1955 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1957 if (JNI_TRUE == ret)
1959 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1963 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1968 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1969 "setWriteType", "(I)V");
1970 if (!jni_mid_setWriteType)
1972 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1976 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1977 "WRITE_TYPE_NO_RESPONSE", "I");
1978 if (!jni_fid_no_response)
1980 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1984 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1985 jni_fid_no_response);
1987 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1989 return jni_obj_GattCharacteristic;
1992 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1994 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1995 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1997 if (!CALEIsEnableBTAdapter(env))
1999 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
2003 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2004 "BluetoothGattCharacteristic");
2005 if (!jni_cid_BTGattCharacteristic)
2007 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2011 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2012 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2014 if (!jni_mid_getValue)
2016 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2020 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2022 return jni_obj_data_array;
2025 CAResult_t CALEClientCreateUUIDList()
2029 OIC_LOG(ERROR, TAG, "g_jvm is null");
2030 return CA_STATUS_FAILED;
2033 bool isAttached = false;
2035 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2038 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2039 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2043 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2044 return CA_STATUS_FAILED;
2049 // create new object array
2050 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2051 if (!jni_cid_uuid_list)
2053 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2057 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2058 jni_cid_uuid_list, NULL);
2059 if (!jni_obj_uuid_list)
2061 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2066 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2069 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2072 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2074 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2078 (*g_jvm)->DetachCurrentThread(g_jvm);
2081 return CA_STATUS_OK;
2088 (*g_jvm)->DetachCurrentThread(g_jvm);
2090 return CA_STATUS_FAILED;
2093 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2094 jobject characteristic)
2096 VERIFY_NON_NULL(env, TAG, "env is null");
2097 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2098 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2100 if (!CALEIsEnableBTAdapter(env))
2102 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
2103 return CA_ADAPTER_NOT_ENABLED;
2106 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2107 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2108 "BluetoothGattCharacteristic");
2109 if (!jni_cid_BTGattCharacteristic)
2111 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2112 return CA_STATUS_FAILED;
2115 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2116 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2118 "(Ljava/util/UUID;)Landroid/bluetooth/"
2119 "BluetoothGattDescriptor;");
2120 if (!jni_mid_getDescriptor)
2122 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2123 return CA_STATUS_FAILED;
2126 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2127 if (!jni_obj_cc_uuid)
2129 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2130 return CA_STATUS_FAILED;
2133 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2134 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2135 jni_mid_getDescriptor, jni_obj_cc_uuid);
2136 if (!jni_obj_descriptor)
2138 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2139 return CA_NOT_SUPPORTED;
2142 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2143 jclass jni_cid_descriptor = (*env)->FindClass(env,
2144 "android/bluetooth/BluetoothGattDescriptor");
2145 if (!jni_cid_descriptor)
2147 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2148 return CA_STATUS_FAILED;
2151 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2152 if (!jni_mid_setValue)
2154 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2155 return CA_STATUS_FAILED;
2158 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2159 "ENABLE_NOTIFICATION_VALUE", "[B");
2160 if (!jni_fid_NotiValue)
2162 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2163 return CA_STATUS_FAILED;
2166 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2168 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2169 env, jni_obj_descriptor, jni_mid_setValue,
2170 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2173 OIC_LOG(DEBUG, TAG, "setValue success");
2177 OIC_LOG(ERROR, TAG, "setValue has failed");
2178 return CA_STATUS_FAILED;
2181 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2184 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2185 return CA_STATUS_FAILED;
2188 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2189 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2190 "(Landroid/bluetooth/"
2191 "BluetoothGattDescriptor;)Z");
2192 if (!jni_mid_writeDescriptor)
2194 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2195 return CA_STATUS_FAILED;
2198 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2199 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2200 jni_obj_descriptor);
2203 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2207 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2208 return CA_STATUS_FAILED;
2211 return CA_STATUS_OK;
2214 void CALEClientCreateScanDeviceList(JNIEnv *env)
2216 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2217 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2219 ca_mutex_lock(g_deviceListMutex);
2220 // create new object array
2221 if (g_deviceList == NULL)
2223 OIC_LOG(DEBUG, TAG, "Create device list");
2225 g_deviceList = u_arraylist_create();
2227 ca_mutex_unlock(g_deviceListMutex);
2230 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2232 VERIFY_NON_NULL(device, TAG, "device is null");
2233 VERIFY_NON_NULL(env, TAG, "env is null");
2235 ca_mutex_lock(g_deviceListMutex);
2239 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2240 ca_mutex_unlock(g_deviceListMutex);
2241 return CA_STATUS_FAILED;
2244 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2245 if (!jni_remoteAddress)
2247 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2248 ca_mutex_unlock(g_deviceListMutex);
2249 return CA_STATUS_FAILED;
2252 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2255 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2256 ca_mutex_unlock(g_deviceListMutex);
2257 return CA_STATUS_FAILED;
2260 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2262 jobject gdevice = (*env)->NewGlobalRef(env, device);
2263 u_arraylist_add(g_deviceList, gdevice);
2264 ca_cond_signal(g_deviceDescCond);
2265 OIC_LOG_V(DEBUG, TAG, "Added this Device[%s] in the List", remoteAddress);
2267 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2269 ca_mutex_unlock(g_deviceListMutex);
2271 return CA_STATUS_OK;
2274 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2276 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2277 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2281 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2285 uint32_t length = u_arraylist_length(g_deviceList);
2286 for (uint32_t index = 0; index < length; index++)
2288 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2291 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2295 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2296 if (!jni_setAddress)
2298 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2302 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2305 OIC_LOG(ERROR, TAG, "setAddress is null");
2309 if (!strcmp(remoteAddress, setAddress))
2311 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2315 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2318 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2323 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2325 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2326 VERIFY_NON_NULL(env, TAG, "env is null");
2328 ca_mutex_lock(g_deviceListMutex);
2332 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2333 ca_mutex_unlock(g_deviceListMutex);
2334 return CA_STATUS_FAILED;
2337 uint32_t length = u_arraylist_length(g_deviceList);
2338 for (uint32_t index = 0; index < length; index++)
2340 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2343 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2346 (*env)->DeleteGlobalRef(env, jarrayObj);
2349 OICFree(g_deviceList);
2350 g_deviceList = NULL;
2352 ca_mutex_unlock(g_deviceListMutex);
2353 return CA_STATUS_OK;
2356 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2358 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2359 VERIFY_NON_NULL(address, TAG, "address is null");
2360 VERIFY_NON_NULL(env, TAG, "env is null");
2362 ca_mutex_lock(g_deviceListMutex);
2366 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2367 ca_mutex_unlock(g_deviceListMutex);
2368 return CA_STATUS_FAILED;
2371 uint32_t length = u_arraylist_length(g_deviceList);
2372 for (uint32_t index = 0; index < length; index++)
2374 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2377 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2378 ca_mutex_unlock(g_deviceListMutex);
2379 return CA_STATUS_FAILED;
2382 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2383 if (!jni_setAddress)
2385 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2386 ca_mutex_unlock(g_deviceListMutex);
2387 return CA_STATUS_FAILED;
2390 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2393 OIC_LOG(ERROR, TAG, "setAddress is null");
2394 ca_mutex_unlock(g_deviceListMutex);
2395 return CA_STATUS_FAILED;
2398 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2401 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2402 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2403 ca_mutex_unlock(g_deviceListMutex);
2404 return CA_STATUS_FAILED;
2407 if (!strcmp(setAddress, remoteAddress))
2409 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2410 (*env)->DeleteGlobalRef(env, jarrayObj);
2411 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2412 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2414 if (NULL == u_arraylist_remove(g_deviceList, index))
2416 OIC_LOG(ERROR, TAG, "List removal failed.");
2417 ca_mutex_unlock(g_deviceListMutex);
2418 return CA_STATUS_FAILED;
2420 ca_mutex_unlock(g_deviceListMutex);
2421 return CA_STATUS_OK;
2423 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2424 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2427 ca_mutex_unlock(g_deviceListMutex);
2428 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2430 return CA_STATUS_OK;
2437 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2439 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2440 VERIFY_NON_NULL(env, TAG, "env is null");
2441 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2443 ca_mutex_lock(g_gattObjectMutex);
2445 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2446 if (!jni_remoteAddress)
2448 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2449 ca_mutex_unlock(g_gattObjectMutex);
2450 return CA_STATUS_FAILED;
2453 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2456 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2457 ca_mutex_unlock(g_gattObjectMutex);
2458 return CA_STATUS_FAILED;
2461 if (!CALEClientIsGattObjInList(env, remoteAddress))
2463 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2464 u_arraylist_add(g_gattObjectList, newGatt);
2465 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2468 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2469 ca_mutex_unlock(g_gattObjectMutex);
2470 return CA_STATUS_OK;
2473 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2475 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2476 VERIFY_NON_NULL(env, TAG, "env is null");
2477 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2479 uint32_t length = u_arraylist_length(g_gattObjectList);
2480 for (uint32_t index = 0; index < length; index++)
2483 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2486 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2490 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2491 if (!jni_setAddress)
2493 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2497 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2500 OIC_LOG(ERROR, TAG, "setAddress is null");
2504 if (!strcmp(remoteAddress, setAddress))
2506 OIC_LOG(DEBUG, TAG, "the device is already set");
2507 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2512 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2517 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2521 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2523 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2524 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2525 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2527 ca_mutex_lock(g_gattObjectMutex);
2528 uint32_t length = u_arraylist_length(g_gattObjectList);
2529 for (uint32_t index = 0; index < length; index++)
2531 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2534 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2535 ca_mutex_unlock(g_gattObjectMutex);
2539 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2540 if (!jni_setAddress)
2542 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2543 ca_mutex_unlock(g_gattObjectMutex);
2547 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2550 OIC_LOG(ERROR, TAG, "setAddress is null");
2551 ca_mutex_unlock(g_gattObjectMutex);
2555 if (!strcmp(remoteAddress, setAddress))
2557 OIC_LOG(DEBUG, TAG, "the device is already set");
2558 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2559 ca_mutex_unlock(g_gattObjectMutex);
2562 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2565 ca_mutex_unlock(g_gattObjectMutex);
2566 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2570 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2572 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2573 VERIFY_NON_NULL(env, TAG, "env is null");
2575 ca_mutex_lock(g_gattObjectMutex);
2576 if (!g_gattObjectList)
2578 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2579 ca_mutex_unlock(g_gattObjectMutex);
2580 return CA_STATUS_FAILED;
2583 uint32_t length = u_arraylist_length(g_gattObjectList);
2584 for (uint32_t index = 0; index < length; index++)
2586 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2589 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2592 (*env)->DeleteGlobalRef(env, jarrayObj);
2595 OICFree(g_gattObjectList);
2596 g_gattObjectList = NULL;
2597 ca_mutex_unlock(g_gattObjectMutex);
2598 return CA_STATUS_OK;
2601 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2603 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2604 VERIFY_NON_NULL(gatt, TAG, "gatt 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 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2643 if (!jni_remoteAddress)
2645 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2646 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2647 ca_mutex_unlock(g_gattObjectMutex);
2648 return CA_STATUS_FAILED;
2651 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2654 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2655 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2656 ca_mutex_unlock(g_gattObjectMutex);
2657 return CA_STATUS_FAILED;
2660 if (!strcmp(setAddress, remoteAddress))
2662 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2663 (*env)->DeleteGlobalRef(env, jarrayObj);
2664 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2665 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2667 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2669 OIC_LOG(ERROR, TAG, "List removal failed.");
2670 ca_mutex_unlock(g_gattObjectMutex);
2671 return CA_STATUS_FAILED;
2673 ca_mutex_unlock(g_gattObjectMutex);
2674 return CA_STATUS_OK;
2676 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2677 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2680 ca_mutex_unlock(g_gattObjectMutex);
2681 OIC_LOG(DEBUG, TAG, "there are no target object");
2682 return CA_STATUS_OK;
2685 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2687 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2688 VERIFY_NON_NULL(addr, TAG, "addr is null");
2689 VERIFY_NON_NULL(env, TAG, "env is null");
2691 ca_mutex_lock(g_gattObjectMutex);
2692 if (!g_gattObjectList)
2694 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2695 ca_mutex_unlock(g_gattObjectMutex);
2696 return CA_STATUS_FAILED;
2699 uint32_t length = u_arraylist_length(g_gattObjectList);
2700 for (uint32_t index = 0; index < length; index++)
2702 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2705 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2706 ca_mutex_unlock(g_gattObjectMutex);
2707 return CA_STATUS_FAILED;
2710 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2711 if (!jni_setAddress)
2713 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2714 ca_mutex_unlock(g_gattObjectMutex);
2715 return CA_STATUS_FAILED;
2718 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2721 OIC_LOG(ERROR, TAG, "setAddress is null");
2722 ca_mutex_unlock(g_gattObjectMutex);
2723 return CA_STATUS_FAILED;
2726 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2729 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2730 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2731 ca_mutex_unlock(g_gattObjectMutex);
2732 return CA_STATUS_FAILED;
2735 if (!strcmp(setAddress, remoteAddress))
2737 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2738 (*env)->DeleteGlobalRef(env, jarrayObj);
2740 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2741 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2742 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2744 OIC_LOG(ERROR, TAG, "List removal failed.");
2745 ca_mutex_unlock(g_gattObjectMutex);
2746 return CA_STATUS_FAILED;
2748 ca_mutex_unlock(g_gattObjectMutex);
2749 return CA_STATUS_OK;
2751 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2752 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2755 ca_mutex_unlock(g_gattObjectMutex);
2756 OIC_LOG(DEBUG, TAG, "there are no target object");
2757 return CA_STATUS_FAILED;
2764 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2765 uint16_t notificationState, uint16_t sendState)
2767 VERIFY_NON_NULL(address, TAG, "address is null");
2769 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2772 OIC_LOG(ERROR, TAG, "out of memory");
2773 return CA_MEMORY_ALLOC_FAILED;
2776 if (strlen(address) > CA_MACADDR_SIZE)
2778 OIC_LOG(ERROR, TAG, "address is not proper");
2780 return CA_STATUS_FAILED;
2783 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2784 newstate->connectedState = connectedState;
2785 newstate->notificationState = notificationState;
2786 newstate->sendState = sendState;
2787 return CALEClientAddDeviceStateToList(newstate);
2790 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2792 VERIFY_NON_NULL(state, TAG, "state is null");
2794 ca_mutex_lock(g_deviceStateListMutex);
2796 if (!g_deviceStateList)
2798 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2799 ca_mutex_unlock(g_deviceStateListMutex);
2800 return CA_STATUS_FAILED;
2803 if (CALEClientIsDeviceInList(state->address))
2805 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2808 OIC_LOG(ERROR, TAG, "curState is null");
2809 ca_mutex_unlock(g_deviceStateListMutex);
2810 return CA_STATUS_FAILED;
2813 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2815 state->notificationState = curState->notificationState;
2818 // delete previous state for update new state
2819 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2820 if (CA_STATUS_OK != res)
2822 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2823 ca_mutex_unlock(g_deviceStateListMutex);
2827 u_arraylist_add(g_deviceStateList, state); // update new state
2828 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2829 state->connectedState, state->notificationState);
2831 ca_mutex_unlock(g_deviceStateListMutex);
2832 return CA_STATUS_OK;
2835 bool CALEClientIsDeviceInList(const char* remoteAddress)
2837 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2839 if (!g_deviceStateList)
2841 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2845 uint32_t length = u_arraylist_length(g_deviceStateList);
2846 for (uint32_t index = 0; index < length; index++)
2848 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2851 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2855 if (!strcmp(remoteAddress, state->address))
2857 OIC_LOG(DEBUG, TAG, "the device is already set");
2866 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2870 CAResult_t CALEClientRemoveAllDeviceState()
2872 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2874 ca_mutex_lock(g_deviceStateListMutex);
2875 if (!g_deviceStateList)
2877 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2878 ca_mutex_unlock(g_deviceStateListMutex);
2879 return CA_STATUS_FAILED;
2882 uint32_t length = u_arraylist_length(g_deviceStateList);
2883 for (uint32_t index = 0; index < length; index++)
2885 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2888 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2894 OICFree(g_deviceStateList);
2895 g_deviceStateList = NULL;
2896 ca_mutex_unlock(g_deviceStateListMutex);
2898 return CA_STATUS_OK;
2901 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2903 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2904 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2906 if (!g_deviceStateList)
2908 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2909 return CA_STATUS_FAILED;
2912 uint32_t length = u_arraylist_length(g_deviceStateList);
2913 for (uint32_t index = 0; index < length; index++)
2915 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2918 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2922 if (!strcmp(state->address, remoteAddress))
2924 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2927 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2929 OIC_LOG(ERROR, TAG, "List removal failed.");
2930 return CA_STATUS_FAILED;
2933 return CA_STATUS_OK;
2937 return CA_STATUS_FAILED;
2940 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2942 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2943 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2945 if (!g_deviceStateList)
2947 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2951 uint32_t length = u_arraylist_length(g_deviceStateList);
2952 for (uint32_t index = 0; index < length; index++)
2954 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2957 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2961 if (!strcmp(state->address, remoteAddress))
2963 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2970 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2972 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2973 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2975 ca_mutex_lock(g_deviceStateListMutex);
2976 if (!g_deviceStateList)
2978 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2979 ca_mutex_unlock(g_deviceStateListMutex);
2983 uint32_t length = u_arraylist_length(g_deviceStateList);
2984 for (uint32_t index = 0; index < length; index++)
2986 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2989 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2993 if (!strcmp(state->address, remoteAddress))
2995 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2997 if (STATE_CONNECTED == state->connectedState)
2999 ca_mutex_unlock(g_deviceStateListMutex);
3004 ca_mutex_unlock(g_deviceStateListMutex);
3009 ca_mutex_unlock(g_deviceStateListMutex);
3013 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3015 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3016 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3018 ca_mutex_lock(g_deviceStateListMutex);
3019 if (!g_deviceStateList)
3021 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3022 ca_mutex_unlock(g_deviceStateListMutex);
3026 uint32_t length = u_arraylist_length(g_deviceStateList);
3027 for (uint32_t index = 0; index < length; index++)
3029 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3032 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3036 if (!strcmp(state->address, remoteAddress))
3038 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3040 if (STATE_CHARACTER_SET == state->notificationState)
3042 ca_mutex_unlock(g_deviceStateListMutex);
3047 ca_mutex_unlock(g_deviceStateListMutex);
3053 ca_mutex_unlock(g_deviceStateListMutex);
3057 void CALEClientCreateDeviceList()
3059 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3061 // create new object array
3062 if (!g_gattObjectList)
3064 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3066 g_gattObjectList = u_arraylist_create();
3069 if (!g_deviceStateList)
3071 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3073 g_deviceStateList = u_arraylist_create();
3078 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3080 g_deviceList = u_arraylist_create();
3085 * Check Sent Count for remove g_sendBuffer
3087 void CALEClientUpdateSendCnt(JNIEnv *env)
3089 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3091 ca_mutex_lock(g_threadMutex);
3095 if (g_targetCnt <= g_currentSentCnt)
3098 g_currentSentCnt = 0;
3102 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3103 g_sendBuffer = NULL;
3105 // notity the thread
3106 ca_cond_signal(g_threadCond);
3108 CALEClientSetSendFinishFlag(true);
3109 OIC_LOG(DEBUG, TAG, "set signal for send data");
3112 ca_mutex_unlock(g_threadMutex);
3115 CAResult_t CALEClientInitGattMutexVaraibles()
3117 if (NULL == g_bleReqRespClientCbMutex)
3119 g_bleReqRespClientCbMutex = ca_mutex_new();
3120 if (NULL == g_bleReqRespClientCbMutex)
3122 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3123 return CA_STATUS_FAILED;
3127 if (NULL == g_bleServerBDAddressMutex)
3129 g_bleServerBDAddressMutex = ca_mutex_new();
3130 if (NULL == g_bleServerBDAddressMutex)
3132 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3133 return CA_STATUS_FAILED;
3137 if (NULL == g_threadMutex)
3139 g_threadMutex = ca_mutex_new();
3140 if (NULL == g_threadMutex)
3142 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3143 return CA_STATUS_FAILED;
3147 if (NULL == g_threadSendMutex)
3149 g_threadSendMutex = ca_mutex_new();
3150 if (NULL == g_threadSendMutex)
3152 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3153 return CA_STATUS_FAILED;
3157 if (NULL == g_deviceListMutex)
3159 g_deviceListMutex = ca_mutex_new();
3160 if (NULL == g_deviceListMutex)
3162 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3163 return CA_STATUS_FAILED;
3167 if (NULL == g_gattObjectMutex)
3169 g_gattObjectMutex = ca_mutex_new();
3170 if (NULL == g_gattObjectMutex)
3172 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3173 return CA_STATUS_FAILED;
3177 if (NULL == g_deviceStateListMutex)
3179 g_deviceStateListMutex = ca_mutex_new();
3180 if (NULL == g_deviceStateListMutex)
3182 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3183 return CA_STATUS_FAILED;
3187 if (NULL == g_SendFinishMutex)
3189 g_SendFinishMutex = ca_mutex_new();
3190 if (NULL == g_SendFinishMutex)
3192 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3193 return CA_STATUS_FAILED;
3197 if (NULL == g_scanMutex)
3199 g_scanMutex = ca_mutex_new();
3200 if (NULL == g_scanMutex)
3202 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3203 return CA_STATUS_FAILED;
3207 if (NULL == g_threadWriteCharacteristicMutex)
3209 g_threadWriteCharacteristicMutex = ca_mutex_new();
3210 if (NULL == g_threadWriteCharacteristicMutex)
3212 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3213 return CA_STATUS_FAILED;
3217 return CA_STATUS_OK;
3220 void CALEClientTerminateGattMutexVariables()
3222 ca_mutex_free(g_bleReqRespClientCbMutex);
3223 g_bleReqRespClientCbMutex = NULL;
3225 ca_mutex_free(g_bleServerBDAddressMutex);
3226 g_bleServerBDAddressMutex = NULL;
3228 ca_mutex_free(g_threadMutex);
3229 g_threadMutex = NULL;
3231 ca_mutex_free(g_threadSendMutex);
3232 g_threadSendMutex = NULL;
3234 ca_mutex_free(g_deviceListMutex);
3235 g_deviceListMutex = NULL;
3237 ca_mutex_free(g_SendFinishMutex);
3238 g_SendFinishMutex = NULL;
3240 ca_mutex_free(g_scanMutex);
3243 ca_mutex_free(g_threadWriteCharacteristicMutex);
3244 g_threadWriteCharacteristicMutex = NULL;
3247 void CALEClientSetSendFinishFlag(bool flag)
3249 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3251 ca_mutex_lock(g_SendFinishMutex);
3252 g_isFinishedSendData = flag;
3253 ca_mutex_unlock(g_SendFinishMutex);
3260 CAResult_t CAStartLEGattClient()
3262 CAResult_t res = CALEClientStartMulticastServer();
3263 if (CA_STATUS_OK != res)
3265 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3269 g_isStartedLEClient = true;
3275 void CAStopLEGattClient()
3277 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3281 OIC_LOG(ERROR, TAG, "g_jvm is null");
3285 bool isAttached = false;
3287 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3290 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3291 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3295 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3301 CAResult_t ret = CALEClientDisconnectAll(env);
3302 if (CA_STATUS_OK != ret)
3304 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3307 ret = CALEClientStopScan();
3308 if(CA_STATUS_OK != ret)
3310 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3313 ca_mutex_lock(g_threadMutex);
3314 ca_cond_signal(g_threadCond);
3315 ca_mutex_unlock(g_threadMutex);
3317 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3318 ca_cond_signal(g_threadWriteCharacteristicCond);
3319 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3323 (*g_jvm)->DetachCurrentThread(g_jvm);
3328 CAResult_t CAInitializeLEGattClient()
3330 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3331 CALEClientInitialize();
3332 return CA_STATUS_OK;
3335 void CATerminateLEGattClient()
3337 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3338 CALEClientTerminate();
3341 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3342 uint32_t dataLen, CALETransferType_t type,
3345 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3346 VERIFY_NON_NULL(data, TAG, "data is null");
3347 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3349 if (LE_UNICAST != type || position < 0)
3351 OIC_LOG(ERROR, TAG, "this request is not unicast");
3352 return CA_STATUS_INVALID_PARAM;
3355 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3358 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3360 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3361 VERIFY_NON_NULL(data, TAG, "data is null");
3363 return CALEClientSendMulticastMessage(data, dataLen);
3366 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3368 ca_mutex_lock(g_bleReqRespClientCbMutex);
3369 g_CABLEClientDataReceivedCallback = callback;
3370 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3373 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3375 g_threadPoolHandle = handle;
3378 CAResult_t CAGetLEAddress(char **local_address)
3380 VERIFY_NON_NULL(local_address, TAG, "local_address");
3381 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3382 return CA_NOT_SUPPORTED;
3385 JNIEXPORT void JNICALL
3386 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3389 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3390 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3391 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3392 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3394 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3397 JNIEXPORT void JNICALL
3398 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3401 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3402 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3403 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3404 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3406 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3409 JNIEXPORT void JNICALL
3410 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3413 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3414 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3415 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3417 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3418 if (CA_STATUS_OK != res)
3420 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3425 * Class: org_iotivity_ca_jar_caleinterface
3426 * Method: CALeGattConnectionStateChangeCallback
3427 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3429 JNIEXPORT void JNICALL
3430 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3436 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %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 (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3444 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3450 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3453 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3454 STATE_CHARACTER_NO_CHANGE,
3456 if (CA_STATUS_OK != res)
3458 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3459 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3462 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3465 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3466 if (CA_STATUS_OK != res)
3468 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3472 res = CALEClientDiscoverServices(env, gatt);
3473 if (CA_STATUS_OK != res)
3475 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3479 else // le disconnected
3481 CAResult_t res = CALEClientStartScan();
3482 if (CA_STATUS_OK != res)
3484 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3488 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3491 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3495 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3498 res = CALEClientRemoveDeviceState(address);
3499 if (CA_STATUS_OK != res)
3501 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3505 res = CALEClientRemoveGattObjForAddr(env, jni_address);
3506 if (CA_STATUS_OK != res)
3508 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
3512 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3515 res = CALEClientGattClose(env, gatt);
3516 if (CA_STATUS_OK != res)
3518 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3523 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3524 g_sendBuffer = NULL;
3532 CALEClientSendFinish(env, gatt);
3537 * Class: org_iotivity_ca_jar_caleinterface
3538 * Method: CALeGattServicesDiscoveredCallback
3539 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3541 JNIEXPORT void JNICALL
3542 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3547 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3548 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3549 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3550 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3552 if (0 != status) // discovery error
3554 CALEClientSendFinish(env, gatt);
3558 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3561 CALEClientSendFinish(env, gatt);
3565 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3568 CALEClientSendFinish(env, gatt);
3572 if (!CALEClientIsSetCharacteristic(address))
3574 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3577 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3581 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3582 if (!jni_obj_GattCharacteristic)
3584 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3588 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3589 jni_obj_GattCharacteristic);
3590 if (CA_STATUS_OK != res)
3592 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3596 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3597 if (CA_STATUS_OK != res)
3599 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
3602 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3603 if (CA_STATUS_OK != res)
3605 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3611 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3613 if (CA_STATUS_OK != res)
3615 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3621 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3622 if (CA_STATUS_OK != res)
3624 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3628 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3633 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3634 CALEClientSendFinish(env, gatt);
3639 * Class: org_iotivity_ca_jar_caleinterface
3640 * Method: CALeGattCharacteristicWritjclasseCallback
3641 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3643 JNIEXPORT void JNICALL
3644 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3645 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3648 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3649 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3650 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3651 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3654 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3656 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3658 // send success & signal
3659 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3665 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3671 if (GATT_SUCCESS != status) // error case
3673 OIC_LOG(ERROR, TAG, "send failure");
3676 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3677 if (CA_STATUS_OK != res)
3679 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
3680 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3681 g_isSignalSetFlag = true;
3682 ca_cond_signal(g_threadWriteCharacteristicCond);
3683 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3685 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3686 STATE_CHARACTER_SET,
3688 if (CA_STATUS_OK != res)
3690 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3693 if (g_clientErrorCallback)
3695 jint length = (*env)->GetArrayLength(env, data);
3696 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
3699 CALEClientSendFinish(env, gatt);
3705 OIC_LOG(DEBUG, TAG, "send success");
3706 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3707 STATE_SEND_SUCCESS);
3708 if (CA_STATUS_OK != res)
3710 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3713 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3714 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
3715 g_isSignalSetFlag = true;
3716 ca_cond_signal(g_threadWriteCharacteristicCond);
3717 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3719 CALEClientUpdateSendCnt(env);
3722 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3728 CALEClientSendFinish(env, gatt);
3733 * Class: org_iotivity_ca_jar_caleinterface
3734 * Method: CALeGattCharacteristicChangedCallback
3735 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3737 JNIEXPORT void JNICALL
3738 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3739 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3741 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3742 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3743 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3744 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3745 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3747 // get Byte Array and convert to uint8_t*
3748 jint length = (*env)->GetArrayLength(env, data);
3751 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3753 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3754 jni_byte_responseData);
3756 uint8_t* receivedData = OICMalloc(length);
3759 OIC_LOG(ERROR, TAG, "receivedData is null");
3763 memcpy(receivedData, jni_byte_responseData, length);
3764 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3766 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3769 OIC_LOG(ERROR, TAG, "jni_address is null");
3770 OICFree(receivedData);
3774 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3777 OIC_LOG(ERROR, TAG, "address is null");
3778 OICFree(receivedData);
3782 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3783 receivedData, length);
3785 ca_mutex_lock(g_bleServerBDAddressMutex);
3786 uint32_t sentLength = 0;
3787 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3789 ca_mutex_unlock(g_bleServerBDAddressMutex);
3791 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3795 * Class: org_iotivity_ca_jar_caleinterface
3796 * Method: CALeGattDescriptorWriteCallback
3797 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3799 JNIEXPORT void JNICALL
3800 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3804 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3805 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3806 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3807 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3809 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3810 if (CA_STATUS_OK != res)
3812 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3820 CALEClientSendFinish(env, gatt);