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;
98 static ca_mutex g_threadSendStateMutex = NULL;
100 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
103 * check if retry logic for connection routine has to be stopped or not.
104 * in case of error value including this method, connection routine has to be stopped.
105 * since there is no retry logic for this error reason in this client.
106 * @param state constant value of bluetoothgatt.
107 * @return true - waiting for background connection in BT platform.
108 * false - connection routine has to be stopped.
110 static bool CALECheckConnectionStateValue(jint state)
114 case GATT_CONNECTION_PRIORITY_BALANCED:
116 case GATT_INSUFFICIENT_AUTHENTICATION:
117 case GATT_INSUFFICIENT_ENCRYPTION:
118 case GATT_INVALID_ATTRIBUTE_LENGTH:
119 case GATT_INVALID_OFFSET:
120 case GATT_READ_NOT_PERMITTED:
121 case GATT_REQUEST_NOT_SUPPORTED:
122 case GATT_WRITE_NOT_PERMITTED:
129 void CALEClientJniInit()
131 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
132 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
135 void CALEClientJNISetContext()
137 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
138 g_context = (jobject) CANativeJNIGetContext();
141 CAResult_t CALECreateJniInterfaceObject()
143 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
147 OIC_LOG(ERROR, TAG, "g_context is null");
148 return CA_STATUS_FAILED;
153 OIC_LOG(ERROR, TAG, "g_jvm is null");
154 return CA_STATUS_FAILED;
157 bool isAttached = false;
159 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
162 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
163 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
167 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
168 return CA_STATUS_FAILED;
173 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
174 "getApplicationContext",
175 "()Landroid/content/Context;");
177 if (!mid_getApplicationContext)
179 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
180 return CA_STATUS_FAILED;
183 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
184 mid_getApplicationContext);
185 if (!jApplicationContext)
187 OIC_LOG(ERROR, TAG, "Could not get application context");
188 return CA_STATUS_FAILED;
191 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
192 if (!jni_LEInterface)
194 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
198 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
199 "(Landroid/content/Context;)V");
200 if (!LeInterfaceConstructorMethod)
202 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
206 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
207 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
211 (*g_jvm)->DetachCurrentThread(g_jvm);
220 (*g_jvm)->DetachCurrentThread(g_jvm);
223 return CA_STATUS_FAILED;
226 CAResult_t CALEClientInitialize()
228 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
234 OIC_LOG(ERROR, TAG, "g_jvm is null");
235 return CA_STATUS_FAILED;
238 bool isAttached = false;
240 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
243 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
244 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
248 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
249 return CA_STATUS_FAILED;
254 CAResult_t ret = CALECheckPlatformVersion(env, 18);
255 if (CA_STATUS_OK != ret)
257 OIC_LOG(ERROR, TAG, "it is not supported");
261 (*g_jvm)->DetachCurrentThread(g_jvm);
267 ret = CALEClientInitGattMutexVaraibles();
268 if (CA_STATUS_OK != ret)
270 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
271 CALEClientTerminateGattMutexVariables();
275 (*g_jvm)->DetachCurrentThread(g_jvm);
281 g_deviceDescCond = ca_cond_new();
283 // init mutex for send logic
284 g_threadCond = ca_cond_new();
285 g_threadWriteCharacteristicCond = ca_cond_new();
286 g_deviceScanRetryDelayCond = ca_cond_new();
288 CALEClientCreateDeviceList();
289 CALEClientJNISetContext();
291 ret = CALEClientCreateUUIDList();
292 if (CA_STATUS_OK != ret)
294 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
298 (*g_jvm)->DetachCurrentThread(g_jvm);
304 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
305 if (CA_STATUS_OK != ret)
307 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
311 (*g_jvm)->DetachCurrentThread(g_jvm);
316 g_isStartedLEClient = true;
320 (*g_jvm)->DetachCurrentThread(g_jvm);
326 void CALEClientTerminate()
328 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
332 OIC_LOG(ERROR, TAG, "g_jvm is null");
336 bool isAttached = false;
338 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
341 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
342 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
346 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
352 if (g_leScanCallback)
354 (*env)->DeleteGlobalRef(env, g_leScanCallback);
355 g_leScanCallback = NULL;
358 if (g_leGattCallback)
360 (*env)->DeleteGlobalRef(env, g_leGattCallback);
361 g_leGattCallback = NULL;
366 (*env)->DeleteGlobalRef(env, g_sendBuffer);
372 (*env)->DeleteGlobalRef(env, g_uuidList);
376 CAResult_t ret = CALEClientRemoveAllDeviceState();
377 if (CA_STATUS_OK != ret)
379 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
382 ret = CALEClientRemoveAllScanDevices(env);
383 if (CA_STATUS_OK != ret)
385 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
388 ret = CALEClientRemoveAllGattObjs(env);
389 if (CA_STATUS_OK != ret)
391 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
394 CALEClientSetScanFlag(false);
395 CALEClientSetSendFinishFlag(true);
397 CALEClientTerminateGattMutexVariables();
398 CALEClientDestroyJniInterface();
400 ca_cond_free(g_deviceDescCond);
401 ca_cond_free(g_threadCond);
402 ca_cond_free(g_threadWriteCharacteristicCond);
403 ca_cond_free(g_deviceScanRetryDelayCond);
405 g_deviceDescCond = NULL;
407 g_threadWriteCharacteristicCond = NULL;
408 g_deviceScanRetryDelayCond = NULL;
410 g_isSignalSetFlag = false;
414 (*g_jvm)->DetachCurrentThread(g_jvm);
418 CAResult_t CALEClientDestroyJniInterface()
420 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
424 OIC_LOG(ERROR, TAG, "g_jvm is null");
425 return CA_STATUS_FAILED;
428 bool isAttached = false;
430 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
433 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
434 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
438 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
439 return CA_STATUS_FAILED;
444 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
445 if (!jni_LeInterface)
447 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
451 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
452 "destroyLeInterface",
454 if (!jni_InterfaceDestroyMethod)
456 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
460 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
462 if ((*env)->ExceptionCheck(env))
464 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
465 (*env)->ExceptionDescribe(env);
466 (*env)->ExceptionClear(env);
470 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
474 (*g_jvm)->DetachCurrentThread(g_jvm);
483 (*g_jvm)->DetachCurrentThread(g_jvm);
486 return CA_STATUS_FAILED;
489 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
491 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
492 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
496 CAResult_t res = CALEClientDisconnect(env, gatt);
497 if (CA_STATUS_OK != res)
499 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
502 CALEClientUpdateSendCnt(env);
505 CAResult_t CALEClientSendUnicastMessage(const char* address,
507 const uint32_t dataLen)
509 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
510 VERIFY_NON_NULL(address, TAG, "address is null");
511 VERIFY_NON_NULL(data, TAG, "data is null");
513 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
516 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
517 const uint32_t dataLen)
519 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
520 VERIFY_NON_NULL(data, TAG, "data is null");
524 OIC_LOG(ERROR, TAG, "g_jvm is null");
525 return CA_STATUS_FAILED;
528 bool isAttached = false;
530 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
533 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
534 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
538 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
539 return CA_STATUS_FAILED;
544 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
545 if (CA_STATUS_OK != ret)
547 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
552 (*g_jvm)->DetachCurrentThread(g_jvm);
558 CAResult_t CALEClientStartUnicastServer(const char* address)
560 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
562 return CA_NOT_SUPPORTED;
565 CAResult_t CALEClientStartMulticastServer()
567 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
569 return CA_NOT_SUPPORTED;
572 void CALEClientStopUnicastServer()
574 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
577 void CALEClientStopMulticastServer()
579 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
582 void CALEClientSetCallback(CAPacketReceiveCallback callback)
584 g_packetReceiveCallback = callback;
587 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
589 g_clientErrorCallback = callback;
592 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
594 VERIFY_NON_NULL(env, TAG, "env");
598 return CA_STATUS_FAILED;
601 if (0 == u_arraylist_length(g_deviceList) // multicast
602 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
604 // Wait for LE peripherals to be discovered.
606 // Number of times to wait for discovery to complete.
607 static size_t const RETRIES = 5;
609 static uint64_t const TIMEOUT =
610 2 * MICROSECS_PER_SEC; // Microseconds
612 bool devicesDiscovered = false;
613 for (size_t i = 0; i < RETRIES; ++i)
615 OIC_LOG(DEBUG, TAG, "waiting for target device");
616 if (ca_cond_wait_for(g_deviceDescCond,
618 TIMEOUT) == CA_WAIT_SUCCESS)
620 ca_mutex_lock(g_deviceListMutex);
621 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
622 ca_mutex_unlock(g_deviceListMutex);
624 if (0 < scannedDeviceLen)
626 if (!address // multicast
627 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
629 devicesDiscovered = true;
636 OIC_LOG(INFO, TAG, "waiting..");
638 ca_mutex_lock(g_deviceScanRetryDelayMutex);
639 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
640 g_deviceScanRetryDelayMutex,
641 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
643 OIC_LOG(INFO, TAG, "finish to waiting for target device");
644 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
647 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
650 // checking whether a target device is found while waiting for time-out.
651 if (CALEClientIsDeviceInScanDeviceList(env, address))
653 devicesDiscovered = true;
662 // time out for scanning devices
663 if (!devicesDiscovered)
665 return CA_STATUS_FAILED;
673 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
674 const uint32_t dataLen)
676 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
678 VERIFY_NON_NULL(address, TAG, "address is null");
679 VERIFY_NON_NULL(data, TAG, "data is null");
683 OIC_LOG(ERROR, TAG, "g_jvm is null");
684 return CA_STATUS_FAILED;
687 bool isAttached = false;
689 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
692 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
693 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
696 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
697 return CA_STATUS_FAILED;
702 ca_mutex_lock(g_threadSendMutex);
704 CALEClientSetSendFinishFlag(false);
706 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
707 if (CA_STATUS_OK != ret)
709 OIC_LOG(INFO, TAG, "there is no scanned device");
713 if (g_context && g_deviceList)
715 uint32_t length = u_arraylist_length(g_deviceList);
716 for (uint32_t index = 0; index < length; index++)
718 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
721 OIC_LOG(ERROR, TAG, "jarrayObj is null");
725 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
728 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
732 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
735 OIC_LOG(ERROR, TAG, "setAddress is null");
739 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
741 if (!strcmp(setAddress, address))
743 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
745 // connect to gatt server
746 ret = CALEClientStopScan();
747 if (CA_STATUS_OK != ret)
749 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
755 (*env)->DeleteGlobalRef(env, g_sendBuffer);
758 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
759 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
760 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
762 // Target device to send message is just one.
765 ret = CALEClientSendData(env, jarrayObj);
766 if (CA_STATUS_OK != ret)
768 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
772 OIC_LOG(INFO, TAG, "wake up");
775 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
779 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
781 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
782 // if there is no connection state.
783 ca_mutex_lock(g_threadMutex);
784 if (!g_isFinishedSendData)
786 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
787 ca_cond_wait(g_threadCond, g_threadMutex);
788 OIC_LOG(DEBUG, TAG, "the data was sent");
790 ca_mutex_unlock(g_threadMutex);
794 (*g_jvm)->DetachCurrentThread(g_jvm);
797 // start LE Scan again
798 ret = CALEClientStartScan();
799 if (CA_STATUS_OK != ret)
801 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
802 ca_mutex_unlock(g_threadSendMutex);
806 ca_mutex_unlock(g_threadSendMutex);
807 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
808 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
815 ret = CA_SEND_FAILED;
819 ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
821 if (CA_STATUS_OK != ret)
823 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
831 // start LE Scan again
832 ret = CALEClientStartScan();
833 if (CA_STATUS_OK != ret)
835 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
836 ca_mutex_unlock(g_threadSendMutex);
839 (*g_jvm)->DetachCurrentThread(g_jvm);
846 (*g_jvm)->DetachCurrentThread(g_jvm);
849 ca_mutex_unlock(g_threadSendMutex);
850 return CA_SEND_FAILED;
853 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
854 const uint32_t dataLen)
856 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
857 VERIFY_NON_NULL(data, TAG, "data is null");
858 VERIFY_NON_NULL(env, TAG, "env is null");
862 OIC_LOG(ERROR, TAG, "g_deviceList is null");
863 return CA_STATUS_FAILED;
866 ca_mutex_lock(g_threadSendMutex);
868 CALEClientSetSendFinishFlag(false);
870 OIC_LOG(DEBUG, TAG, "set byteArray for data");
873 (*env)->DeleteGlobalRef(env, g_sendBuffer);
877 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
878 if (CA_STATUS_OK != res)
880 OIC_LOG(INFO, TAG, "there is no scanned device");
884 // connect to gatt server
885 res = CALEClientStopScan();
886 if (CA_STATUS_OK != res)
888 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
889 ca_mutex_unlock(g_threadSendMutex);
892 uint32_t length = u_arraylist_length(g_deviceList);
893 g_targetCnt = length;
895 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
896 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
897 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
899 for (uint32_t index = 0; index < length; index++)
901 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
904 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
908 res = CALEClientSendData(env, jarrayObj);
909 if (res != CA_STATUS_OK)
911 OIC_LOG(ERROR, TAG, "BT device - send has failed");
914 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
917 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
921 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
924 OIC_LOG(ERROR, TAG, "address is not available");
928 (*env)->ReleaseStringUTFChars(env, jni_address, address);
931 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
933 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
934 ca_mutex_lock(g_threadMutex);
935 if (!g_isFinishedSendData)
937 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
938 ca_cond_wait(g_threadCond, g_threadMutex);
939 OIC_LOG(DEBUG, TAG, "the data was sent");
941 ca_mutex_unlock(g_threadMutex);
943 // start LE Scan again
944 res = CALEClientStartScan();
945 if (CA_STATUS_OK != res)
947 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
948 ca_mutex_unlock(g_threadSendMutex);
952 ca_mutex_unlock(g_threadSendMutex);
953 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
957 res = CALEClientStartScan();
958 if (CA_STATUS_OK != res)
960 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
961 ca_mutex_unlock(g_threadSendMutex);
965 ca_mutex_unlock(g_threadSendMutex);
966 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
967 return CA_SEND_FAILED;
970 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
972 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
973 VERIFY_NON_NULL(device, TAG, "device is null");
974 VERIFY_NON_NULL(env, TAG, "env is null");
976 // get BLE address from bluetooth device object.
977 char* address = NULL;
978 CALEState_t* state = NULL;
979 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
982 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
983 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
986 OIC_LOG(ERROR, TAG, "address is not available");
987 return CA_STATUS_FAILED;
989 ca_mutex_lock(g_deviceStateListMutex);
990 state = CALEClientGetStateInfo(address);
991 ca_mutex_unlock(g_deviceStateListMutex);
996 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
998 // cancel previous connection request before connection
999 // if there is gatt object in g_gattObjectList.
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 (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1026 STATE_SERVICE_CONNECTED))
1028 OIC_LOG(INFO, TAG, "GATT has already connected");
1030 jobject gatt = CALEClientGetGattObjInList(env, address);
1033 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1034 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1035 return CA_STATUS_FAILED;
1038 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1039 if (CA_STATUS_OK != ret)
1041 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1042 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1045 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1047 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1050 OIC_LOG(INFO, TAG, "service connecting...");
1052 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1053 STATE_DISCONNECTED))
1055 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1057 // cancel previous connection request before connection
1058 // if there is gatt object in g_gattObjectList.
1061 jobject gatt = CALEClientGetGattObjInList(env, address);
1064 CAResult_t res = CALEClientDisconnect(env, gatt);
1065 if (CA_STATUS_OK != res)
1067 OIC_LOG(INFO, TAG, "there is no gatt object");
1070 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1073 OIC_LOG(DEBUG, TAG, "start to connect LE");
1074 jobject gatt = CALEClientConnect(env, device,
1075 CALEClientGetFlagFromState(env, jni_address,
1076 CA_LE_AUTO_CONNECT_FLAG));
1079 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1080 return CA_STATUS_FAILED;
1085 return CA_STATUS_OK;
1088 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1090 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1091 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1093 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1094 "()Landroid/bluetooth/BluetoothDevice;");
1095 if (!jni_mid_getDevice)
1097 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1101 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1102 if (!jni_obj_device)
1104 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1108 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1111 OIC_LOG(ERROR, TAG, "jni_address is null");
1121 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1124 OIC_LOG(DEBUG, TAG, "Gatt Close");
1125 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1126 VERIFY_NON_NULL(env, TAG, "env is null");
1128 // get BluetoothGatt method
1129 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1130 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1131 if (!jni_mid_closeGatt)
1133 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1134 return CA_STATUS_OK;
1137 // call disconnect gatt method
1138 OIC_LOG(DEBUG, TAG, "request to close GATT");
1139 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1141 if ((*env)->ExceptionCheck(env))
1143 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1144 (*env)->ExceptionDescribe(env);
1145 (*env)->ExceptionClear(env);
1146 return CA_STATUS_FAILED;
1149 return CA_STATUS_OK;
1152 CAResult_t CALEClientStartScan()
1154 if (!g_isStartedLEClient)
1156 OIC_LOG(ERROR, TAG, "LE client is not started");
1157 return CA_STATUS_FAILED;
1162 OIC_LOG(ERROR, TAG, "g_jvm is null");
1163 return CA_STATUS_FAILED;
1166 if (g_isStartedScan)
1168 OIC_LOG(INFO, TAG, "scanning is already started");
1169 return CA_STATUS_OK;
1172 bool isAttached = false;
1174 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1177 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1179 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1182 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1183 return CA_STATUS_FAILED;
1188 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1190 CAResult_t ret = CA_STATUS_OK;
1191 // scan gatt server with UUID
1192 if (g_leScanCallback && g_uuidList)
1195 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1197 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1199 if (CA_STATUS_OK != ret)
1201 if (CA_ADAPTER_NOT_ENABLED == ret)
1203 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1207 OIC_LOG(ERROR, TAG, "start scan has failed");
1214 (*g_jvm)->DetachCurrentThread(g_jvm);
1220 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1222 VERIFY_NON_NULL(callback, TAG, "callback is null");
1223 VERIFY_NON_NULL(env, TAG, "env is null");
1225 if (!CALEIsEnableBTAdapter(env))
1227 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1228 return CA_ADAPTER_NOT_ENABLED;
1231 // get default bt adapter class
1232 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1233 if (!jni_cid_BTAdapter)
1235 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1236 return CA_STATUS_FAILED;
1239 // get remote bt adapter method
1240 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1241 "getDefaultAdapter",
1242 METHODID_OBJECTNONPARAM);
1243 if (!jni_mid_getDefaultAdapter)
1245 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1246 return CA_STATUS_FAILED;
1249 // get start le scan method
1250 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1251 "(Landroid/bluetooth/BluetoothAdapter$"
1252 "LeScanCallback;)Z");
1253 if (!jni_mid_startLeScan)
1255 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1256 return CA_STATUS_FAILED;
1259 // gat bt adapter object
1260 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1261 jni_mid_getDefaultAdapter);
1262 if (!jni_obj_BTAdapter)
1264 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1265 return CA_STATUS_FAILED;
1268 // call start le scan method
1269 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1270 jni_mid_startLeScan, callback);
1271 if (!jni_obj_startLeScan)
1273 OIC_LOG(INFO, TAG, "startLeScan is failed");
1277 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1278 CALEClientSetScanFlag(true);
1281 return CA_STATUS_OK;
1284 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1286 VERIFY_NON_NULL(callback, TAG, "callback is null");
1287 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1288 VERIFY_NON_NULL(env, TAG, "env is null");
1290 if (!CALEIsEnableBTAdapter(env))
1292 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1293 return CA_ADAPTER_NOT_ENABLED;
1296 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1297 if (!jni_cid_BTAdapter)
1299 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1300 return CA_STATUS_FAILED;
1303 // get remote bt adapter method
1304 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1305 "getDefaultAdapter",
1306 METHODID_OBJECTNONPARAM);
1307 if (!jni_mid_getDefaultAdapter)
1309 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1310 return CA_STATUS_FAILED;
1313 // get start le scan method
1314 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1315 "([Ljava/util/UUID;Landroid/bluetooth/"
1316 "BluetoothAdapter$LeScanCallback;)Z");
1317 if (!jni_mid_startLeScan)
1319 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1320 return CA_STATUS_FAILED;
1323 // get bt adapter object
1324 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1325 jni_mid_getDefaultAdapter);
1326 if (!jni_obj_BTAdapter)
1328 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1329 return CA_STATUS_FAILED;
1332 // call start le scan method
1333 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1334 jni_mid_startLeScan, uuids, callback);
1335 if (!jni_obj_startLeScan)
1337 OIC_LOG(INFO, TAG, "startLeScan With UUID is failed");
1341 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1342 CALEClientSetScanFlag(true);
1345 return CA_STATUS_OK;
1348 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1350 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1351 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1354 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1357 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1361 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1362 "(Ljava/lang/String;)"
1363 "Ljava/util/UUID;");
1364 if (!jni_mid_fromString)
1366 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1370 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1371 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1375 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1379 return jni_obj_uuid;
1382 CAResult_t CALEClientStopScan()
1386 OIC_LOG(ERROR, TAG, "g_jvm is null");
1387 return CA_STATUS_FAILED;
1390 if (!g_isStartedScan)
1392 OIC_LOG(INFO, TAG, "scanning is already stopped");
1393 return CA_STATUS_OK;
1396 bool isAttached = false;
1398 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1401 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1402 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1405 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1406 return CA_STATUS_FAILED;
1411 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1412 if (CA_STATUS_OK != ret)
1414 if (CA_ADAPTER_NOT_ENABLED == ret)
1416 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1420 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1425 CALEClientSetScanFlag(false);
1430 (*g_jvm)->DetachCurrentThread(g_jvm);
1436 void CALEClientSetScanFlag(bool flag)
1438 ca_mutex_lock(g_scanMutex);
1439 g_isStartedScan = flag;
1440 ca_mutex_unlock(g_scanMutex);
1443 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1445 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1446 VERIFY_NON_NULL(callback, TAG, "callback is null");
1447 VERIFY_NON_NULL(env, TAG, "env is null");
1449 if (!CALEIsEnableBTAdapter(env))
1451 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1452 return CA_ADAPTER_NOT_ENABLED;
1455 // get default bt adapter class
1456 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1457 if (!jni_cid_BTAdapter)
1459 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1460 return CA_STATUS_FAILED;
1463 // get remote bt adapter method
1464 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1465 "getDefaultAdapter",
1466 METHODID_OBJECTNONPARAM);
1467 if (!jni_mid_getDefaultAdapter)
1469 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1470 return CA_STATUS_FAILED;
1473 // get start le scan method
1474 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1475 "(Landroid/bluetooth/"
1476 "BluetoothAdapter$LeScanCallback;)V");
1477 if (!jni_mid_stopLeScan)
1479 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1480 return CA_STATUS_FAILED;
1483 // gat bt adapter object
1484 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1485 jni_mid_getDefaultAdapter);
1486 if (!jni_obj_BTAdapter)
1488 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1489 return CA_STATUS_FAILED;
1492 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1493 // call start le scan method
1494 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1495 if ((*env)->ExceptionCheck(env))
1497 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1498 (*env)->ExceptionDescribe(env);
1499 (*env)->ExceptionClear(env);
1500 return CA_STATUS_FAILED;
1503 return CA_STATUS_OK;
1506 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
1507 jint state_idx, jboolean flag)
1509 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1510 VERIFY_NON_NULL(env, TAG, "env");
1511 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1513 ca_mutex_lock(g_deviceStateListMutex);
1515 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1518 OIC_LOG(ERROR, TAG, "address is not available");
1519 return CA_STATUS_FAILED;
1522 if (CALEClientIsDeviceInList(address))
1524 CALEState_t* curState = CALEClientGetStateInfo(address);
1527 OIC_LOG(ERROR, TAG, "curState is null");
1528 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1529 ca_mutex_unlock(g_deviceStateListMutex);
1530 return CA_STATUS_FAILED;
1532 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1536 case CA_LE_AUTO_CONNECT_FLAG:
1537 curState->autoConnectFlag = flag;
1544 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1545 ca_mutex_unlock(g_deviceStateListMutex);
1546 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1547 return CA_STATUS_OK;
1550 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1552 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1553 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1554 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1556 ca_mutex_lock(g_deviceStateListMutex);
1558 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1561 OIC_LOG(ERROR, TAG, "address is not available");
1565 CALEState_t* curState = CALEClientGetStateInfo(address);
1568 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1569 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1570 ca_mutex_unlock(g_deviceStateListMutex);
1574 jboolean ret = JNI_FALSE;
1577 case CA_LE_AUTO_CONNECT_FLAG:
1578 ret = curState->autoConnectFlag;
1583 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1585 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1586 ca_mutex_unlock(g_deviceStateListMutex);
1588 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1592 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1594 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1595 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1596 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1598 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1599 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1602 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1605 OIC_LOG(ERROR, TAG, "address is not available");
1609 // close the gatt service
1610 jobject gatt = CALEClientGetGattObjInList(env, address);
1613 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1614 if (CA_STATUS_OK != res)
1616 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1617 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1621 // clean previous gatt object after close profile service
1622 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1623 if (CA_STATUS_OK != res)
1625 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1626 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1630 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1633 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1636 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1640 // add new gatt object into g_gattObjectList
1641 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1642 if (CA_STATUS_OK != res)
1644 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1651 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1653 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1654 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1655 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1657 if (!g_leGattCallback)
1659 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1663 if (!CALEIsEnableBTAdapter(env))
1665 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1669 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1672 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1676 // get BluetoothDevice method
1677 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1678 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1680 "(Landroid/content/Context;ZLandroid/"
1681 "bluetooth/BluetoothGattCallback;)"
1682 "Landroid/bluetooth/BluetoothGatt;");
1683 if (!jni_mid_connectGatt)
1685 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1689 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1690 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1691 jni_mid_connectGatt,
1693 autoconnect, g_leGattCallback);
1694 if (!jni_obj_connectGatt)
1696 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1697 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1698 CALEClientUpdateSendCnt(env);
1703 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1705 return jni_obj_connectGatt;
1708 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1710 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1712 VERIFY_NON_NULL(env, TAG, "env is null");
1713 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1715 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1716 if (!jni_cid_BTAdapter)
1718 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1719 return CA_STATUS_FAILED;
1722 // get remote bt adapter method
1723 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1724 "getDefaultAdapter",
1725 METHODID_OBJECTNONPARAM);
1726 if (!jni_mid_getDefaultAdapter)
1728 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1729 return CA_STATUS_FAILED;
1732 // gat bt adapter object
1733 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1734 jni_mid_getDefaultAdapter);
1735 if (!jni_obj_BTAdapter)
1737 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1738 return CA_STATUS_FAILED;
1741 // get closeProfileProxy method
1742 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1743 "closeProfileProxy",
1744 "(ILandroid/bluetooth/"
1745 "BluetoothProfile;)V");
1746 if (!jni_mid_closeProfileProxy)
1748 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1749 return CA_STATUS_FAILED;
1752 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1753 if (!jni_cid_BTProfile)
1755 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1756 return CA_STATUS_FAILED;
1759 // GATT - Constant value : 7 (0x00000007)
1760 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1764 OIC_LOG(ERROR, TAG, "id_gatt is null");
1765 return CA_STATUS_FAILED;
1768 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1770 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1771 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1772 if ((*env)->ExceptionCheck(env))
1774 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1775 (*env)->ExceptionDescribe(env);
1776 (*env)->ExceptionClear(env);
1777 return CA_STATUS_FAILED;
1780 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1781 return CA_STATUS_OK;
1785 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1787 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1788 VERIFY_NON_NULL(env, TAG, "env is null");
1789 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1791 // get BluetoothGatt method
1792 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1793 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1794 "disconnect", "()V");
1795 if (!jni_mid_disconnectGatt)
1797 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1798 return CA_STATUS_FAILED;
1801 // call disconnect gatt method
1802 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1803 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1804 if ((*env)->ExceptionCheck(env))
1806 OIC_LOG(ERROR, TAG, "disconnect has failed");
1807 (*env)->ExceptionDescribe(env);
1808 (*env)->ExceptionClear(env);
1809 return CA_STATUS_FAILED;
1812 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1814 return CA_STATUS_OK;
1817 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1819 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1820 VERIFY_NON_NULL(env, TAG, "env is null");
1822 if (!g_gattObjectList)
1824 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1825 return CA_STATUS_OK;
1828 uint32_t length = u_arraylist_length(g_gattObjectList);
1829 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1830 for (uint32_t index = 0; index < length; index++)
1832 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1833 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1836 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1839 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1840 if (CA_STATUS_OK != res)
1842 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1847 return CA_STATUS_OK;
1850 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1852 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1853 VERIFY_NON_NULL(env, TAG, "env is null");
1855 if (!g_gattObjectList)
1857 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1858 return CA_STATUS_OK;
1861 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1864 OIC_LOG(ERROR, TAG, "address is null");
1865 return CA_STATUS_FAILED;
1868 uint32_t length = u_arraylist_length(g_gattObjectList);
1869 for (uint32_t index = 0; index < length; index++)
1871 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1874 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1878 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1879 if (!jni_setAddress)
1881 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1882 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1883 return CA_STATUS_FAILED;
1886 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1889 OIC_LOG(ERROR, TAG, "setAddress is null");
1890 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1891 return CA_STATUS_FAILED;
1894 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1895 if (!strcmp(address, setAddress))
1897 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1898 if (CA_STATUS_OK != res)
1900 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1901 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1902 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1903 return CA_STATUS_FAILED;
1905 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1906 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1907 return CA_STATUS_OK;
1909 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1911 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1913 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1914 return CA_STATUS_OK;
1917 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1919 VERIFY_NON_NULL(env, TAG, "env is null");
1920 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1922 if (!CALEIsEnableBTAdapter(env))
1924 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1925 return CA_ADAPTER_NOT_ENABLED;
1928 // get BluetoothGatt.discoverServices method
1929 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1930 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1931 "discoverServices", "()Z");
1932 if (!jni_mid_discoverServices)
1934 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1935 return CA_STATUS_FAILED;
1938 // call disconnect gatt method
1939 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1940 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1943 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1944 return CA_STATUS_FAILED;
1947 return CA_STATUS_OK;
1950 static void CALEWriteCharacteristicThread(void* object)
1952 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1954 bool isAttached = false;
1956 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1959 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1960 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1964 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1970 jobject gatt = (jobject)object;
1971 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1972 if (CA_STATUS_OK != ret)
1974 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1979 (*g_jvm)->DetachCurrentThread(g_jvm);
1983 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1985 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
1987 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1988 VERIFY_NON_NULL(env, TAG, "env is null");
1990 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
1993 CALEClientSendFinish(env, gatt);
1994 return CA_STATUS_FAILED;
1997 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2000 CALEClientSendFinish(env, gatt);
2001 return CA_STATUS_FAILED;
2004 ca_mutex_lock(g_threadSendStateMutex);
2006 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2008 OIC_LOG(INFO, TAG, "current state is SENDING");
2009 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2010 ca_mutex_unlock(g_threadSendStateMutex);
2011 return CA_STATUS_OK;
2014 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2017 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2018 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2019 CALEClientSendFinish(env, gatt);
2020 ca_mutex_unlock(g_threadSendStateMutex);
2021 return CA_STATUS_FAILED;
2024 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2026 ca_mutex_unlock(g_threadSendStateMutex);
2029 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2030 if (!jni_obj_character)
2032 CALEClientSendFinish(env, gatt);
2033 return CA_STATUS_FAILED;
2036 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2037 if (CA_STATUS_OK != ret)
2039 CALEClientSendFinish(env, gatt);
2040 return CA_STATUS_FAILED;
2043 // wait for callback for write Characteristic with success to sent data
2044 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2045 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2046 if (!g_isSignalSetFlag)
2048 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2049 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2050 g_threadWriteCharacteristicMutex,
2051 WAIT_TIME_WRITE_CHARACTERISTIC))
2053 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2054 g_isSignalSetFlag = false;
2055 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2056 return CA_STATUS_FAILED;
2059 // reset flag set by writeCharacteristic Callback
2060 g_isSignalSetFlag = false;
2061 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2063 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2064 return CA_STATUS_OK;
2067 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2069 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2070 VERIFY_NON_NULL(env, TAG, "env is null");
2071 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2073 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2074 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2075 CALEWriteCharacteristicThread, (void*)gattParam))
2077 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2078 return CA_STATUS_FAILED;
2081 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2082 return CA_STATUS_OK;
2085 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2086 jobject gattCharacteristic)
2088 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2089 VERIFY_NON_NULL(env, TAG, "env is null");
2090 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2091 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2093 if (!CALEIsEnableBTAdapter(env))
2095 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2096 return CA_STATUS_FAILED;
2099 // get BluetoothGatt.write characteristic method
2100 OIC_LOG(DEBUG, TAG, "write characteristic method");
2101 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2102 "writeCharacteristic",
2103 "(Landroid/bluetooth/"
2104 "BluetoothGattCharacteristic;)Z");
2105 if (!jni_mid_writeCharacteristic)
2107 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2108 return CA_STATUS_FAILED;
2111 // call disconnect gatt method
2112 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2113 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2114 jni_mid_writeCharacteristic,
2115 gattCharacteristic);
2118 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2122 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2123 return CA_STATUS_FAILED;
2126 return CA_STATUS_OK;
2129 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2131 VERIFY_NON_NULL(env, TAG, "env is null");
2132 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2134 if (!CALEIsEnableBTAdapter(env))
2136 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2137 return CA_STATUS_FAILED;
2140 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2143 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2144 return CA_STATUS_FAILED;
2147 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2148 if (!jni_obj_GattCharacteristic)
2150 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2151 return CA_STATUS_FAILED;
2154 OIC_LOG(DEBUG, TAG, "read characteristic method");
2155 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2156 "readCharacteristic",
2157 "(Landroid/bluetooth/"
2158 "BluetoothGattCharacteristic;)Z");
2159 if (!jni_mid_readCharacteristic)
2161 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2162 return CA_STATUS_FAILED;
2165 // call disconnect gatt method
2166 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2167 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2168 jni_obj_GattCharacteristic);
2171 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2175 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2176 return CA_STATUS_FAILED;
2179 return CA_STATUS_OK;
2182 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2183 jobject characteristic)
2185 VERIFY_NON_NULL(env, TAG, "env is null");
2186 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2187 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2189 if (!CALEIsEnableBTAdapter(env))
2191 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2192 return CA_ADAPTER_NOT_ENABLED;
2195 // get BluetoothGatt.setCharacteristicNotification method
2196 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2197 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2198 "setCharacteristicNotification",
2199 "(Landroid/bluetooth/"
2200 "BluetoothGattCharacteristic;Z)Z");
2201 if (!jni_mid_setNotification)
2203 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2204 return CA_STATUS_FAILED;
2207 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2208 characteristic, JNI_TRUE);
2209 if (JNI_TRUE == ret)
2211 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2215 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2216 return CA_STATUS_FAILED;
2219 return CA_STATUS_OK;
2222 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2224 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2225 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2226 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2228 if (!CALEIsEnableBTAdapter(env))
2230 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2234 // get BluetoothGatt.getService method
2235 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2236 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2238 "(Ljava/util/UUID;)Landroid/bluetooth/"
2239 "BluetoothGattService;");
2240 if (!jni_mid_getService)
2242 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2246 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2247 if (!jni_obj_service_uuid)
2249 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2253 // get bluetooth gatt service
2254 OIC_LOG(DEBUG, TAG, "request to get service");
2255 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2256 jni_obj_service_uuid);
2257 if (!jni_obj_gattService)
2259 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2263 // get bluetooth gatt service method
2264 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2265 "BluetoothGattService",
2266 "getCharacteristic",
2267 "(Ljava/util/UUID;)"
2268 "Landroid/bluetooth/"
2269 "BluetoothGattCharacteristic;");
2270 if (!jni_mid_getCharacteristic)
2272 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2276 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2279 OIC_LOG(ERROR, TAG, "uuid is null");
2283 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2284 if (!jni_obj_tx_uuid)
2286 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2287 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2291 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2292 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2293 jni_mid_getCharacteristic,
2296 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2297 return jni_obj_GattCharacteristic;
2300 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2302 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2303 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2304 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2305 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2307 if (!CALEIsEnableBTAdapter(env))
2309 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2313 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2316 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2320 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2321 if (!jni_obj_GattCharacteristic)
2323 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2327 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2328 "/BluetoothGattCharacteristic");
2329 if (!jni_cid_BTGattCharacteristic)
2331 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2335 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2336 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2338 if (!jni_mid_setValue)
2340 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2344 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2346 if (JNI_TRUE == ret)
2348 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2352 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2357 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2358 "setWriteType", "(I)V");
2359 if (!jni_mid_setWriteType)
2361 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2365 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2366 "WRITE_TYPE_NO_RESPONSE", "I");
2367 if (!jni_fid_no_response)
2369 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2373 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2374 jni_fid_no_response);
2376 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2378 return jni_obj_GattCharacteristic;
2381 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2383 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2384 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2386 if (!CALEIsEnableBTAdapter(env))
2388 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2392 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2393 "BluetoothGattCharacteristic",
2394 "getValue", "()[B");
2395 if (!jni_mid_getValue)
2397 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2401 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2403 return jni_obj_data_array;
2406 CAResult_t CALEClientCreateUUIDList()
2410 OIC_LOG(ERROR, TAG, "g_jvm is null");
2411 return CA_STATUS_FAILED;
2414 bool isAttached = false;
2416 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2419 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2420 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2424 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2425 return CA_STATUS_FAILED;
2430 // create new object array
2431 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2432 if (!jni_cid_uuid_list)
2434 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2438 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2439 jni_cid_uuid_list, NULL);
2440 if (!jni_obj_uuid_list)
2442 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2447 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2450 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2453 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2455 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2459 (*g_jvm)->DetachCurrentThread(g_jvm);
2462 return CA_STATUS_OK;
2469 (*g_jvm)->DetachCurrentThread(g_jvm);
2471 return CA_STATUS_FAILED;
2474 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2475 jobject characteristic)
2477 VERIFY_NON_NULL(env, TAG, "env is null");
2478 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2479 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2481 if (!CALEIsEnableBTAdapter(env))
2483 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2484 return CA_ADAPTER_NOT_ENABLED;
2487 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2488 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2489 "BluetoothGattCharacteristic",
2491 "(Ljava/util/UUID;)Landroid/bluetooth/"
2492 "BluetoothGattDescriptor;");
2493 if (!jni_mid_getDescriptor)
2495 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2496 return CA_STATUS_FAILED;
2499 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2500 if (!jni_obj_cc_uuid)
2502 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2503 return CA_STATUS_FAILED;
2506 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2507 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2508 jni_mid_getDescriptor, jni_obj_cc_uuid);
2509 if (!jni_obj_descriptor)
2511 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2512 return CA_NOT_SUPPORTED;
2515 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2516 jclass jni_cid_descriptor = (*env)->FindClass(env,
2517 "android/bluetooth/BluetoothGattDescriptor");
2518 if (!jni_cid_descriptor)
2520 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2521 return CA_STATUS_FAILED;
2524 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2525 if (!jni_mid_setValue)
2527 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2528 return CA_STATUS_FAILED;
2531 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2532 "ENABLE_NOTIFICATION_VALUE", "[B");
2533 if (!jni_fid_NotiValue)
2535 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2536 return CA_STATUS_FAILED;
2539 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2541 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2542 env, jni_obj_descriptor, jni_mid_setValue,
2543 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2546 OIC_LOG(DEBUG, TAG, "setValue success");
2550 OIC_LOG(ERROR, TAG, "setValue has failed");
2551 return CA_STATUS_FAILED;
2554 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2556 "(Landroid/bluetooth/"
2557 "BluetoothGattDescriptor;)Z");
2558 if (!jni_mid_writeDescriptor)
2560 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2561 return CA_STATUS_FAILED;
2564 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2565 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2566 jni_obj_descriptor);
2569 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2573 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2574 return CA_STATUS_FAILED;
2577 return CA_STATUS_OK;
2580 void CALEClientCreateScanDeviceList(JNIEnv *env)
2582 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2583 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2585 ca_mutex_lock(g_deviceListMutex);
2586 // create new object array
2587 if (g_deviceList == NULL)
2589 OIC_LOG(DEBUG, TAG, "Create device list");
2591 g_deviceList = u_arraylist_create();
2593 ca_mutex_unlock(g_deviceListMutex);
2596 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2598 VERIFY_NON_NULL(device, TAG, "device is null");
2599 VERIFY_NON_NULL(env, TAG, "env is null");
2601 ca_mutex_lock(g_deviceListMutex);
2605 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2607 CALEClientSetScanFlag(false);
2608 if (CA_STATUS_OK != CALEClientStopScan())
2610 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2613 ca_mutex_unlock(g_deviceListMutex);
2614 return CA_STATUS_FAILED;
2617 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2618 if (!jni_remoteAddress)
2620 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2621 ca_mutex_unlock(g_deviceListMutex);
2622 return CA_STATUS_FAILED;
2625 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2628 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2629 ca_mutex_unlock(g_deviceListMutex);
2630 return CA_STATUS_FAILED;
2633 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2635 jobject gdevice = (*env)->NewGlobalRef(env, device);
2636 u_arraylist_add(g_deviceList, gdevice);
2637 ca_cond_signal(g_deviceDescCond);
2638 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2640 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2642 ca_mutex_unlock(g_deviceListMutex);
2644 return CA_STATUS_OK;
2647 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2649 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2650 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2654 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2658 uint32_t length = u_arraylist_length(g_deviceList);
2659 for (uint32_t index = 0; index < length; index++)
2661 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2664 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2668 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2669 if (!jni_setAddress)
2671 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2675 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2678 OIC_LOG(ERROR, TAG, "setAddress is null");
2682 if (!strcmp(remoteAddress, setAddress))
2684 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2688 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2691 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2696 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2698 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2699 VERIFY_NON_NULL(env, TAG, "env is null");
2701 ca_mutex_lock(g_deviceListMutex);
2705 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2706 ca_mutex_unlock(g_deviceListMutex);
2707 return CA_STATUS_FAILED;
2710 uint32_t length = u_arraylist_length(g_deviceList);
2711 for (uint32_t index = 0; index < length; index++)
2713 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2716 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2719 (*env)->DeleteGlobalRef(env, jarrayObj);
2723 OICFree(g_deviceList);
2724 g_deviceList = NULL;
2726 ca_mutex_unlock(g_deviceListMutex);
2727 return CA_STATUS_OK;
2730 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2732 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2733 VERIFY_NON_NULL(address, TAG, "address is null");
2734 VERIFY_NON_NULL(env, TAG, "env is null");
2736 ca_mutex_lock(g_deviceListMutex);
2740 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2741 ca_mutex_unlock(g_deviceListMutex);
2742 return CA_STATUS_FAILED;
2745 uint32_t length = u_arraylist_length(g_deviceList);
2746 for (uint32_t index = 0; index < length; index++)
2748 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2751 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2752 ca_mutex_unlock(g_deviceListMutex);
2753 return CA_STATUS_FAILED;
2756 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2757 if (!jni_setAddress)
2759 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2760 ca_mutex_unlock(g_deviceListMutex);
2761 return CA_STATUS_FAILED;
2764 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2767 OIC_LOG(ERROR, TAG, "setAddress is null");
2768 ca_mutex_unlock(g_deviceListMutex);
2769 return CA_STATUS_FAILED;
2772 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2775 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2776 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2777 ca_mutex_unlock(g_deviceListMutex);
2778 return CA_STATUS_FAILED;
2781 if (!strcmp(setAddress, remoteAddress))
2783 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2784 (*env)->DeleteGlobalRef(env, jarrayObj);
2786 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2787 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2789 if (NULL == u_arraylist_remove(g_deviceList, index))
2791 OIC_LOG(ERROR, TAG, "List removal failed.");
2792 ca_mutex_unlock(g_deviceListMutex);
2793 return CA_STATUS_FAILED;
2795 ca_mutex_unlock(g_deviceListMutex);
2796 return CA_STATUS_OK;
2798 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2799 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2802 ca_mutex_unlock(g_deviceListMutex);
2803 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2805 return CA_STATUS_OK;
2812 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2814 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2815 VERIFY_NON_NULL(env, TAG, "env is null");
2816 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2818 ca_mutex_lock(g_gattObjectMutex);
2820 if (!g_gattObjectList)
2822 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2823 ca_mutex_unlock(g_gattObjectMutex);
2824 return CA_STATUS_FAILED;
2827 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2828 if (!jni_remoteAddress)
2830 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2831 ca_mutex_unlock(g_gattObjectMutex);
2832 return CA_STATUS_FAILED;
2835 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2838 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2839 ca_mutex_unlock(g_gattObjectMutex);
2840 return CA_STATUS_FAILED;
2843 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2844 if (!CALEClientIsGattObjInList(env, remoteAddress))
2846 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2847 u_arraylist_add(g_gattObjectList, newGatt);
2848 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2851 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2852 ca_mutex_unlock(g_gattObjectMutex);
2853 return CA_STATUS_OK;
2856 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2858 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2859 VERIFY_NON_NULL(env, TAG, "env is null");
2860 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2862 uint32_t length = u_arraylist_length(g_gattObjectList);
2863 for (uint32_t index = 0; index < length; index++)
2866 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2869 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2873 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2874 if (!jni_setAddress)
2876 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2880 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2883 OIC_LOG(ERROR, TAG, "setAddress is null");
2887 if (!strcmp(remoteAddress, setAddress))
2889 OIC_LOG(DEBUG, TAG, "the device is already set");
2890 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2895 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2900 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2904 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2906 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2907 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2908 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2910 ca_mutex_lock(g_gattObjectMutex);
2911 uint32_t length = u_arraylist_length(g_gattObjectList);
2912 for (uint32_t index = 0; index < length; index++)
2914 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2917 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2918 ca_mutex_unlock(g_gattObjectMutex);
2922 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2923 if (!jni_setAddress)
2925 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2926 ca_mutex_unlock(g_gattObjectMutex);
2930 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2933 OIC_LOG(ERROR, TAG, "setAddress is null");
2934 ca_mutex_unlock(g_gattObjectMutex);
2938 if (!strcmp(remoteAddress, setAddress))
2940 OIC_LOG(DEBUG, TAG, "the device is already set");
2941 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2942 ca_mutex_unlock(g_gattObjectMutex);
2945 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2948 ca_mutex_unlock(g_gattObjectMutex);
2949 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2953 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2955 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2956 VERIFY_NON_NULL(env, TAG, "env is null");
2958 ca_mutex_lock(g_gattObjectMutex);
2959 if (!g_gattObjectList)
2961 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2962 ca_mutex_unlock(g_gattObjectMutex);
2963 return CA_STATUS_OK;
2966 uint32_t length = u_arraylist_length(g_gattObjectList);
2967 for (uint32_t index = 0; index < length; index++)
2969 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2972 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2975 (*env)->DeleteGlobalRef(env, jarrayObj);
2979 OICFree(g_gattObjectList);
2980 g_gattObjectList = NULL;
2981 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2982 ca_mutex_unlock(g_gattObjectMutex);
2983 return CA_STATUS_OK;
2986 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2988 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2989 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2990 VERIFY_NON_NULL(env, TAG, "env is null");
2992 ca_mutex_lock(g_gattObjectMutex);
2993 if (!g_gattObjectList)
2995 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2996 ca_mutex_unlock(g_gattObjectMutex);
2997 return CA_STATUS_OK;
3000 uint32_t length = u_arraylist_length(g_gattObjectList);
3001 for (uint32_t index = 0; index < length; index++)
3003 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3006 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3007 ca_mutex_unlock(g_gattObjectMutex);
3008 return CA_STATUS_FAILED;
3011 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3012 if (!jni_setAddress)
3014 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3015 ca_mutex_unlock(g_gattObjectMutex);
3016 return CA_STATUS_FAILED;
3019 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3022 OIC_LOG(ERROR, TAG, "setAddress is null");
3023 ca_mutex_unlock(g_gattObjectMutex);
3024 return CA_STATUS_FAILED;
3027 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3028 if (!jni_remoteAddress)
3030 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3031 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3032 ca_mutex_unlock(g_gattObjectMutex);
3033 return CA_STATUS_FAILED;
3036 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3039 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3040 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3041 ca_mutex_unlock(g_gattObjectMutex);
3042 return CA_STATUS_FAILED;
3045 if (!strcmp(setAddress, remoteAddress))
3047 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3048 (*env)->DeleteGlobalRef(env, jarrayObj);
3050 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3051 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3053 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3055 OIC_LOG(ERROR, TAG, "List removal failed.");
3056 ca_mutex_unlock(g_gattObjectMutex);
3057 return CA_STATUS_FAILED;
3059 ca_mutex_unlock(g_gattObjectMutex);
3060 return CA_STATUS_OK;
3062 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3063 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3066 ca_mutex_unlock(g_gattObjectMutex);
3067 OIC_LOG(DEBUG, TAG, "there are no target object");
3068 return CA_STATUS_OK;
3071 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3073 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3074 VERIFY_NON_NULL(addr, TAG, "addr is null");
3075 VERIFY_NON_NULL(env, TAG, "env is null");
3077 ca_mutex_lock(g_gattObjectMutex);
3078 if (!g_gattObjectList)
3080 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3081 ca_mutex_unlock(g_gattObjectMutex);
3082 return CA_STATUS_OK;
3085 uint32_t length = u_arraylist_length(g_gattObjectList);
3086 for (uint32_t index = 0; index < length; index++)
3088 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3091 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3092 ca_mutex_unlock(g_gattObjectMutex);
3093 return CA_STATUS_FAILED;
3096 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3097 if (!jni_setAddress)
3099 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3100 ca_mutex_unlock(g_gattObjectMutex);
3101 return CA_STATUS_FAILED;
3104 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3107 OIC_LOG(ERROR, TAG, "setAddress is null");
3108 ca_mutex_unlock(g_gattObjectMutex);
3109 return CA_STATUS_FAILED;
3112 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3115 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3116 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3117 ca_mutex_unlock(g_gattObjectMutex);
3118 return CA_STATUS_FAILED;
3121 if (!strcmp(setAddress, remoteAddress))
3123 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3124 (*env)->DeleteGlobalRef(env, jarrayObj);
3126 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3127 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3128 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3130 OIC_LOG(ERROR, TAG, "List removal failed.");
3131 ca_mutex_unlock(g_gattObjectMutex);
3132 return CA_STATUS_FAILED;
3134 ca_mutex_unlock(g_gattObjectMutex);
3135 return CA_STATUS_OK;
3137 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3138 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3141 ca_mutex_unlock(g_gattObjectMutex);
3142 OIC_LOG(DEBUG, TAG, "there are no target object");
3143 return CA_STATUS_FAILED;
3146 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3148 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3150 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3151 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3153 // get Bluetooth Address
3154 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3155 if (!jni_btTargetAddress)
3157 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3161 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3164 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3168 // get method ID of getDevice()
3169 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3170 "getDevice", METHODID_BT_DEVICE);
3171 if (!jni_mid_getDevice)
3173 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3174 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3178 size_t length = u_arraylist_length(g_gattObjectList);
3179 for (size_t index = 0; index < length; index++)
3181 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3184 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3185 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3189 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3190 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3191 if (!jni_obj_device)
3193 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3194 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3198 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3201 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3202 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3206 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3209 OIC_LOG(ERROR, TAG, "btAddress is not available");
3210 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3214 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3215 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3216 if (!strcmp(targetAddress, btAddress))
3218 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3221 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3224 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3226 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3227 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3228 (*env)->DeleteLocalRef(env, jni_btAddress);
3229 (*env)->DeleteLocalRef(env, jni_obj_device);
3230 return jni_LEAddress;
3232 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3233 (*env)->DeleteLocalRef(env, jni_btAddress);
3234 (*env)->DeleteLocalRef(env, jni_obj_device);
3237 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3245 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3246 uint16_t target_state)
3248 VERIFY_NON_NULL(address, TAG, "address is null");
3250 if (!g_deviceStateList)
3252 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3253 return CA_STATUS_FAILED;
3256 ca_mutex_lock(g_deviceStateListMutex);
3258 if (CALEClientIsDeviceInList(address))
3260 CALEState_t* curState = CALEClientGetStateInfo(address);
3263 OIC_LOG(ERROR, TAG, "curState is null");
3264 ca_mutex_unlock(g_deviceStateListMutex);
3265 return CA_STATUS_FAILED;
3270 case CA_LE_CONNECTION_STATE:
3271 curState->connectedState = target_state;
3273 case CA_LE_SEND_STATE:
3274 curState->sendState = target_state;
3279 OIC_LOG_V(INFO, TAG, "update state : - addr : %s, "
3280 "conn : %d, send : %d, ACFlag : %d",
3281 curState->address, curState->connectedState,
3282 curState->sendState, curState->autoConnectFlag);
3284 else /** state is added newly **/
3286 if (strlen(address) > CA_MACADDR_SIZE)
3288 OIC_LOG(ERROR, TAG, "address is not proper");
3289 ca_mutex_unlock(g_deviceStateListMutex);
3290 return CA_STATUS_INVALID_PARAM;
3293 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3296 OIC_LOG(ERROR, TAG, "out of memory");
3297 ca_mutex_unlock(g_deviceStateListMutex);
3298 return CA_MEMORY_ALLOC_FAILED;
3301 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3305 case CA_LE_CONNECTION_STATE:
3306 newstate->connectedState = target_state;
3307 newstate->sendState = STATE_SEND_NONE;
3309 case CA_LE_SEND_STATE:
3310 newstate->connectedState = STATE_DISCONNECTED;
3311 newstate->sendState = target_state;
3316 OIC_LOG_V(INFO, TAG, "Set newState to List - addr : %s, "
3317 "conn : %d, send : %d, ACFlag : %d",
3318 newstate->address, newstate->connectedState,
3319 newstate->sendState, newstate->autoConnectFlag);
3320 u_arraylist_add(g_deviceStateList, newstate); // update new state
3323 ca_mutex_unlock(g_deviceStateListMutex);
3325 return CA_STATUS_OK;
3328 bool CALEClientIsDeviceInList(const char* remoteAddress)
3330 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3332 if (!g_deviceStateList)
3334 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3338 uint32_t length = u_arraylist_length(g_deviceStateList);
3339 for (uint32_t index = 0; index < length; index++)
3341 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3344 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3348 if (!strcmp(remoteAddress, state->address))
3350 OIC_LOG(DEBUG, TAG, "the device is already set");
3359 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3363 CAResult_t CALEClientRemoveAllDeviceState()
3365 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3367 ca_mutex_lock(g_deviceStateListMutex);
3368 if (!g_deviceStateList)
3370 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3371 ca_mutex_unlock(g_deviceStateListMutex);
3372 return CA_STATUS_FAILED;
3375 uint32_t length = u_arraylist_length(g_deviceStateList);
3376 for (uint32_t index = 0; index < length; index++)
3378 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3381 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3387 OICFree(g_deviceStateList);
3388 g_deviceStateList = NULL;
3389 ca_mutex_unlock(g_deviceStateListMutex);
3391 return CA_STATUS_OK;
3394 CAResult_t CALEClientResetDeviceStateForAll()
3396 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3398 ca_mutex_lock(g_deviceStateListMutex);
3399 if (!g_deviceStateList)
3401 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3402 ca_mutex_unlock(g_deviceStateListMutex);
3403 return CA_STATUS_FAILED;
3406 size_t length = u_arraylist_length(g_deviceStateList);
3407 for (size_t index = 0; index < length; index++)
3409 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3412 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3416 // autoConnectFlag value will be not changed,
3417 // since it has reset only termination case.
3418 state->connectedState = STATE_DISCONNECTED;
3419 state->sendState = STATE_SEND_NONE;
3421 ca_mutex_unlock(g_deviceStateListMutex);
3423 return CA_STATUS_OK;
3426 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3428 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3429 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3431 if (!g_deviceStateList)
3433 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3434 return CA_STATUS_FAILED;
3437 uint32_t length = u_arraylist_length(g_deviceStateList);
3438 for (uint32_t index = 0; index < length; index++)
3440 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3443 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3447 if (!strcmp(state->address, remoteAddress))
3449 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3451 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3453 if (NULL == targetState)
3455 OIC_LOG(ERROR, TAG, "List removal failed.");
3456 return CA_STATUS_FAILED;
3459 OICFree(targetState);
3460 return CA_STATUS_OK;
3464 return CA_STATUS_OK;
3467 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3469 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3471 if (!g_deviceStateList)
3473 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3477 uint32_t length = u_arraylist_length(g_deviceStateList);
3478 OIC_LOG_V(DEBUG, TAG, "size of deviceStateList is %d", length);
3480 for (uint32_t index = 0; index < length; index++)
3482 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3485 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3489 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3490 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3492 if (!strcmp(state->address, remoteAddress))
3494 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3501 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3502 uint16_t target_state)
3504 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3505 state_type, target_state);
3506 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3508 ca_mutex_lock(g_deviceStateListMutex);
3509 if (!g_deviceStateList)
3511 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3512 ca_mutex_unlock(g_deviceStateListMutex);
3516 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3519 OIC_LOG(ERROR, TAG, "state is null");
3520 ca_mutex_unlock(g_deviceStateListMutex);
3524 uint16_t curValue = 0;
3527 case CA_LE_CONNECTION_STATE:
3528 curValue = state->connectedState;
3530 case CA_LE_SEND_STATE:
3531 curValue = state->sendState;
3537 if (target_state == curValue)
3539 ca_mutex_unlock(g_deviceStateListMutex);
3544 ca_mutex_unlock(g_deviceStateListMutex);
3548 ca_mutex_unlock(g_deviceStateListMutex);
3552 void CALEClientCreateDeviceList()
3554 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3556 // create new object array
3557 if (!g_gattObjectList)
3559 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3561 g_gattObjectList = u_arraylist_create();
3564 if (!g_deviceStateList)
3566 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3568 g_deviceStateList = u_arraylist_create();
3573 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3575 g_deviceList = u_arraylist_create();
3580 * Check Sent Count for remove g_sendBuffer
3582 void CALEClientUpdateSendCnt(JNIEnv *env)
3584 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3586 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3588 ca_mutex_lock(g_threadMutex);
3592 if (g_targetCnt <= g_currentSentCnt)
3595 g_currentSentCnt = 0;
3599 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3600 g_sendBuffer = NULL;
3602 // notity the thread
3603 ca_cond_signal(g_threadCond);
3605 CALEClientSetSendFinishFlag(true);
3606 OIC_LOG(DEBUG, TAG, "set signal for send data");
3609 ca_mutex_unlock(g_threadMutex);
3612 CAResult_t CALEClientInitGattMutexVaraibles()
3614 if (NULL == g_bleReqRespClientCbMutex)
3616 g_bleReqRespClientCbMutex = ca_mutex_new();
3617 if (NULL == g_bleReqRespClientCbMutex)
3619 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3620 return CA_STATUS_FAILED;
3624 if (NULL == g_bleServerBDAddressMutex)
3626 g_bleServerBDAddressMutex = ca_mutex_new();
3627 if (NULL == g_bleServerBDAddressMutex)
3629 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3630 return CA_STATUS_FAILED;
3634 if (NULL == g_threadMutex)
3636 g_threadMutex = ca_mutex_new();
3637 if (NULL == g_threadMutex)
3639 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3640 return CA_STATUS_FAILED;
3644 if (NULL == g_threadSendMutex)
3646 g_threadSendMutex = ca_mutex_new();
3647 if (NULL == g_threadSendMutex)
3649 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3650 return CA_STATUS_FAILED;
3654 if (NULL == g_deviceListMutex)
3656 g_deviceListMutex = ca_mutex_new();
3657 if (NULL == g_deviceListMutex)
3659 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3660 return CA_STATUS_FAILED;
3664 if (NULL == g_gattObjectMutex)
3666 g_gattObjectMutex = ca_mutex_new();
3667 if (NULL == g_gattObjectMutex)
3669 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3670 return CA_STATUS_FAILED;
3674 if (NULL == g_deviceStateListMutex)
3676 g_deviceStateListMutex = ca_mutex_new();
3677 if (NULL == g_deviceStateListMutex)
3679 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3680 return CA_STATUS_FAILED;
3684 if (NULL == g_SendFinishMutex)
3686 g_SendFinishMutex = ca_mutex_new();
3687 if (NULL == g_SendFinishMutex)
3689 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3690 return CA_STATUS_FAILED;
3694 if (NULL == g_scanMutex)
3696 g_scanMutex = ca_mutex_new();
3697 if (NULL == g_scanMutex)
3699 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3700 return CA_STATUS_FAILED;
3704 if (NULL == g_threadWriteCharacteristicMutex)
3706 g_threadWriteCharacteristicMutex = ca_mutex_new();
3707 if (NULL == g_threadWriteCharacteristicMutex)
3709 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3710 return CA_STATUS_FAILED;
3714 if (NULL == g_deviceScanRetryDelayMutex)
3716 g_deviceScanRetryDelayMutex = ca_mutex_new();
3717 if (NULL == g_deviceScanRetryDelayMutex)
3719 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3720 return CA_STATUS_FAILED;
3724 if (NULL == g_threadSendStateMutex)
3726 g_threadSendStateMutex = ca_mutex_new();
3727 if (NULL == g_threadSendStateMutex)
3729 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3730 return CA_STATUS_FAILED;
3734 return CA_STATUS_OK;
3737 void CALEClientTerminateGattMutexVariables()
3739 ca_mutex_free(g_bleReqRespClientCbMutex);
3740 g_bleReqRespClientCbMutex = NULL;
3742 ca_mutex_free(g_bleServerBDAddressMutex);
3743 g_bleServerBDAddressMutex = NULL;
3745 ca_mutex_free(g_threadMutex);
3746 g_threadMutex = NULL;
3748 ca_mutex_free(g_threadSendMutex);
3749 g_threadSendMutex = NULL;
3751 ca_mutex_free(g_deviceListMutex);
3752 g_deviceListMutex = NULL;
3754 ca_mutex_free(g_SendFinishMutex);
3755 g_SendFinishMutex = NULL;
3757 ca_mutex_free(g_scanMutex);
3760 ca_mutex_free(g_threadWriteCharacteristicMutex);
3761 g_threadWriteCharacteristicMutex = NULL;
3763 ca_mutex_free(g_deviceScanRetryDelayMutex);
3764 g_deviceScanRetryDelayMutex = NULL;
3766 ca_mutex_free(g_threadSendStateMutex);
3767 g_threadSendStateMutex = NULL;
3770 void CALEClientSetSendFinishFlag(bool flag)
3772 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3774 ca_mutex_lock(g_SendFinishMutex);
3775 g_isFinishedSendData = flag;
3776 ca_mutex_unlock(g_SendFinishMutex);
3783 CAResult_t CAStartLEGattClient()
3785 // init mutex for send logic
3786 if (!g_deviceDescCond)
3788 g_deviceDescCond = ca_cond_new();
3793 g_threadCond = ca_cond_new();
3796 if (!g_threadWriteCharacteristicCond)
3798 g_threadWriteCharacteristicCond = ca_cond_new();
3801 CAResult_t ret = CALEClientStartScan();
3802 if (CA_STATUS_OK != ret)
3804 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3808 g_isStartedLEClient = true;
3809 return CA_STATUS_OK;
3812 void CAStopLEGattClient()
3814 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3818 OIC_LOG(ERROR, TAG, "g_jvm is null");
3822 bool isAttached = false;
3824 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3827 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3828 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3832 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3838 CAResult_t ret = CALEClientDisconnectAll(env);
3839 if (CA_STATUS_OK != ret)
3841 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3844 ret = CALEClientStopScan();
3845 if(CA_STATUS_OK != ret)
3847 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3850 ca_mutex_lock(g_threadMutex);
3851 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3852 ca_cond_signal(g_threadCond);
3853 CALEClientSetSendFinishFlag(true);
3854 ca_mutex_unlock(g_threadMutex);
3856 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3857 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3858 ca_cond_signal(g_threadWriteCharacteristicCond);
3859 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3861 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3862 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3863 ca_cond_signal(g_deviceScanRetryDelayCond);
3864 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3866 ca_cond_free(g_deviceDescCond);
3867 ca_cond_free(g_threadCond);
3868 ca_cond_free(g_threadWriteCharacteristicCond);
3869 ca_cond_free(g_deviceScanRetryDelayCond);
3871 g_deviceDescCond = NULL;
3872 g_threadCond = NULL;
3873 g_threadWriteCharacteristicCond = NULL;
3874 g_deviceScanRetryDelayCond = NULL;
3878 (*g_jvm)->DetachCurrentThread(g_jvm);
3883 CAResult_t CAInitializeLEGattClient()
3885 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3886 CALEClientInitialize();
3887 return CA_STATUS_OK;
3890 void CATerminateLEGattClient()
3892 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3893 CAStopLEGattClient();
3894 CALEClientTerminate();
3897 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3898 uint32_t dataLen, CALETransferType_t type,
3901 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3902 VERIFY_NON_NULL(data, TAG, "data is null");
3903 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3905 if (LE_UNICAST != type || position < 0)
3907 OIC_LOG(ERROR, TAG, "this request is not unicast");
3908 return CA_STATUS_INVALID_PARAM;
3911 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3914 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3916 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3917 VERIFY_NON_NULL(data, TAG, "data is null");
3919 return CALEClientSendMulticastMessage(data, dataLen);
3922 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3924 ca_mutex_lock(g_bleReqRespClientCbMutex);
3925 g_CABLEClientDataReceivedCallback = callback;
3926 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3929 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3931 g_threadPoolHandle = handle;
3934 CAResult_t CAGetLEAddress(char **local_address)
3936 VERIFY_NON_NULL(local_address, TAG, "local_address");
3937 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3938 return CA_NOT_SUPPORTED;
3941 JNIEXPORT void JNICALL
3942 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3945 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3946 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3947 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3948 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3950 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3953 JNIEXPORT void JNICALL
3954 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3957 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3958 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3959 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3960 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3962 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3965 JNIEXPORT void JNICALL
3966 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3969 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3970 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3971 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3973 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3974 if (CA_STATUS_OK != res)
3976 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3980 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
3982 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
3984 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3985 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
3987 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3988 "getDevice", METHODID_BT_DEVICE);
3989 if (!jni_mid_getDevice)
3991 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3995 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
3996 if (!jni_obj_device)
3998 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4002 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4005 OIC_LOG(ERROR, TAG, "jni_address is null");
4009 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4014 * Class: org_iotivity_ca_jar_caleinterface
4015 * Method: CALeGattConnectionStateChangeCallback
4016 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4018 JNIEXPORT void JNICALL
4019 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4025 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4027 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4028 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4029 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4031 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4032 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4033 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4035 if (gatt_success == status && state_connected == newstate) // le connected
4037 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4043 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4046 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4048 if (CA_STATUS_OK != res)
4050 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4051 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4054 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4056 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4059 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4060 if (CA_STATUS_OK != res)
4062 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4066 res = CALEClientDiscoverServices(env, gatt);
4067 if (CA_STATUS_OK != res)
4069 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4073 else if (state_disconnected == newstate) // le disconnected
4075 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4078 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4082 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4085 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4086 STATE_DISCONNECTED);
4087 if (CA_STATUS_OK != res)
4089 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4090 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4093 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4095 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4098 CAResult_t res = CALEClientGattClose(env, gatt);
4099 if (CA_STATUS_OK != res)
4101 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4104 if (GATT_ERROR == status)
4106 // when we get GATT ERROR(0x85), gatt connection can be called again.
4107 OIC_LOG(INFO, TAG, "retry gatt connect");
4109 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4112 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4116 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4119 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4123 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4126 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4134 if (CALECheckConnectionStateValue(status))
4136 // this state is unexpected reason to disconnect
4137 // if the reason is suitable, connection logic of the device will be destroyed.
4138 OIC_LOG(INFO, TAG, "connection logic destroy");
4143 // other reason except for gatt_success is expected to running
4144 // background connection in BT platform.
4145 OIC_LOG(INFO, TAG, "unknown state or manual disconnected state");
4146 CALEClientUpdateSendCnt(env);
4153 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4154 g_sendBuffer = NULL;
4162 CALEClientSendFinish(env, gatt);
4167 * Class: org_iotivity_ca_jar_caleinterface
4168 * Method: CALeGattServicesDiscoveredCallback
4169 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4171 JNIEXPORT void JNICALL
4172 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4177 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4178 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4179 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4180 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4182 if (0 != status) // discovery error
4184 CALEClientSendFinish(env, gatt);
4188 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4191 CALEClientSendFinish(env, gatt);
4195 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4198 CALEClientSendFinish(env, gatt);
4202 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4205 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4209 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4210 if (!jni_obj_GattCharacteristic)
4212 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4216 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4217 jni_obj_GattCharacteristic);
4218 if (CA_STATUS_OK != res)
4220 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4224 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4225 if (CA_STATUS_OK != res)
4227 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4229 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE ,
4230 STATE_SERVICE_CONNECTED);
4231 if (CA_STATUS_OK != res)
4233 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4239 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4240 if (CA_STATUS_OK != res)
4242 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4248 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4249 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4254 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4255 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4256 CALEClientSendFinish(env, gatt);
4261 * Class: org_iotivity_ca_jar_caleinterface
4262 * Method: CALeGattCharacteristicWritjclasseCallback
4263 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4265 JNIEXPORT void JNICALL
4266 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4267 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4270 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4271 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4272 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4273 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4275 // send success & signal
4276 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4282 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4288 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4289 if (gatt_success != status) // error case
4291 OIC_LOG(ERROR, TAG, "send failure");
4294 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4295 if (CA_STATUS_OK != res)
4297 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4298 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4299 g_isSignalSetFlag = true;
4300 ca_cond_signal(g_threadWriteCharacteristicCond);
4301 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4303 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4305 if (CA_STATUS_OK != res)
4307 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4310 if (g_clientErrorCallback)
4312 jint length = (*env)->GetArrayLength(env, data);
4313 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4316 CALEClientSendFinish(env, gatt);
4322 OIC_LOG(DEBUG, TAG, "send success");
4323 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4324 STATE_SEND_SUCCESS);
4325 if (CA_STATUS_OK != res)
4327 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4330 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4331 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4332 g_isSignalSetFlag = true;
4333 ca_cond_signal(g_threadWriteCharacteristicCond);
4334 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4336 CALEClientUpdateSendCnt(env);
4339 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4345 CALEClientSendFinish(env, gatt);
4350 * Class: org_iotivity_ca_jar_caleinterface
4351 * Method: CALeGattCharacteristicChangedCallback
4352 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4354 JNIEXPORT void JNICALL
4355 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4356 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4358 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4359 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4360 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4361 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4362 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4364 // get Byte Array and convert to uint8_t*
4365 jint length = (*env)->GetArrayLength(env, data);
4368 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4370 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4371 jni_byte_responseData);
4373 uint8_t* receivedData = OICMalloc(length);
4376 OIC_LOG(ERROR, TAG, "receivedData is null");
4380 memcpy(receivedData, jni_byte_responseData, length);
4381 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4383 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4386 OIC_LOG(ERROR, TAG, "jni_address is null");
4387 OICFree(receivedData);
4391 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4394 OIC_LOG(ERROR, TAG, "address is null");
4395 OICFree(receivedData);
4399 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4400 receivedData, length);
4402 ca_mutex_lock(g_bleServerBDAddressMutex);
4403 uint32_t sentLength = 0;
4404 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4406 ca_mutex_unlock(g_bleServerBDAddressMutex);
4408 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4412 * Class: org_iotivity_ca_jar_caleinterface
4413 * Method: CALeGattDescriptorWriteCallback
4414 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4416 JNIEXPORT void JNICALL
4417 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4421 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4422 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4423 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4424 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4426 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4427 if (gatt_success != status) // error
4432 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4438 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4441 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4442 STATE_SERVICE_CONNECTED);
4443 if (CA_STATUS_OK != res)
4445 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4446 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4450 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4454 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4455 if (CA_STATUS_OK != res)
4457 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4466 CALEClientSendFinish(env, gatt);