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 #define GATT_CONNECTION_PRIORITY_BALANCED 0
46 #define GATT_FAILURE 257
47 #define GATT_INSUFFICIENT_AUTHENTICATION 5
48 #define GATT_INSUFFICIENT_ENCRYPTION 15
49 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
50 #define GATT_INVALID_OFFSET 7
51 #define GATT_READ_NOT_PERMITTED 2
52 #define GATT_REQUEST_NOT_SUPPORTED 6
53 #define GATT_WRITE_NOT_PERMITTED 3
55 static ca_thread_pool_t g_threadPoolHandle = NULL;
58 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
59 static u_arraylist_t *g_gattObjectList = NULL;
60 static u_arraylist_t *g_deviceStateList = NULL;
62 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
63 static CABLEErrorHandleCallback g_clientErrorCallback;
64 static jobject g_leScanCallback = NULL;
65 static jobject g_leGattCallback = NULL;
66 static jobject g_context = NULL;
67 static jobjectArray g_uuidList = NULL;
69 // it will be prevent to start send logic when adapter has stopped.
70 static bool g_isStartedLEClient = false;
71 static bool g_isStartedScan = false;
73 static jbyteArray g_sendBuffer = NULL;
74 static uint32_t g_targetCnt = 0;
75 static uint32_t g_currentSentCnt = 0;
76 static bool g_isFinishedSendData = false;
77 static ca_mutex g_SendFinishMutex = NULL;
78 static ca_mutex g_threadMutex = NULL;
79 static ca_cond g_threadCond = NULL;
80 static ca_cond g_deviceDescCond = NULL;
82 static ca_mutex g_threadSendMutex = NULL;
83 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
84 static ca_cond g_threadWriteCharacteristicCond = NULL;
85 static bool g_isSignalSetFlag = false;
87 static ca_mutex g_bleReqRespClientCbMutex = NULL;
88 static ca_mutex g_bleServerBDAddressMutex = NULL;
90 static ca_mutex g_deviceListMutex = NULL;
91 static ca_mutex g_gattObjectMutex = NULL;
92 static ca_mutex g_deviceStateListMutex = NULL;
94 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
95 static ca_cond g_deviceScanRetryDelayCond = NULL;
97 static ca_mutex g_scanMutex = NULL;
99 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
102 * check if retry logic for connection routine has to be stopped or not.
103 * in case of error value including this method, connection routine has to be stopped.
104 * since there is no retry logic for this error reason in this client.
105 * @param state constant value of bluetoothgatt.
106 * @return true - waiting for background connection in BT platform.
107 * false - connection routine has to be stopped.
109 static bool CALECheckConnectionStateValue(jint state)
113 case GATT_CONNECTION_PRIORITY_BALANCED:
115 case GATT_INSUFFICIENT_AUTHENTICATION:
116 case GATT_INSUFFICIENT_ENCRYPTION:
117 case GATT_INVALID_ATTRIBUTE_LENGTH:
118 case GATT_INVALID_OFFSET:
119 case GATT_READ_NOT_PERMITTED:
120 case GATT_REQUEST_NOT_SUPPORTED:
121 case GATT_WRITE_NOT_PERMITTED:
128 void CALEClientJniInit()
130 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
131 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
134 void CALEClientJNISetContext()
136 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
137 g_context = (jobject) CANativeJNIGetContext();
140 CAResult_t CALECreateJniInterfaceObject()
142 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
146 OIC_LOG(ERROR, TAG, "g_context is null");
147 return CA_STATUS_FAILED;
152 OIC_LOG(ERROR, TAG, "g_jvm is null");
153 return CA_STATUS_FAILED;
156 bool isAttached = false;
158 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
161 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
162 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
166 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
167 return CA_STATUS_FAILED;
172 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
173 if (!jni_LEInterface)
175 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
179 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
180 "(Landroid/content/Context;)V");
181 if (!LeInterfaceConstructorMethod)
183 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
187 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
188 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
192 (*g_jvm)->DetachCurrentThread(g_jvm);
201 (*g_jvm)->DetachCurrentThread(g_jvm);
204 return CA_STATUS_FAILED;
207 CAResult_t CALEClientInitialize()
209 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
215 OIC_LOG(ERROR, TAG, "g_jvm is null");
216 return CA_STATUS_FAILED;
219 bool isAttached = false;
221 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
224 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
225 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
229 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
230 return CA_STATUS_FAILED;
235 CAResult_t ret = CALECheckPlatformVersion(env, 18);
236 if (CA_STATUS_OK != ret)
238 OIC_LOG(ERROR, TAG, "it is not supported");
242 (*g_jvm)->DetachCurrentThread(g_jvm);
248 ret = CALEClientInitGattMutexVaraibles();
249 if (CA_STATUS_OK != ret)
251 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
252 CALEClientTerminateGattMutexVariables();
256 (*g_jvm)->DetachCurrentThread(g_jvm);
262 g_deviceDescCond = ca_cond_new();
264 // init mutex for send logic
265 g_threadCond = ca_cond_new();
266 g_threadWriteCharacteristicCond = ca_cond_new();
267 g_deviceScanRetryDelayCond = ca_cond_new();
269 CALEClientCreateDeviceList();
270 CALEClientJNISetContext();
272 ret = CALEClientCreateUUIDList();
273 if (CA_STATUS_OK != ret)
275 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
279 (*g_jvm)->DetachCurrentThread(g_jvm);
285 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
286 if (CA_STATUS_OK != ret)
288 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
292 (*g_jvm)->DetachCurrentThread(g_jvm);
297 g_isStartedLEClient = true;
301 (*g_jvm)->DetachCurrentThread(g_jvm);
307 void CALEClientTerminate()
309 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
313 OIC_LOG(ERROR, TAG, "g_jvm is null");
317 bool isAttached = false;
319 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
322 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
323 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
327 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
333 if (g_leScanCallback)
335 (*env)->DeleteGlobalRef(env, g_leScanCallback);
336 g_leScanCallback = NULL;
339 if (g_leGattCallback)
341 (*env)->DeleteGlobalRef(env, g_leGattCallback);
342 g_leGattCallback = NULL;
347 (*env)->DeleteGlobalRef(env, g_sendBuffer);
353 (*env)->DeleteGlobalRef(env, g_uuidList);
357 CAResult_t ret = CALEClientRemoveAllDeviceState();
358 if (CA_STATUS_OK != ret)
360 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
363 ret = CALEClientRemoveAllScanDevices(env);
364 if (CA_STATUS_OK != ret)
366 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
369 ret = CALEClientRemoveAllGattObjs(env);
370 if (CA_STATUS_OK != ret)
372 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
375 CALEClientSetScanFlag(false);
376 CALEClientSetSendFinishFlag(true);
378 CALEClientTerminateGattMutexVariables();
379 CALEClientDestroyJniInterface();
381 ca_cond_free(g_deviceDescCond);
382 ca_cond_free(g_threadCond);
383 ca_cond_free(g_threadWriteCharacteristicCond);
384 ca_cond_free(g_deviceScanRetryDelayCond);
386 g_deviceDescCond = NULL;
388 g_threadWriteCharacteristicCond = NULL;
389 g_deviceScanRetryDelayCond = NULL;
391 g_isSignalSetFlag = false;
395 (*g_jvm)->DetachCurrentThread(g_jvm);
399 CAResult_t CALEClientDestroyJniInterface()
401 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
405 OIC_LOG(ERROR, TAG, "g_jvm is null");
406 return CA_STATUS_FAILED;
409 bool isAttached = false;
411 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
414 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
415 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
419 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
420 return CA_STATUS_FAILED;
425 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
426 if (!jni_LeInterface)
428 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
432 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
433 "destroyLeInterface",
435 if (!jni_InterfaceDestroyMethod)
437 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
441 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
443 if ((*env)->ExceptionCheck(env))
445 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
446 (*env)->ExceptionDescribe(env);
447 (*env)->ExceptionClear(env);
451 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
455 (*g_jvm)->DetachCurrentThread(g_jvm);
464 (*g_jvm)->DetachCurrentThread(g_jvm);
467 return CA_STATUS_FAILED;
470 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
472 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
473 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
477 CAResult_t res = CALEClientDisconnect(env, gatt);
478 if (CA_STATUS_OK != res)
480 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
483 CALEClientUpdateSendCnt(env);
486 CAResult_t CALEClientSendUnicastMessage(const char* address,
488 const uint32_t dataLen)
490 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
491 VERIFY_NON_NULL(address, TAG, "address is null");
492 VERIFY_NON_NULL(data, TAG, "data is null");
494 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
497 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
498 const uint32_t dataLen)
500 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
501 VERIFY_NON_NULL(data, TAG, "data is null");
505 OIC_LOG(ERROR, TAG, "g_jvm is null");
506 return CA_STATUS_FAILED;
509 bool isAttached = false;
511 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
514 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
515 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
519 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
520 return CA_STATUS_FAILED;
525 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
526 if (CA_STATUS_OK != ret)
528 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
533 (*g_jvm)->DetachCurrentThread(g_jvm);
539 CAResult_t CALEClientStartUnicastServer(const char* address)
541 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
543 return CA_NOT_SUPPORTED;
546 CAResult_t CALEClientStartMulticastServer()
548 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
550 return CA_NOT_SUPPORTED;
553 void CALEClientStopUnicastServer()
555 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
558 void CALEClientStopMulticastServer()
560 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
563 void CALEClientSetCallback(CAPacketReceiveCallback callback)
565 g_packetReceiveCallback = callback;
568 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
570 g_clientErrorCallback = callback;
573 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
575 VERIFY_NON_NULL(env, TAG, "env");
579 return CA_STATUS_FAILED;
582 if (0 == u_arraylist_length(g_deviceList) // multicast
583 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
585 // Wait for LE peripherals to be discovered.
587 // Number of times to wait for discovery to complete.
588 static size_t const RETRIES = 5;
590 static uint64_t const TIMEOUT =
591 2 * MICROSECS_PER_SEC; // Microseconds
593 bool devicesDiscovered = false;
594 for (size_t i = 0; i < RETRIES; ++i)
596 OIC_LOG(DEBUG, TAG, "waiting for target device");
597 if (ca_cond_wait_for(g_deviceDescCond,
599 TIMEOUT) == CA_WAIT_SUCCESS)
601 ca_mutex_lock(g_deviceListMutex);
602 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
603 ca_mutex_unlock(g_deviceListMutex);
605 if (0 < scannedDeviceLen)
607 if (!address // multicast
608 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
610 devicesDiscovered = true;
617 OIC_LOG(INFO, TAG, "waiting..");
619 ca_mutex_lock(g_deviceScanRetryDelayMutex);
620 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
621 g_deviceScanRetryDelayMutex,
622 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
624 OIC_LOG(INFO, TAG, "finish to waiting for target device");
625 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
628 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
631 // checking whether a target device is found while waiting for time-out.
632 if (CALEClientIsDeviceInScanDeviceList(env, address))
634 devicesDiscovered = true;
643 // time out for scanning devices
644 if (!devicesDiscovered)
646 return CA_STATUS_FAILED;
654 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
655 const uint32_t dataLen)
657 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
659 VERIFY_NON_NULL(address, TAG, "address is null");
660 VERIFY_NON_NULL(data, TAG, "data is null");
664 OIC_LOG(ERROR, TAG, "g_jvm is null");
665 return CA_STATUS_FAILED;
668 bool isAttached = false;
670 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
673 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
674 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
677 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
678 return CA_STATUS_FAILED;
683 ca_mutex_lock(g_threadSendMutex);
685 CALEClientSetSendFinishFlag(false);
687 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
688 if (CA_STATUS_OK != ret)
690 OIC_LOG(INFO, TAG, "there is no scanned device");
694 if (g_context && g_deviceList)
696 uint32_t length = u_arraylist_length(g_deviceList);
697 for (uint32_t index = 0; index < length; index++)
699 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
702 OIC_LOG(ERROR, TAG, "jarrayObj is null");
706 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
709 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
713 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
716 OIC_LOG(ERROR, TAG, "setAddress is null");
720 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
722 if (!strcmp(setAddress, address))
724 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
726 // connect to gatt server
727 ret = CALEClientStopScan();
728 if (CA_STATUS_OK != ret)
730 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
736 (*env)->DeleteGlobalRef(env, g_sendBuffer);
739 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
740 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
741 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
743 // Target device to send message is just one.
746 ret = CALEClientSendData(env, jarrayObj);
747 if (CA_STATUS_OK != ret)
749 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
753 OIC_LOG(INFO, TAG, "wake up");
756 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
760 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
762 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
763 // if there is no connection state.
764 ca_mutex_lock(g_threadMutex);
765 if (!g_isFinishedSendData)
767 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
768 ca_cond_wait(g_threadCond, g_threadMutex);
769 OIC_LOG(DEBUG, TAG, "the data was sent");
771 ca_mutex_unlock(g_threadMutex);
775 (*g_jvm)->DetachCurrentThread(g_jvm);
778 // start LE Scan again
779 ret = CALEClientStartScan();
780 if (CA_STATUS_OK != ret)
782 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
783 ca_mutex_unlock(g_threadSendMutex);
787 ca_mutex_unlock(g_threadSendMutex);
788 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
789 return CALECheckSendState(address);
794 // start LE Scan again
795 ret = CALEClientStartScan();
796 if (CA_STATUS_OK != ret)
798 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
799 ca_mutex_unlock(g_threadSendMutex);
802 (*g_jvm)->DetachCurrentThread(g_jvm);
809 (*g_jvm)->DetachCurrentThread(g_jvm);
812 if (g_clientErrorCallback)
814 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
816 ca_mutex_unlock(g_threadSendMutex);
817 return CA_SEND_FAILED;
820 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
821 const uint32_t dataLen)
823 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
824 VERIFY_NON_NULL(data, TAG, "data is null");
825 VERIFY_NON_NULL(env, TAG, "env is null");
829 OIC_LOG(ERROR, TAG, "g_deviceList is null");
830 return CA_STATUS_FAILED;
833 ca_mutex_lock(g_threadSendMutex);
835 CALEClientSetSendFinishFlag(false);
837 OIC_LOG(DEBUG, TAG, "set byteArray for data");
840 (*env)->DeleteGlobalRef(env, g_sendBuffer);
844 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
845 if (CA_STATUS_OK != res)
847 OIC_LOG(INFO, TAG, "there is no scanned device");
851 // connect to gatt server
852 res = CALEClientStopScan();
853 if (CA_STATUS_OK != res)
855 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
856 ca_mutex_unlock(g_threadSendMutex);
859 uint32_t length = u_arraylist_length(g_deviceList);
860 g_targetCnt = length;
862 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
863 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
864 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
866 for (uint32_t index = 0; index < length; index++)
868 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
871 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
875 res = CALEClientSendData(env, jarrayObj);
876 if (res != CA_STATUS_OK)
878 OIC_LOG(ERROR, TAG, "BT device - send has failed");
881 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
884 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
888 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
891 OIC_LOG(ERROR, TAG, "address is not available");
895 (*env)->ReleaseStringUTFChars(env, jni_address, address);
898 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
900 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
901 ca_mutex_lock(g_threadMutex);
902 if (!g_isFinishedSendData)
904 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
905 ca_cond_wait(g_threadCond, g_threadMutex);
906 OIC_LOG(DEBUG, TAG, "the data was sent");
908 ca_mutex_unlock(g_threadMutex);
910 // start LE Scan again
911 res = CALEClientStartScan();
912 if (CA_STATUS_OK != res)
914 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
915 ca_mutex_unlock(g_threadSendMutex);
919 ca_mutex_unlock(g_threadSendMutex);
920 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
924 res = CALEClientStartScan();
925 if (CA_STATUS_OK != res)
927 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
928 ca_mutex_unlock(g_threadSendMutex);
932 ca_mutex_unlock(g_threadSendMutex);
933 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
934 return CA_SEND_FAILED;
937 CAResult_t CALECheckSendState(const char* address)
939 VERIFY_NON_NULL(address, TAG, "address is null");
941 ca_mutex_lock(g_deviceStateListMutex);
942 CALEState_t* state = CALEClientGetStateInfo(address);
945 OIC_LOG(ERROR, TAG, "state is null");
946 ca_mutex_unlock(g_deviceStateListMutex);
947 return CA_SEND_FAILED;
950 if (STATE_SEND_SUCCESS != state->sendState)
952 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
953 ca_mutex_unlock(g_deviceStateListMutex);
954 return CA_SEND_FAILED;
957 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
958 ca_mutex_unlock(g_deviceStateListMutex);
962 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
964 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
965 VERIFY_NON_NULL(device, TAG, "device is null");
966 VERIFY_NON_NULL(env, TAG, "env is null");
968 // get BLE address from bluetooth device object.
969 char* address = NULL;
970 CALEState_t* state = NULL;
971 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
974 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
975 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
978 OIC_LOG(ERROR, TAG, "address is not available");
979 return CA_STATUS_FAILED;
981 ca_mutex_lock(g_deviceStateListMutex);
982 state = CALEClientGetStateInfo(address);
983 ca_mutex_unlock(g_deviceStateListMutex);
984 (*env)->ReleaseStringUTFChars(env, jni_address, address);
989 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
991 // cancel previous connection request before connection
992 // if there is gatt object in g_gattObjectList.
995 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
998 OIC_LOG(ERROR, TAG, "address is not available");
999 return CA_STATUS_FAILED;
1002 jobject gatt = CALEClientGetGattObjInList(env, address);
1005 CAResult_t res = CALEClientDisconnect(env, gatt);
1006 if (CA_STATUS_OK != res)
1008 OIC_LOG(INFO, TAG, "there is no gatt object");
1011 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1014 // connection request
1015 jobject newGatt = CALEClientConnect(env, device,
1017 if (NULL == newGatt)
1019 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1020 return CA_STATUS_FAILED;
1025 if (STATE_CONNECTED == state->connectedState)
1027 OIC_LOG(INFO, TAG, "GATT has already connected");
1030 OIC_LOG(ERROR, TAG, "jni_address is not available");
1031 return CA_STATUS_FAILED;
1034 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1037 OIC_LOG(ERROR, TAG, "address is not available");
1038 return CA_STATUS_FAILED;
1041 jobject gatt = CALEClientGetGattObjInList(env, address);
1044 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1045 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1046 return CA_STATUS_FAILED;
1049 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1050 if (CA_STATUS_OK != ret)
1052 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1053 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1056 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1060 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1062 // cancel previous connection request before connection
1063 // if there is gatt object in g_gattObjectList.
1066 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1069 OIC_LOG(ERROR, TAG, "address is not available");
1070 return CA_STATUS_FAILED;
1073 jobject gatt = CALEClientGetGattObjInList(env, address);
1076 CAResult_t res = CALEClientDisconnect(env, gatt);
1077 if (CA_STATUS_OK != res)
1079 OIC_LOG(INFO, TAG, "there is no gatt object");
1082 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1085 OIC_LOG(DEBUG, TAG, "start to connect LE");
1086 jobject gatt = CALEClientConnect(env, device,
1087 CALEClientGetAutoConnectFlag(env, jni_address));
1090 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1091 return CA_STATUS_FAILED;
1096 return CA_STATUS_OK;
1099 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1101 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1102 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1104 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1105 "()Landroid/bluetooth/BluetoothDevice;");
1106 if (!jni_mid_getDevice)
1108 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1112 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1113 if (!jni_obj_device)
1115 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1119 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1122 OIC_LOG(ERROR, TAG, "jni_address is null");
1132 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1135 OIC_LOG(DEBUG, TAG, "Gatt Close");
1136 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1137 VERIFY_NON_NULL(env, TAG, "env is null");
1139 // get BluetoothGatt method
1140 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1141 jmethodID jni_mid_closeGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1142 if (!jni_mid_closeGatt)
1144 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1145 return CA_STATUS_OK;
1148 // call disconnect gatt method
1149 OIC_LOG(DEBUG, TAG, "request to close GATT");
1150 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1152 if ((*env)->ExceptionCheck(env))
1154 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1155 (*env)->ExceptionDescribe(env);
1156 (*env)->ExceptionClear(env);
1157 return CA_STATUS_FAILED;
1160 return CA_STATUS_OK;
1163 CAResult_t CALEClientStartScan()
1165 if (!g_isStartedLEClient)
1167 OIC_LOG(ERROR, TAG, "LE client is not started");
1168 return CA_STATUS_FAILED;
1173 OIC_LOG(ERROR, TAG, "g_jvm is null");
1174 return CA_STATUS_FAILED;
1177 if (g_isStartedScan)
1179 OIC_LOG(INFO, TAG, "scanning is already started");
1180 return CA_STATUS_OK;
1183 bool isAttached = false;
1185 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1188 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1190 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1193 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1194 return CA_STATUS_FAILED;
1199 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1201 CAResult_t ret = CA_STATUS_OK;
1202 // scan gatt server with UUID
1203 if (g_leScanCallback && g_uuidList)
1206 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1208 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1210 if (CA_STATUS_OK != ret)
1212 if (CA_ADAPTER_NOT_ENABLED == ret)
1214 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1218 OIC_LOG(ERROR, TAG, "start scan has failed");
1225 (*g_jvm)->DetachCurrentThread(g_jvm);
1231 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1233 VERIFY_NON_NULL(callback, TAG, "callback is null");
1234 VERIFY_NON_NULL(env, TAG, "env is null");
1236 if (!CALEIsEnableBTAdapter(env))
1238 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1239 return CA_ADAPTER_NOT_ENABLED;
1242 // get default bt adapter class
1243 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1244 if (!jni_cid_BTAdapter)
1246 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1247 return CA_STATUS_FAILED;
1250 // get remote bt adapter method
1251 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1252 "getDefaultAdapter",
1253 METHODID_OBJECTNONPARAM);
1254 if (!jni_mid_getDefaultAdapter)
1256 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1257 return CA_STATUS_FAILED;
1260 // get start le scan method
1261 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1262 "(Landroid/bluetooth/BluetoothAdapter$"
1263 "LeScanCallback;)Z");
1264 if (!jni_mid_startLeScan)
1266 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1267 return CA_STATUS_FAILED;
1270 // gat bt adapter object
1271 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1272 jni_mid_getDefaultAdapter);
1273 if (!jni_obj_BTAdapter)
1275 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1276 return CA_STATUS_FAILED;
1279 // call start le scan method
1280 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1281 jni_mid_startLeScan, callback);
1282 if (!jni_obj_startLeScan)
1284 OIC_LOG(INFO, TAG, "startLeScan is failed");
1288 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1289 CALEClientSetScanFlag(true);
1292 return CA_STATUS_OK;
1295 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1297 VERIFY_NON_NULL(callback, TAG, "callback is null");
1298 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1299 VERIFY_NON_NULL(env, TAG, "env is null");
1301 if (!CALEIsEnableBTAdapter(env))
1303 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1304 return CA_ADAPTER_NOT_ENABLED;
1307 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1308 if (!jni_cid_BTAdapter)
1310 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1311 return CA_STATUS_FAILED;
1314 // get remote bt adapter method
1315 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1316 "getDefaultAdapter",
1317 METHODID_OBJECTNONPARAM);
1318 if (!jni_mid_getDefaultAdapter)
1320 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1321 return CA_STATUS_FAILED;
1324 // get start le scan method
1325 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1326 "([Ljava/util/UUID;Landroid/bluetooth/"
1327 "BluetoothAdapter$LeScanCallback;)Z");
1328 if (!jni_mid_startLeScan)
1330 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1331 return CA_STATUS_FAILED;
1334 // get bt adapter object
1335 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1336 jni_mid_getDefaultAdapter);
1337 if (!jni_obj_BTAdapter)
1339 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1340 return CA_STATUS_FAILED;
1343 // call start le scan method
1344 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1345 jni_mid_startLeScan, uuids, callback);
1346 if (!jni_obj_startLeScan)
1348 OIC_LOG(INFO, TAG, "startLeScan With UUID is failed");
1352 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1353 CALEClientSetScanFlag(true);
1356 return CA_STATUS_OK;
1359 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1361 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1362 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1365 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1368 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1372 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1373 "(Ljava/lang/String;)"
1374 "Ljava/util/UUID;");
1375 if (!jni_mid_fromString)
1377 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1381 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1382 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1386 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1390 return jni_obj_uuid;
1393 CAResult_t CALEClientStopScan()
1397 OIC_LOG(ERROR, TAG, "g_jvm is null");
1398 return CA_STATUS_FAILED;
1401 if (!g_isStartedScan)
1403 OIC_LOG(INFO, TAG, "scanning is already stopped");
1404 return CA_STATUS_OK;
1407 bool isAttached = false;
1409 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1412 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1413 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1416 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1417 return CA_STATUS_FAILED;
1422 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1423 if (CA_STATUS_OK != ret)
1425 if (CA_ADAPTER_NOT_ENABLED == ret)
1427 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1431 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1436 CALEClientSetScanFlag(false);
1441 (*g_jvm)->DetachCurrentThread(g_jvm);
1447 void CALEClientSetScanFlag(bool flag)
1449 ca_mutex_lock(g_scanMutex);
1450 g_isStartedScan = flag;
1451 ca_mutex_unlock(g_scanMutex);
1454 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1456 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1457 VERIFY_NON_NULL(callback, TAG, "callback is null");
1458 VERIFY_NON_NULL(env, TAG, "env is null");
1460 if (!CALEIsEnableBTAdapter(env))
1462 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1463 return CA_ADAPTER_NOT_ENABLED;
1466 // get default bt adapter class
1467 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1468 if (!jni_cid_BTAdapter)
1470 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1471 return CA_STATUS_FAILED;
1474 // get remote bt adapter method
1475 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1476 "getDefaultAdapter",
1477 METHODID_OBJECTNONPARAM);
1478 if (!jni_mid_getDefaultAdapter)
1480 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1481 return CA_STATUS_FAILED;
1484 // get start le scan method
1485 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1486 "(Landroid/bluetooth/"
1487 "BluetoothAdapter$LeScanCallback;)V");
1488 if (!jni_mid_stopLeScan)
1490 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1491 return CA_STATUS_FAILED;
1494 // gat bt adapter object
1495 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1496 jni_mid_getDefaultAdapter);
1497 if (!jni_obj_BTAdapter)
1499 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1500 return CA_STATUS_FAILED;
1503 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1504 // call start le scan method
1505 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1506 if ((*env)->ExceptionCheck(env))
1508 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1509 (*env)->ExceptionDescribe(env);
1510 (*env)->ExceptionClear(env);
1511 return CA_STATUS_FAILED;
1514 return CA_STATUS_OK;
1517 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1519 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1520 VERIFY_NON_NULL(env, TAG, "env");
1521 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1523 ca_mutex_lock(g_deviceStateListMutex);
1525 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1528 OIC_LOG(ERROR, TAG, "address is not available");
1529 return CA_STATUS_FAILED;
1532 if (CALEClientIsDeviceInList(address))
1534 CALEState_t* curState = CALEClientGetStateInfo(address);
1537 OIC_LOG(ERROR, TAG, "curState is null");
1538 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1539 ca_mutex_unlock(g_deviceStateListMutex);
1540 return CA_STATUS_FAILED;
1542 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1544 curState->autoConnectFlag = flag;
1547 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1548 ca_mutex_unlock(g_deviceStateListMutex);
1549 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1550 return CA_STATUS_OK;
1553 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1555 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1556 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1557 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1559 ca_mutex_lock(g_deviceStateListMutex);
1561 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1564 OIC_LOG(ERROR, TAG, "address is not available");
1568 CALEState_t* curState = CALEClientGetStateInfo(address);
1571 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1572 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1573 ca_mutex_unlock(g_deviceStateListMutex);
1576 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1578 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1579 ca_mutex_unlock(g_deviceStateListMutex);
1581 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1582 return curState->autoConnectFlag;
1585 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1587 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1588 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1589 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1591 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1592 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1595 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1598 OIC_LOG(ERROR, TAG, "address is not available");
1602 // close the gatt service
1603 jobject gatt = CALEClientGetGattObjInList(env, address);
1606 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1607 if (CA_STATUS_OK != res)
1609 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1610 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1614 // clean previous gatt object after close profile service
1615 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1616 if (CA_STATUS_OK != res)
1618 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1619 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1623 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1626 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1629 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1633 // add new gatt object into g_gattObjectList
1634 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1635 if (CA_STATUS_OK != res)
1637 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1644 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1646 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1647 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1648 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1650 if (!g_leGattCallback)
1652 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1656 if (!CALEIsEnableBTAdapter(env))
1658 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1662 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1665 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1669 // get BluetoothDevice method
1670 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1671 jmethodID jni_mid_connectGatt = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1673 "(Landroid/content/Context;ZLandroid/"
1674 "bluetooth/BluetoothGattCallback;)"
1675 "Landroid/bluetooth/BluetoothGatt;");
1676 if (!jni_mid_connectGatt)
1678 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1682 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1683 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1684 jni_mid_connectGatt,
1686 autoconnect, g_leGattCallback);
1687 if (!jni_obj_connectGatt)
1689 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1690 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1691 CALEClientUpdateSendCnt(env);
1696 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1698 return jni_obj_connectGatt;
1701 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1703 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1705 VERIFY_NON_NULL(env, TAG, "env is null");
1706 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1708 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1709 if (!jni_cid_BTAdapter)
1711 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1712 return CA_STATUS_FAILED;
1715 // get remote bt adapter method
1716 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1717 "getDefaultAdapter",
1718 METHODID_OBJECTNONPARAM);
1719 if (!jni_mid_getDefaultAdapter)
1721 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1722 return CA_STATUS_FAILED;
1725 // gat bt adapter object
1726 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1727 jni_mid_getDefaultAdapter);
1728 if (!jni_obj_BTAdapter)
1730 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1731 return CA_STATUS_FAILED;
1734 // get closeProfileProxy method
1735 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1736 "closeProfileProxy",
1737 "(ILandroid/bluetooth/"
1738 "BluetoothProfile;)V");
1739 if (!jni_mid_closeProfileProxy)
1741 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1742 return CA_STATUS_FAILED;
1745 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1746 if (!jni_cid_BTProfile)
1748 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1749 return CA_STATUS_FAILED;
1752 // GATT - Constant value : 7 (0x00000007)
1753 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1757 OIC_LOG(ERROR, TAG, "id_gatt is null");
1758 return CA_STATUS_FAILED;
1761 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1763 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1764 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1765 if ((*env)->ExceptionCheck(env))
1767 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1768 (*env)->ExceptionDescribe(env);
1769 (*env)->ExceptionClear(env);
1770 return CA_STATUS_FAILED;
1773 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1774 return CA_STATUS_OK;
1778 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1780 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1781 VERIFY_NON_NULL(env, TAG, "env is null");
1782 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1784 // get BluetoothGatt method
1785 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1786 jmethodID jni_mid_disconnectGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
1787 "disconnect", "()V");
1788 if (!jni_mid_disconnectGatt)
1790 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1791 return CA_STATUS_FAILED;
1794 // call disconnect gatt method
1795 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1796 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1797 if ((*env)->ExceptionCheck(env))
1799 OIC_LOG(ERROR, TAG, "disconnect has failed");
1800 (*env)->ExceptionDescribe(env);
1801 (*env)->ExceptionClear(env);
1802 return CA_STATUS_FAILED;
1805 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1807 return CA_STATUS_OK;
1810 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1812 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1813 VERIFY_NON_NULL(env, TAG, "env is null");
1815 if (!g_gattObjectList)
1817 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1818 return CA_STATUS_OK;
1821 uint32_t length = u_arraylist_length(g_gattObjectList);
1822 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1823 for (uint32_t index = 0; index < length; index++)
1825 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1826 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1829 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1832 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1833 if (CA_STATUS_OK != res)
1835 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1840 return CA_STATUS_OK;
1843 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1845 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1846 VERIFY_NON_NULL(env, TAG, "env is null");
1848 if (!g_gattObjectList)
1850 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1851 return CA_STATUS_OK;
1854 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1857 OIC_LOG(ERROR, TAG, "address is null");
1858 return CA_STATUS_FAILED;
1861 uint32_t length = u_arraylist_length(g_gattObjectList);
1862 for (uint32_t index = 0; index < length; index++)
1864 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1867 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1871 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1872 if (!jni_setAddress)
1874 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1875 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1876 return CA_STATUS_FAILED;
1879 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1882 OIC_LOG(ERROR, TAG, "setAddress is null");
1883 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1884 return CA_STATUS_FAILED;
1887 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1888 if (!strcmp(address, setAddress))
1890 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1891 if (CA_STATUS_OK != res)
1893 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1894 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1895 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1896 return CA_STATUS_FAILED;
1898 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1899 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1900 return CA_STATUS_OK;
1902 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1904 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1906 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1907 return CA_STATUS_OK;
1910 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1912 VERIFY_NON_NULL(env, TAG, "env is null");
1913 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1915 if (!CALEIsEnableBTAdapter(env))
1917 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1918 return CA_ADAPTER_NOT_ENABLED;
1921 // get BluetoothGatt.discoverServices method
1922 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1923 jmethodID jni_mid_discoverServices = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
1924 "discoverServices", "()Z");
1925 if (!jni_mid_discoverServices)
1927 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1928 return CA_STATUS_FAILED;
1931 // call disconnect gatt method
1932 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1933 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1936 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1937 return CA_STATUS_FAILED;
1940 return CA_STATUS_OK;
1943 static void CALEWriteCharacteristicThread(void* object)
1945 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1947 bool isAttached = false;
1949 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1952 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1953 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1957 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1963 jobject gatt = (jobject)object;
1964 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1965 if (CA_STATUS_OK != ret)
1967 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1972 (*g_jvm)->DetachCurrentThread(g_jvm);
1976 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1978 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1979 VERIFY_NON_NULL(env, TAG, "env is null");
1982 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1983 if (!jni_obj_character)
1985 CALEClientSendFinish(env, gatt);
1986 return CA_STATUS_FAILED;
1989 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1990 if (CA_STATUS_OK != ret)
1992 CALEClientSendFinish(env, gatt);
1993 return CA_STATUS_FAILED;
1996 // wait for callback for write Characteristic with success to sent data
1997 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1998 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1999 if (!g_isSignalSetFlag)
2001 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2002 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2003 g_threadWriteCharacteristicMutex,
2004 WAIT_TIME_WRITE_CHARACTERISTIC))
2006 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2007 g_isSignalSetFlag = false;
2008 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2009 return CA_STATUS_FAILED;
2012 // reset flag set by writeCharacteristic Callback
2013 g_isSignalSetFlag = false;
2014 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2016 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2017 return CA_STATUS_OK;
2020 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2022 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2023 VERIFY_NON_NULL(env, TAG, "env is null");
2024 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2026 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2027 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2028 CALEWriteCharacteristicThread, (void*)gattParam))
2030 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2031 return CA_STATUS_FAILED;
2034 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2035 return CA_STATUS_OK;
2038 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2039 jobject gattCharacteristic)
2041 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2042 VERIFY_NON_NULL(env, TAG, "env is null");
2043 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2044 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2046 if (!CALEIsEnableBTAdapter(env))
2048 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2049 return CA_STATUS_FAILED;
2052 // get BluetoothGatt.write characteristic method
2053 OIC_LOG(DEBUG, TAG, "write characteristic method");
2054 jmethodID jni_mid_writeCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2055 "writeCharacteristic",
2056 "(Landroid/bluetooth/"
2057 "BluetoothGattCharacteristic;)Z");
2058 if (!jni_mid_writeCharacteristic)
2060 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2061 return CA_STATUS_FAILED;
2064 // call disconnect gatt method
2065 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2066 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2067 jni_mid_writeCharacteristic,
2068 gattCharacteristic);
2071 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2075 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2076 return CA_STATUS_FAILED;
2079 return CA_STATUS_OK;
2082 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2084 VERIFY_NON_NULL(env, TAG, "env is null");
2085 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2087 if (!CALEIsEnableBTAdapter(env))
2089 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2090 return CA_STATUS_FAILED;
2093 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2096 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2097 return CA_STATUS_FAILED;
2100 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2101 if (!jni_obj_GattCharacteristic)
2103 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2104 return CA_STATUS_FAILED;
2107 OIC_LOG(DEBUG, TAG, "read characteristic method");
2108 jmethodID jni_mid_readCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2109 "readCharacteristic",
2110 "(Landroid/bluetooth/"
2111 "BluetoothGattCharacteristic;)Z");
2112 if (!jni_mid_readCharacteristic)
2114 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2115 return CA_STATUS_FAILED;
2118 // call disconnect gatt method
2119 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2120 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2121 jni_obj_GattCharacteristic);
2124 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2128 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2129 return CA_STATUS_FAILED;
2132 return CA_STATUS_OK;
2135 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2136 jobject characteristic)
2138 VERIFY_NON_NULL(env, TAG, "env is null");
2139 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2140 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2142 if (!CALEIsEnableBTAdapter(env))
2144 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2145 return CA_ADAPTER_NOT_ENABLED;
2148 // get BluetoothGatt.setCharacteristicNotification method
2149 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2150 jmethodID jni_mid_setNotification = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2151 "setCharacteristicNotification",
2152 "(Landroid/bluetooth/"
2153 "BluetoothGattCharacteristic;Z)Z");
2154 if (!jni_mid_setNotification)
2156 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2157 return CA_STATUS_FAILED;
2160 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2161 characteristic, JNI_TRUE);
2162 if (JNI_TRUE == ret)
2164 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2168 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2169 return CA_STATUS_FAILED;
2172 return CA_STATUS_OK;
2175 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2177 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2178 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2179 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2181 if (!CALEIsEnableBTAdapter(env))
2183 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2187 // get BluetoothGatt.getService method
2188 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2189 jmethodID jni_mid_getService = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2191 "(Ljava/util/UUID;)Landroid/bluetooth/"
2192 "BluetoothGattService;");
2193 if (!jni_mid_getService)
2195 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2199 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2200 if (!jni_obj_service_uuid)
2202 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2206 // get bluetooth gatt service
2207 OIC_LOG(DEBUG, TAG, "request to get service");
2208 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2209 jni_obj_service_uuid);
2210 if (!jni_obj_gattService)
2212 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2216 // get bluetooth gatt service method
2217 jmethodID jni_mid_getCharacteristic = CALEGetJNIMethodID(env, "android/bluetooth/"
2218 "BluetoothGattService",
2219 "getCharacteristic",
2220 "(Ljava/util/UUID;)"
2221 "Landroid/bluetooth/"
2222 "BluetoothGattCharacteristic;");
2223 if (!jni_mid_getCharacteristic)
2225 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2229 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2232 OIC_LOG(ERROR, TAG, "uuid is null");
2236 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2237 if (!jni_obj_tx_uuid)
2239 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2240 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2244 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2245 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2246 jni_mid_getCharacteristic,
2249 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2250 return jni_obj_GattCharacteristic;
2253 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2255 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2256 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2257 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2258 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2260 if (!CALEIsEnableBTAdapter(env))
2262 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2266 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2269 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2273 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2274 if (!jni_obj_GattCharacteristic)
2276 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2280 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2281 "/BluetoothGattCharacteristic");
2282 if (!jni_cid_BTGattCharacteristic)
2284 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2288 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2289 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2291 if (!jni_mid_setValue)
2293 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2297 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2299 if (JNI_TRUE == ret)
2301 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2305 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2310 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2311 "setWriteType", "(I)V");
2312 if (!jni_mid_setWriteType)
2314 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2318 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2319 "WRITE_TYPE_NO_RESPONSE", "I");
2320 if (!jni_fid_no_response)
2322 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2326 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2327 jni_fid_no_response);
2329 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2331 return jni_obj_GattCharacteristic;
2334 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2336 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2337 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2339 if (!CALEIsEnableBTAdapter(env))
2341 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2345 jmethodID jni_mid_getValue = CALEGetJNIMethodID(env, "android/bluetooth/"
2346 "BluetoothGattCharacteristic",
2347 "getValue", "()[B");
2348 if (!jni_mid_getValue)
2350 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2354 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2356 return jni_obj_data_array;
2359 CAResult_t CALEClientCreateUUIDList()
2363 OIC_LOG(ERROR, TAG, "g_jvm is null");
2364 return CA_STATUS_FAILED;
2367 bool isAttached = false;
2369 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2372 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2373 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2377 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2378 return CA_STATUS_FAILED;
2383 // create new object array
2384 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2385 if (!jni_cid_uuid_list)
2387 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2391 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2392 jni_cid_uuid_list, NULL);
2393 if (!jni_obj_uuid_list)
2395 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2400 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2403 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2406 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2408 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2412 (*g_jvm)->DetachCurrentThread(g_jvm);
2415 return CA_STATUS_OK;
2422 (*g_jvm)->DetachCurrentThread(g_jvm);
2424 return CA_STATUS_FAILED;
2427 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2428 jobject characteristic)
2430 VERIFY_NON_NULL(env, TAG, "env is null");
2431 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2432 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2434 if (!CALEIsEnableBTAdapter(env))
2436 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2437 return CA_ADAPTER_NOT_ENABLED;
2440 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2441 jmethodID jni_mid_getDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/"
2442 "BluetoothGattCharacteristic",
2444 "(Ljava/util/UUID;)Landroid/bluetooth/"
2445 "BluetoothGattDescriptor;");
2446 if (!jni_mid_getDescriptor)
2448 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2449 return CA_STATUS_FAILED;
2452 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2453 if (!jni_obj_cc_uuid)
2455 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2456 return CA_STATUS_FAILED;
2459 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2460 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2461 jni_mid_getDescriptor, jni_obj_cc_uuid);
2462 if (!jni_obj_descriptor)
2464 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2465 return CA_NOT_SUPPORTED;
2468 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2469 jclass jni_cid_descriptor = (*env)->FindClass(env,
2470 "android/bluetooth/BluetoothGattDescriptor");
2471 if (!jni_cid_descriptor)
2473 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2474 return CA_STATUS_FAILED;
2477 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2478 if (!jni_mid_setValue)
2480 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2481 return CA_STATUS_FAILED;
2484 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2485 "ENABLE_NOTIFICATION_VALUE", "[B");
2486 if (!jni_fid_NotiValue)
2488 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2489 return CA_STATUS_FAILED;
2492 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2494 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2495 env, jni_obj_descriptor, jni_mid_setValue,
2496 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2499 OIC_LOG(DEBUG, TAG, "setValue success");
2503 OIC_LOG(ERROR, TAG, "setValue has failed");
2504 return CA_STATUS_FAILED;
2507 jmethodID jni_mid_writeDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2509 "(Landroid/bluetooth/"
2510 "BluetoothGattDescriptor;)Z");
2511 if (!jni_mid_writeDescriptor)
2513 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2514 return CA_STATUS_FAILED;
2517 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2518 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2519 jni_obj_descriptor);
2522 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2526 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2527 return CA_STATUS_FAILED;
2530 return CA_STATUS_OK;
2533 void CALEClientCreateScanDeviceList(JNIEnv *env)
2535 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2536 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2538 ca_mutex_lock(g_deviceListMutex);
2539 // create new object array
2540 if (g_deviceList == NULL)
2542 OIC_LOG(DEBUG, TAG, "Create device list");
2544 g_deviceList = u_arraylist_create();
2546 ca_mutex_unlock(g_deviceListMutex);
2549 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2551 VERIFY_NON_NULL(device, TAG, "device is null");
2552 VERIFY_NON_NULL(env, TAG, "env is null");
2554 ca_mutex_lock(g_deviceListMutex);
2558 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2560 CALEClientSetScanFlag(false);
2561 if(CA_STATUS_OK != CALEClientStopScan())
2563 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2566 ca_mutex_unlock(g_deviceListMutex);
2567 return CA_STATUS_FAILED;
2570 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2571 if (!jni_remoteAddress)
2573 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2574 ca_mutex_unlock(g_deviceListMutex);
2575 return CA_STATUS_FAILED;
2578 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2581 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2582 ca_mutex_unlock(g_deviceListMutex);
2583 return CA_STATUS_FAILED;
2586 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2588 jobject gdevice = (*env)->NewGlobalRef(env, device);
2589 u_arraylist_add(g_deviceList, gdevice);
2590 ca_cond_signal(g_deviceDescCond);
2591 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2593 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2595 ca_mutex_unlock(g_deviceListMutex);
2597 return CA_STATUS_OK;
2600 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2602 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2603 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2607 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2611 uint32_t length = u_arraylist_length(g_deviceList);
2612 for (uint32_t index = 0; index < length; index++)
2614 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2617 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2621 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2622 if (!jni_setAddress)
2624 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2628 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2631 OIC_LOG(ERROR, TAG, "setAddress is null");
2635 if (!strcmp(remoteAddress, setAddress))
2637 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2641 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2644 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2649 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2651 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2652 VERIFY_NON_NULL(env, TAG, "env is null");
2654 ca_mutex_lock(g_deviceListMutex);
2658 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2659 ca_mutex_unlock(g_deviceListMutex);
2660 return CA_STATUS_FAILED;
2663 uint32_t length = u_arraylist_length(g_deviceList);
2664 for (uint32_t index = 0; index < length; index++)
2666 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2669 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2672 (*env)->DeleteGlobalRef(env, jarrayObj);
2676 OICFree(g_deviceList);
2677 g_deviceList = NULL;
2679 ca_mutex_unlock(g_deviceListMutex);
2680 return CA_STATUS_OK;
2683 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2685 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2686 VERIFY_NON_NULL(address, TAG, "address is null");
2687 VERIFY_NON_NULL(env, TAG, "env is null");
2689 ca_mutex_lock(g_deviceListMutex);
2693 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2694 ca_mutex_unlock(g_deviceListMutex);
2695 return CA_STATUS_FAILED;
2698 uint32_t length = u_arraylist_length(g_deviceList);
2699 for (uint32_t index = 0; index < length; index++)
2701 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2704 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2705 ca_mutex_unlock(g_deviceListMutex);
2706 return CA_STATUS_FAILED;
2709 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2710 if (!jni_setAddress)
2712 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2713 ca_mutex_unlock(g_deviceListMutex);
2714 return CA_STATUS_FAILED;
2717 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2720 OIC_LOG(ERROR, TAG, "setAddress is null");
2721 ca_mutex_unlock(g_deviceListMutex);
2722 return CA_STATUS_FAILED;
2725 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2728 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2729 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2730 ca_mutex_unlock(g_deviceListMutex);
2731 return CA_STATUS_FAILED;
2734 if (!strcmp(setAddress, remoteAddress))
2736 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2737 (*env)->DeleteGlobalRef(env, jarrayObj);
2739 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2740 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2742 if (NULL == u_arraylist_remove(g_deviceList, index))
2744 OIC_LOG(ERROR, TAG, "List removal failed.");
2745 ca_mutex_unlock(g_deviceListMutex);
2746 return CA_STATUS_FAILED;
2748 ca_mutex_unlock(g_deviceListMutex);
2749 return CA_STATUS_OK;
2751 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2752 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2755 ca_mutex_unlock(g_deviceListMutex);
2756 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2758 return CA_STATUS_OK;
2765 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2767 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2768 VERIFY_NON_NULL(env, TAG, "env is null");
2769 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2771 ca_mutex_lock(g_gattObjectMutex);
2773 if (!g_gattObjectList)
2775 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2776 ca_mutex_unlock(g_gattObjectMutex);
2777 return CA_STATUS_FAILED;
2780 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2781 if (!jni_remoteAddress)
2783 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2784 ca_mutex_unlock(g_gattObjectMutex);
2785 return CA_STATUS_FAILED;
2788 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2791 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2792 ca_mutex_unlock(g_gattObjectMutex);
2793 return CA_STATUS_FAILED;
2796 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2797 if (!CALEClientIsGattObjInList(env, remoteAddress))
2799 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2800 u_arraylist_add(g_gattObjectList, newGatt);
2801 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2804 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2805 ca_mutex_unlock(g_gattObjectMutex);
2806 return CA_STATUS_OK;
2809 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2811 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2812 VERIFY_NON_NULL(env, TAG, "env is null");
2813 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2815 uint32_t length = u_arraylist_length(g_gattObjectList);
2816 for (uint32_t index = 0; index < length; index++)
2819 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2822 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2826 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2827 if (!jni_setAddress)
2829 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2833 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2836 OIC_LOG(ERROR, TAG, "setAddress is null");
2840 if (!strcmp(remoteAddress, setAddress))
2842 OIC_LOG(DEBUG, TAG, "the device is already set");
2843 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2848 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2853 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2857 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2859 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2860 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2861 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2863 ca_mutex_lock(g_gattObjectMutex);
2864 uint32_t length = u_arraylist_length(g_gattObjectList);
2865 for (uint32_t index = 0; index < length; index++)
2867 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2870 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2871 ca_mutex_unlock(g_gattObjectMutex);
2875 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2876 if (!jni_setAddress)
2878 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2879 ca_mutex_unlock(g_gattObjectMutex);
2883 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2886 OIC_LOG(ERROR, TAG, "setAddress is null");
2887 ca_mutex_unlock(g_gattObjectMutex);
2891 if (!strcmp(remoteAddress, setAddress))
2893 OIC_LOG(DEBUG, TAG, "the device is already set");
2894 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2895 ca_mutex_unlock(g_gattObjectMutex);
2898 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2901 ca_mutex_unlock(g_gattObjectMutex);
2902 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2906 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2908 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2909 VERIFY_NON_NULL(env, TAG, "env is null");
2911 ca_mutex_lock(g_gattObjectMutex);
2912 if (!g_gattObjectList)
2914 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2915 ca_mutex_unlock(g_gattObjectMutex);
2916 return CA_STATUS_OK;
2919 uint32_t length = u_arraylist_length(g_gattObjectList);
2920 for (uint32_t index = 0; index < length; index++)
2922 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2925 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2928 (*env)->DeleteGlobalRef(env, jarrayObj);
2932 OICFree(g_gattObjectList);
2933 g_gattObjectList = NULL;
2934 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2935 ca_mutex_unlock(g_gattObjectMutex);
2936 return CA_STATUS_OK;
2939 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2941 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2942 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2943 VERIFY_NON_NULL(env, TAG, "env is null");
2945 ca_mutex_lock(g_gattObjectMutex);
2946 if (!g_gattObjectList)
2948 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2949 ca_mutex_unlock(g_gattObjectMutex);
2950 return CA_STATUS_OK;
2953 uint32_t length = u_arraylist_length(g_gattObjectList);
2954 for (uint32_t index = 0; index < length; index++)
2956 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2959 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2960 ca_mutex_unlock(g_gattObjectMutex);
2961 return CA_STATUS_FAILED;
2964 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2965 if (!jni_setAddress)
2967 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2968 ca_mutex_unlock(g_gattObjectMutex);
2969 return CA_STATUS_FAILED;
2972 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2975 OIC_LOG(ERROR, TAG, "setAddress is null");
2976 ca_mutex_unlock(g_gattObjectMutex);
2977 return CA_STATUS_FAILED;
2980 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2981 if (!jni_remoteAddress)
2983 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2984 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2985 ca_mutex_unlock(g_gattObjectMutex);
2986 return CA_STATUS_FAILED;
2989 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2992 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2993 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2994 ca_mutex_unlock(g_gattObjectMutex);
2995 return CA_STATUS_FAILED;
2998 if (!strcmp(setAddress, remoteAddress))
3000 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3001 (*env)->DeleteGlobalRef(env, jarrayObj);
3003 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3004 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3006 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3008 OIC_LOG(ERROR, TAG, "List removal failed.");
3009 ca_mutex_unlock(g_gattObjectMutex);
3010 return CA_STATUS_FAILED;
3012 ca_mutex_unlock(g_gattObjectMutex);
3013 return CA_STATUS_OK;
3015 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3016 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3019 ca_mutex_unlock(g_gattObjectMutex);
3020 OIC_LOG(DEBUG, TAG, "there are no target object");
3021 return CA_STATUS_OK;
3024 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3026 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3027 VERIFY_NON_NULL(addr, TAG, "addr is null");
3028 VERIFY_NON_NULL(env, TAG, "env is null");
3030 ca_mutex_lock(g_gattObjectMutex);
3031 if (!g_gattObjectList)
3033 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3034 ca_mutex_unlock(g_gattObjectMutex);
3035 return CA_STATUS_OK;
3038 uint32_t length = u_arraylist_length(g_gattObjectList);
3039 for (uint32_t index = 0; index < length; index++)
3041 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3044 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3045 ca_mutex_unlock(g_gattObjectMutex);
3046 return CA_STATUS_FAILED;
3049 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3050 if (!jni_setAddress)
3052 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3053 ca_mutex_unlock(g_gattObjectMutex);
3054 return CA_STATUS_FAILED;
3057 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3060 OIC_LOG(ERROR, TAG, "setAddress is null");
3061 ca_mutex_unlock(g_gattObjectMutex);
3062 return CA_STATUS_FAILED;
3065 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3068 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3069 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3070 ca_mutex_unlock(g_gattObjectMutex);
3071 return CA_STATUS_FAILED;
3074 if (!strcmp(setAddress, remoteAddress))
3076 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3077 (*env)->DeleteGlobalRef(env, jarrayObj);
3079 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3080 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3081 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3083 OIC_LOG(ERROR, TAG, "List removal failed.");
3084 ca_mutex_unlock(g_gattObjectMutex);
3085 return CA_STATUS_FAILED;
3087 ca_mutex_unlock(g_gattObjectMutex);
3088 return CA_STATUS_OK;
3090 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3091 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3094 ca_mutex_unlock(g_gattObjectMutex);
3095 OIC_LOG(DEBUG, TAG, "there are no target object");
3096 return CA_STATUS_FAILED;
3099 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3101 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3103 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3104 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3106 // get Bluetooth Address
3107 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3108 if (!jni_btTargetAddress)
3110 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3114 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3117 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3121 // get method ID of getDevice()
3122 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
3123 "getDevice", METHODID_BT_DEVICE);
3124 if (!jni_mid_getDevice)
3126 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3127 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3131 size_t length = u_arraylist_length(g_gattObjectList);
3132 for (size_t index = 0; index < length; index++)
3134 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3137 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3138 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3142 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3143 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3144 if (!jni_obj_device)
3146 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3147 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3151 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3154 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3155 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3159 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3162 OIC_LOG(ERROR, TAG, "btAddress is not available");
3163 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3167 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3168 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3169 if (!strcmp(targetAddress, btAddress))
3171 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3174 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3177 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3179 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3180 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3181 (*env)->DeleteLocalRef(env, jni_btAddress);
3182 (*env)->DeleteLocalRef(env, jni_obj_device);
3183 return jni_LEAddress;
3185 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3186 (*env)->DeleteLocalRef(env, jni_btAddress);
3187 (*env)->DeleteLocalRef(env, jni_obj_device);
3190 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3198 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3199 uint16_t notificationState, uint16_t sendState)
3201 VERIFY_NON_NULL(address, TAG, "address is null");
3203 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3206 OIC_LOG(ERROR, TAG, "out of memory");
3207 return CA_MEMORY_ALLOC_FAILED;
3210 if (strlen(address) > CA_MACADDR_SIZE)
3212 OIC_LOG(ERROR, TAG, "address is not proper");
3214 return CA_STATUS_FAILED;
3217 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3218 newstate->connectedState = connectedState;
3219 newstate->notificationState = notificationState;
3220 newstate->sendState = sendState;
3221 return CALEClientAddDeviceStateToList(newstate);
3224 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3226 VERIFY_NON_NULL(state, TAG, "state is null");
3228 ca_mutex_lock(g_deviceStateListMutex);
3230 if (!g_deviceStateList)
3232 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3233 ca_mutex_unlock(g_deviceStateListMutex);
3234 return CA_STATUS_FAILED;
3237 if (CALEClientIsDeviceInList(state->address))
3239 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3242 OIC_LOG(ERROR, TAG, "curState is null");
3243 ca_mutex_unlock(g_deviceStateListMutex);
3244 return CA_STATUS_FAILED;
3247 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3249 state->notificationState = curState->notificationState;
3251 state->autoConnectFlag = curState->autoConnectFlag;
3253 // delete previous state for update new state
3254 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3255 if (CA_STATUS_OK != res)
3257 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3258 ca_mutex_unlock(g_deviceStateListMutex);
3262 u_arraylist_add(g_deviceStateList, state); // update new state
3263 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
3264 state->connectedState, state->notificationState,
3265 state->address, state->autoConnectFlag);
3267 ca_mutex_unlock(g_deviceStateListMutex);
3268 return CA_STATUS_OK;
3271 bool CALEClientIsDeviceInList(const char* remoteAddress)
3273 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3275 if (!g_deviceStateList)
3277 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3281 uint32_t length = u_arraylist_length(g_deviceStateList);
3282 for (uint32_t index = 0; index < length; index++)
3284 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3287 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3291 if (!strcmp(remoteAddress, state->address))
3293 OIC_LOG(DEBUG, TAG, "the device is already set");
3302 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3306 CAResult_t CALEClientRemoveAllDeviceState()
3308 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3310 ca_mutex_lock(g_deviceStateListMutex);
3311 if (!g_deviceStateList)
3313 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3314 ca_mutex_unlock(g_deviceStateListMutex);
3315 return CA_STATUS_FAILED;
3318 uint32_t length = u_arraylist_length(g_deviceStateList);
3319 for (uint32_t index = 0; index < length; index++)
3321 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3324 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3330 OICFree(g_deviceStateList);
3331 g_deviceStateList = NULL;
3332 ca_mutex_unlock(g_deviceStateListMutex);
3334 return CA_STATUS_OK;
3337 CAResult_t CALEClientResetDeviceStateForAll()
3339 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3341 ca_mutex_lock(g_deviceStateListMutex);
3342 if (!g_deviceStateList)
3344 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3345 ca_mutex_unlock(g_deviceStateListMutex);
3346 return CA_STATUS_FAILED;
3349 size_t length = u_arraylist_length(g_deviceStateList);
3350 for (size_t index = 0; index < length; index++)
3352 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3355 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3359 // autoConnectFlag value will be not changed,
3360 // since it has reset only termination case.
3361 state->connectedState = STATE_DISCONNECTED;
3362 state->notificationState = STATE_CHARACTER_UNSET;
3363 state->sendState = STATE_SEND_NONE;
3365 ca_mutex_unlock(g_deviceStateListMutex);
3367 return CA_STATUS_OK;
3370 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3372 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3373 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3375 if (!g_deviceStateList)
3377 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3378 return CA_STATUS_FAILED;
3381 uint32_t length = u_arraylist_length(g_deviceStateList);
3382 for (uint32_t index = 0; index < length; index++)
3384 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3387 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3391 if (!strcmp(state->address, remoteAddress))
3393 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3395 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3397 if (NULL == targetState)
3399 OIC_LOG(ERROR, TAG, "List removal failed.");
3400 return CA_STATUS_FAILED;
3403 OICFree(targetState);
3404 return CA_STATUS_OK;
3408 return CA_STATUS_OK;
3411 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3413 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3414 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3416 if (!g_deviceStateList)
3418 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3422 uint32_t length = u_arraylist_length(g_deviceStateList);
3423 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3425 for (uint32_t index = 0; index < length; index++)
3427 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3430 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3434 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3435 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3437 if (!strcmp(state->address, remoteAddress))
3439 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3446 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3448 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3449 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3451 ca_mutex_lock(g_deviceStateListMutex);
3452 if (!g_deviceStateList)
3454 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3455 ca_mutex_unlock(g_deviceStateListMutex);
3459 uint32_t length = u_arraylist_length(g_deviceStateList);
3460 for (uint32_t index = 0; index < length; index++)
3462 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3465 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3469 if (!strcmp(state->address, remoteAddress))
3471 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3473 if (STATE_CONNECTED == state->connectedState)
3475 ca_mutex_unlock(g_deviceStateListMutex);
3480 ca_mutex_unlock(g_deviceStateListMutex);
3485 ca_mutex_unlock(g_deviceStateListMutex);
3489 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3491 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3492 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3494 ca_mutex_lock(g_deviceStateListMutex);
3495 if (!g_deviceStateList)
3497 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3498 ca_mutex_unlock(g_deviceStateListMutex);
3502 uint32_t length = u_arraylist_length(g_deviceStateList);
3503 for (uint32_t index = 0; index < length; index++)
3505 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3508 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3512 if (!strcmp(state->address, remoteAddress))
3514 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3516 if (STATE_CHARACTER_SET == state->notificationState)
3518 ca_mutex_unlock(g_deviceStateListMutex);
3523 ca_mutex_unlock(g_deviceStateListMutex);
3529 ca_mutex_unlock(g_deviceStateListMutex);
3533 void CALEClientCreateDeviceList()
3535 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3537 // create new object array
3538 if (!g_gattObjectList)
3540 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3542 g_gattObjectList = u_arraylist_create();
3545 if (!g_deviceStateList)
3547 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3549 g_deviceStateList = u_arraylist_create();
3554 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3556 g_deviceList = u_arraylist_create();
3561 * Check Sent Count for remove g_sendBuffer
3563 void CALEClientUpdateSendCnt(JNIEnv *env)
3565 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3567 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3569 ca_mutex_lock(g_threadMutex);
3573 if (g_targetCnt <= g_currentSentCnt)
3576 g_currentSentCnt = 0;
3580 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3581 g_sendBuffer = NULL;
3583 // notity the thread
3584 ca_cond_signal(g_threadCond);
3586 CALEClientSetSendFinishFlag(true);
3587 OIC_LOG(DEBUG, TAG, "set signal for send data");
3590 ca_mutex_unlock(g_threadMutex);
3593 CAResult_t CALEClientInitGattMutexVaraibles()
3595 if (NULL == g_bleReqRespClientCbMutex)
3597 g_bleReqRespClientCbMutex = ca_mutex_new();
3598 if (NULL == g_bleReqRespClientCbMutex)
3600 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3601 return CA_STATUS_FAILED;
3605 if (NULL == g_bleServerBDAddressMutex)
3607 g_bleServerBDAddressMutex = ca_mutex_new();
3608 if (NULL == g_bleServerBDAddressMutex)
3610 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3611 return CA_STATUS_FAILED;
3615 if (NULL == g_threadMutex)
3617 g_threadMutex = ca_mutex_new();
3618 if (NULL == g_threadMutex)
3620 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3621 return CA_STATUS_FAILED;
3625 if (NULL == g_threadSendMutex)
3627 g_threadSendMutex = ca_mutex_new();
3628 if (NULL == g_threadSendMutex)
3630 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3631 return CA_STATUS_FAILED;
3635 if (NULL == g_deviceListMutex)
3637 g_deviceListMutex = ca_mutex_new();
3638 if (NULL == g_deviceListMutex)
3640 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3641 return CA_STATUS_FAILED;
3645 if (NULL == g_gattObjectMutex)
3647 g_gattObjectMutex = ca_mutex_new();
3648 if (NULL == g_gattObjectMutex)
3650 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3651 return CA_STATUS_FAILED;
3655 if (NULL == g_deviceStateListMutex)
3657 g_deviceStateListMutex = ca_mutex_new();
3658 if (NULL == g_deviceStateListMutex)
3660 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3661 return CA_STATUS_FAILED;
3665 if (NULL == g_SendFinishMutex)
3667 g_SendFinishMutex = ca_mutex_new();
3668 if (NULL == g_SendFinishMutex)
3670 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3671 return CA_STATUS_FAILED;
3675 if (NULL == g_scanMutex)
3677 g_scanMutex = ca_mutex_new();
3678 if (NULL == g_scanMutex)
3680 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3681 return CA_STATUS_FAILED;
3685 if (NULL == g_threadWriteCharacteristicMutex)
3687 g_threadWriteCharacteristicMutex = ca_mutex_new();
3688 if (NULL == g_threadWriteCharacteristicMutex)
3690 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3691 return CA_STATUS_FAILED;
3695 if (NULL == g_deviceScanRetryDelayMutex)
3697 g_deviceScanRetryDelayMutex = ca_mutex_new();
3698 if (NULL == g_deviceScanRetryDelayMutex)
3700 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3701 return CA_STATUS_FAILED;
3705 return CA_STATUS_OK;
3708 void CALEClientTerminateGattMutexVariables()
3710 ca_mutex_free(g_bleReqRespClientCbMutex);
3711 g_bleReqRespClientCbMutex = NULL;
3713 ca_mutex_free(g_bleServerBDAddressMutex);
3714 g_bleServerBDAddressMutex = NULL;
3716 ca_mutex_free(g_threadMutex);
3717 g_threadMutex = NULL;
3719 ca_mutex_free(g_threadSendMutex);
3720 g_threadSendMutex = NULL;
3722 ca_mutex_free(g_deviceListMutex);
3723 g_deviceListMutex = NULL;
3725 ca_mutex_free(g_SendFinishMutex);
3726 g_SendFinishMutex = NULL;
3728 ca_mutex_free(g_scanMutex);
3731 ca_mutex_free(g_threadWriteCharacteristicMutex);
3732 g_threadWriteCharacteristicMutex = NULL;
3734 ca_mutex_free(g_deviceScanRetryDelayMutex);
3735 g_deviceScanRetryDelayMutex = NULL;
3738 void CALEClientSetSendFinishFlag(bool flag)
3740 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3742 ca_mutex_lock(g_SendFinishMutex);
3743 g_isFinishedSendData = flag;
3744 ca_mutex_unlock(g_SendFinishMutex);
3751 CAResult_t CAStartLEGattClient()
3753 // init mutex for send logic
3754 if (!g_deviceDescCond)
3756 g_deviceDescCond = ca_cond_new();
3761 g_threadCond = ca_cond_new();
3764 if (!g_threadWriteCharacteristicCond)
3766 g_threadWriteCharacteristicCond = ca_cond_new();
3769 CAResult_t ret = CALEClientStartScan();
3770 if (CA_STATUS_OK != ret)
3772 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3776 g_isStartedLEClient = true;
3777 return CA_STATUS_OK;
3780 void CAStopLEGattClient()
3782 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3786 OIC_LOG(ERROR, TAG, "g_jvm is null");
3790 bool isAttached = false;
3792 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3795 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3796 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3800 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3806 CAResult_t ret = CALEClientDisconnectAll(env);
3807 if (CA_STATUS_OK != ret)
3809 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3812 ret = CALEClientStopScan();
3813 if(CA_STATUS_OK != ret)
3815 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3818 ca_mutex_lock(g_threadMutex);
3819 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3820 ca_cond_signal(g_threadCond);
3821 CALEClientSetSendFinishFlag(true);
3822 ca_mutex_unlock(g_threadMutex);
3824 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3825 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3826 ca_cond_signal(g_threadWriteCharacteristicCond);
3827 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3829 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3830 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3831 ca_cond_signal(g_deviceScanRetryDelayCond);
3832 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3834 ca_cond_free(g_deviceDescCond);
3835 ca_cond_free(g_threadCond);
3836 ca_cond_free(g_threadWriteCharacteristicCond);
3837 ca_cond_free(g_deviceScanRetryDelayCond);
3839 g_deviceDescCond = NULL;
3840 g_threadCond = NULL;
3841 g_threadWriteCharacteristicCond = NULL;
3842 g_deviceScanRetryDelayCond = NULL;
3846 (*g_jvm)->DetachCurrentThread(g_jvm);
3851 CAResult_t CAInitializeLEGattClient()
3853 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3854 CALEClientInitialize();
3855 return CA_STATUS_OK;
3858 void CATerminateLEGattClient()
3860 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3861 CAStopLEGattClient();
3862 CALEClientTerminate();
3865 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3866 uint32_t dataLen, CALETransferType_t type,
3869 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3870 VERIFY_NON_NULL(data, TAG, "data is null");
3871 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3873 if (LE_UNICAST != type || position < 0)
3875 OIC_LOG(ERROR, TAG, "this request is not unicast");
3876 return CA_STATUS_INVALID_PARAM;
3879 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3882 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3884 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3885 VERIFY_NON_NULL(data, TAG, "data is null");
3887 return CALEClientSendMulticastMessage(data, dataLen);
3890 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3892 ca_mutex_lock(g_bleReqRespClientCbMutex);
3893 g_CABLEClientDataReceivedCallback = callback;
3894 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3897 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3899 g_threadPoolHandle = handle;
3902 CAResult_t CAGetLEAddress(char **local_address)
3904 VERIFY_NON_NULL(local_address, TAG, "local_address");
3905 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3906 return CA_NOT_SUPPORTED;
3909 JNIEXPORT void JNICALL
3910 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3913 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3914 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3915 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3916 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3918 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3921 JNIEXPORT void JNICALL
3922 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3925 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3926 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3927 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3928 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3930 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3933 JNIEXPORT void JNICALL
3934 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3937 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3938 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3939 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3941 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3942 if (CA_STATUS_OK != res)
3944 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3948 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
3950 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
3952 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3953 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
3955 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
3956 "getDevice", METHODID_BT_DEVICE);
3957 if (!jni_mid_getDevice)
3959 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3963 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
3964 if (!jni_obj_device)
3966 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3970 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
3973 OIC_LOG(ERROR, TAG, "jni_address is null");
3977 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
3982 * Class: org_iotivity_ca_jar_caleinterface
3983 * Method: CALeGattConnectionStateChangeCallback
3984 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3986 JNIEXPORT void JNICALL
3987 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3993 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3995 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3996 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3997 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3999 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4000 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4001 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4003 if (gatt_success == status && state_connected == newstate) // le connected
4005 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4011 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4014 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4015 STATE_CHARACTER_NO_CHANGE,
4017 if (CA_STATUS_OK != res)
4019 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4020 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4023 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4025 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4028 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4029 if (CA_STATUS_OK != res)
4031 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4035 res = CALEClientDiscoverServices(env, gatt);
4036 if (CA_STATUS_OK != res)
4038 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4042 else if (state_disconnected == newstate) // le disconnected
4044 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4047 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4051 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4054 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4055 STATE_CHARACTER_UNSET,
4057 if (CA_STATUS_OK != res)
4059 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4060 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4063 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4065 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4068 CAResult_t res = CALEClientGattClose(env, gatt);
4069 if (CA_STATUS_OK != res)
4071 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4074 if (GATT_ERROR == status)
4076 // when we get GATT ERROR(0x85), gatt connection can be called again.
4077 OIC_LOG(INFO, TAG, "retry gatt connect");
4079 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4082 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4086 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4089 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4093 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4096 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4104 if (CALECheckConnectionStateValue(status))
4106 // this state is unexpected reason to disconnect
4107 // if the reason is suitable, connection logic of the device will be destroyed.
4108 OIC_LOG(INFO, TAG, "connection logic destroy");
4113 // other reason except for gatt_success is expected to running
4114 // background connection in BT platform.
4115 OIC_LOG(INFO, TAG, "unknown state or manual disconnected state");
4116 CALEClientUpdateSendCnt(env);
4123 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4124 g_sendBuffer = NULL;
4132 CALEClientSendFinish(env, gatt);
4137 * Class: org_iotivity_ca_jar_caleinterface
4138 * Method: CALeGattServicesDiscoveredCallback
4139 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4141 JNIEXPORT void JNICALL
4142 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4147 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4148 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4149 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4150 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4152 if (0 != status) // discovery error
4154 CALEClientSendFinish(env, gatt);
4158 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4161 CALEClientSendFinish(env, gatt);
4165 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4168 CALEClientSendFinish(env, gatt);
4172 if (!CALEClientIsSetCharacteristic(address))
4174 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4177 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4181 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4182 if (!jni_obj_GattCharacteristic)
4184 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4188 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4189 jni_obj_GattCharacteristic);
4190 if (CA_STATUS_OK != res)
4192 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4196 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4197 if (CA_STATUS_OK != res)
4199 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4202 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4203 if (CA_STATUS_OK != res)
4205 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4211 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4213 if (CA_STATUS_OK != res)
4215 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4223 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4224 if (CA_STATUS_OK != res)
4226 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4231 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4232 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4237 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4238 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4239 CALEClientSendFinish(env, gatt);
4244 * Class: org_iotivity_ca_jar_caleinterface
4245 * Method: CALeGattCharacteristicWritjclasseCallback
4246 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4248 JNIEXPORT void JNICALL
4249 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4250 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4253 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4254 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4255 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4256 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4258 // send success & signal
4259 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4265 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4271 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4272 if (gatt_success != status) // error case
4274 OIC_LOG(ERROR, TAG, "send failure");
4277 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4278 if (CA_STATUS_OK != res)
4280 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4281 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4282 g_isSignalSetFlag = true;
4283 ca_cond_signal(g_threadWriteCharacteristicCond);
4284 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4286 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4287 STATE_CHARACTER_SET,
4289 if (CA_STATUS_OK != res)
4291 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4294 if (g_clientErrorCallback)
4296 jint length = (*env)->GetArrayLength(env, data);
4297 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4300 CALEClientSendFinish(env, gatt);
4306 OIC_LOG(DEBUG, TAG, "send success");
4307 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4308 STATE_SEND_SUCCESS);
4309 if (CA_STATUS_OK != res)
4311 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4314 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4315 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4316 g_isSignalSetFlag = true;
4317 ca_cond_signal(g_threadWriteCharacteristicCond);
4318 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4320 CALEClientUpdateSendCnt(env);
4323 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4329 CALEClientSendFinish(env, gatt);
4334 * Class: org_iotivity_ca_jar_caleinterface
4335 * Method: CALeGattCharacteristicChangedCallback
4336 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4338 JNIEXPORT void JNICALL
4339 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4340 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4342 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4343 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4344 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4345 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4346 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4348 // get Byte Array and convert to uint8_t*
4349 jint length = (*env)->GetArrayLength(env, data);
4352 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4354 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4355 jni_byte_responseData);
4357 uint8_t* receivedData = OICMalloc(length);
4360 OIC_LOG(ERROR, TAG, "receivedData is null");
4364 memcpy(receivedData, jni_byte_responseData, length);
4365 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4367 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4370 OIC_LOG(ERROR, TAG, "jni_address is null");
4371 OICFree(receivedData);
4375 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4378 OIC_LOG(ERROR, TAG, "address is null");
4379 OICFree(receivedData);
4383 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4384 receivedData, length);
4386 ca_mutex_lock(g_bleServerBDAddressMutex);
4387 uint32_t sentLength = 0;
4388 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4390 ca_mutex_unlock(g_bleServerBDAddressMutex);
4392 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4396 * Class: org_iotivity_ca_jar_caleinterface
4397 * Method: CALeGattDescriptorWriteCallback
4398 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4400 JNIEXPORT void JNICALL
4401 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4405 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4406 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4407 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4408 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4410 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4411 if (gatt_success != status) // error
4418 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4419 if (CA_STATUS_OK != res)
4421 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4430 CALEClientSendFinish(env, gatt);