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_isStartedMulticastServer = false;
72 static bool g_isStartedScan = false;
74 static jbyteArray g_sendBuffer = NULL;
75 static uint32_t g_targetCnt = 0;
76 static uint32_t g_currentSentCnt = 0;
77 static bool g_isFinishedSendData = false;
78 static ca_mutex g_SendFinishMutex = NULL;
79 static ca_mutex g_threadMutex = NULL;
80 static ca_cond g_threadCond = NULL;
81 static ca_cond g_deviceDescCond = NULL;
83 static ca_mutex g_threadSendMutex = NULL;
84 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
85 static ca_cond g_threadWriteCharacteristicCond = NULL;
86 static bool g_isSignalSetFlag = false;
88 static ca_mutex g_bleReqRespClientCbMutex = NULL;
89 static ca_mutex g_bleServerBDAddressMutex = NULL;
91 static ca_mutex g_deviceListMutex = NULL;
92 static ca_mutex g_gattObjectMutex = NULL;
93 static ca_mutex g_deviceStateListMutex = NULL;
95 static ca_mutex g_scanMutex = NULL;
97 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
99 static jboolean g_autoConnectFlag = JNI_FALSE;
102 * check if retry logic for connection routine has to be stopped or not.
103 * in case of error value including this method, connection routine has to be stopped.
104 * since there is no retry logic for this error reason in this client.
105 * @param state constant value of bluetoothgatt.
106 * @return true - waiting for background connection in BT platform.
107 * false - connection routine has to be stopped.
109 static bool CALECheckConnectionStateValue(jint state)
113 case GATT_CONNECTION_PRIORITY_BALANCED:
115 case GATT_INSUFFICIENT_AUTHENTICATION:
116 case GATT_INSUFFICIENT_ENCRYPTION:
117 case GATT_INVALID_ATTRIBUTE_LENGTH:
118 case GATT_INVALID_OFFSET:
119 case GATT_READ_NOT_PERMITTED:
120 case GATT_REQUEST_NOT_SUPPORTED:
121 case GATT_WRITE_NOT_PERMITTED:
128 void CALEClientJniInit()
130 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
131 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
134 void CALEClientJNISetContext()
136 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
137 g_context = (jobject) CANativeJNIGetContext();
140 CAResult_t CALECreateJniInterfaceObject()
142 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
146 OIC_LOG(ERROR, TAG, "g_context is null");
147 return CA_STATUS_FAILED;
152 OIC_LOG(ERROR, TAG, "g_jvm is null");
153 return CA_STATUS_FAILED;
156 bool isAttached = false;
158 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
161 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
162 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
166 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
167 return CA_STATUS_FAILED;
172 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
173 if (!jni_LEInterface)
175 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
179 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
180 "(Landroid/content/Context;)V");
181 if (!LeInterfaceConstructorMethod)
183 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
187 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
188 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
192 (*g_jvm)->DetachCurrentThread(g_jvm);
201 (*g_jvm)->DetachCurrentThread(g_jvm);
204 return CA_STATUS_FAILED;
207 CAResult_t CALEClientInitialize()
209 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
215 OIC_LOG(ERROR, TAG, "g_jvm is null");
216 return CA_STATUS_FAILED;
219 bool isAttached = false;
221 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
224 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
225 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
229 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
230 return CA_STATUS_FAILED;
235 CAResult_t ret = CALECheckPlatformVersion(env, 18);
236 if (CA_STATUS_OK != ret)
238 OIC_LOG(ERROR, TAG, "it is not supported");
242 (*g_jvm)->DetachCurrentThread(g_jvm);
248 ret = CALEClientInitGattMutexVaraibles();
249 if (CA_STATUS_OK != ret)
251 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
252 CALEClientTerminateGattMutexVariables();
256 (*g_jvm)->DetachCurrentThread(g_jvm);
262 g_deviceDescCond = ca_cond_new();
264 // init mutex for send logic
265 g_threadCond = ca_cond_new();
266 g_threadWriteCharacteristicCond = ca_cond_new();
268 CALEClientCreateDeviceList();
269 CALEClientJNISetContext();
271 ret = CALEClientCreateUUIDList();
272 if (CA_STATUS_OK != ret)
274 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
278 (*g_jvm)->DetachCurrentThread(g_jvm);
284 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
285 if (CA_STATUS_OK != ret)
287 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
291 (*g_jvm)->DetachCurrentThread(g_jvm);
296 g_isStartedLEClient = true;
300 (*g_jvm)->DetachCurrentThread(g_jvm);
306 void CALEClientTerminate()
308 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
312 OIC_LOG(ERROR, TAG, "g_jvm is null");
316 bool isAttached = false;
318 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
321 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
322 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
326 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
332 if (g_leScanCallback)
334 (*env)->DeleteGlobalRef(env, g_leScanCallback);
337 if (g_leGattCallback)
339 (*env)->DeleteGlobalRef(env, g_leGattCallback);
344 (*env)->DeleteGlobalRef(env, g_sendBuffer);
349 (*env)->DeleteGlobalRef(env, g_uuidList);
352 CAResult_t ret = CALEClientRemoveAllDeviceState();
353 if (CA_STATUS_OK != ret)
355 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
358 ret = CALEClientRemoveAllScanDevices(env);
359 if (CA_STATUS_OK != ret)
361 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
364 ret = CALEClientRemoveAllGattObjs(env);
365 if (CA_STATUS_OK != ret)
367 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
370 g_isStartedMulticastServer = false;
371 CALEClientSetScanFlag(false);
372 CALEClientSetSendFinishFlag(false);
374 CALEClientTerminateGattMutexVariables();
375 CALEClientDestroyJniInterface();
377 ca_cond_free(g_deviceDescCond);
378 ca_cond_free(g_threadCond);
379 ca_cond_free(g_threadWriteCharacteristicCond);
381 g_deviceDescCond = NULL;
383 g_threadWriteCharacteristicCond = NULL;
384 g_isSignalSetFlag = false;
385 CALEClientSetAutoConnectFlag(JNI_FALSE);
389 (*g_jvm)->DetachCurrentThread(g_jvm);
393 CAResult_t CALEClientDestroyJniInterface()
395 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
399 OIC_LOG(ERROR, TAG, "g_jvm is null");
400 return CA_STATUS_FAILED;
403 bool isAttached = false;
405 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
408 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
409 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
413 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
414 return CA_STATUS_FAILED;
419 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
420 if (!jni_LeInterface)
422 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
426 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
427 "destroyLeInterface",
429 if (!jni_InterfaceDestroyMethod)
431 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
435 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
437 if ((*env)->ExceptionCheck(env))
439 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
440 (*env)->ExceptionDescribe(env);
441 (*env)->ExceptionClear(env);
445 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
449 (*g_jvm)->DetachCurrentThread(g_jvm);
458 (*g_jvm)->DetachCurrentThread(g_jvm);
461 return CA_STATUS_FAILED;
464 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
466 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
467 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
471 CAResult_t res = CALEClientDisconnect(env, gatt);
472 if (CA_STATUS_OK != res)
474 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
477 CALEClientUpdateSendCnt(env);
480 CAResult_t CALEClientSendUnicastMessage(const char* address,
482 const uint32_t dataLen)
484 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
485 VERIFY_NON_NULL(address, TAG, "address is null");
486 VERIFY_NON_NULL(data, TAG, "data is null");
488 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
491 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
492 const uint32_t dataLen)
494 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
495 VERIFY_NON_NULL(data, TAG, "data is null");
499 OIC_LOG(ERROR, TAG, "g_jvm is null");
500 return CA_STATUS_FAILED;
503 bool isAttached = false;
505 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
508 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
509 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
513 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
514 return CA_STATUS_FAILED;
519 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
520 if (CA_STATUS_OK != ret)
522 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
527 (*g_jvm)->DetachCurrentThread(g_jvm);
533 CAResult_t CALEClientStartUnicastServer(const char* address)
535 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
537 return CA_NOT_SUPPORTED;
540 CAResult_t CALEClientStartMulticastServer()
542 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
544 if (g_isStartedMulticastServer)
546 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
547 return CA_STATUS_FAILED;
552 OIC_LOG(ERROR, TAG, "g_jvm is null");
553 return CA_STATUS_FAILED;
556 bool isAttached = false;
558 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
561 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
562 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
566 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
567 return CA_STATUS_FAILED;
572 g_isStartedMulticastServer = true;
573 CAResult_t ret = CALEClientStartScan();
574 if (CA_STATUS_OK != ret)
576 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
581 (*g_jvm)->DetachCurrentThread(g_jvm);
587 void CALEClientStopUnicastServer()
589 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
592 void CALEClientStopMulticastServer()
594 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
595 g_isStartedMulticastServer = false;
596 CAResult_t res = CALEClientStopScan();
597 if (CA_STATUS_OK != res)
599 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
604 void CALEClientSetCallback(CAPacketReceiveCallback callback)
606 g_packetReceiveCallback = callback;
609 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
611 g_clientErrorCallback = callback;
614 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
616 VERIFY_NON_NULL(env, TAG, "env");
620 return CA_STATUS_FAILED;
623 if (0 == u_arraylist_length(g_deviceList) // multicast
624 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
626 // Wait for LE peripherals to be discovered.
628 // Number of times to wait for discovery to complete.
629 static size_t const RETRIES = 5;
631 static uint64_t const TIMEOUT =
632 2 * MICROSECS_PER_SEC; // Microseconds
634 bool devicesDiscovered = false;
635 for (size_t i = 0; i < RETRIES; ++i)
637 OIC_LOG(DEBUG, TAG, "waiting for target device");
638 if (ca_cond_wait_for(g_deviceDescCond,
640 TIMEOUT) == CA_WAIT_SUCCESS)
642 ca_mutex_lock(g_deviceListMutex);
643 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
644 ca_mutex_unlock(g_deviceListMutex);
646 if (0 < scannedDeviceLen)
648 if (!address // multicast
649 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
651 devicesDiscovered = true;
658 // time out for scanning devices
659 if (!devicesDiscovered)
661 return CA_STATUS_FAILED;
669 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
670 const uint32_t dataLen)
672 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
674 VERIFY_NON_NULL(address, TAG, "address is null");
675 VERIFY_NON_NULL(data, TAG, "data is null");
679 OIC_LOG(ERROR, TAG, "g_jvm is null");
680 return CA_STATUS_FAILED;
683 bool isAttached = false;
685 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
688 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
689 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
692 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
693 return CA_STATUS_FAILED;
698 ca_mutex_lock(g_threadSendMutex);
700 CALEClientSetSendFinishFlag(false);
702 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
703 if (CA_STATUS_OK != ret)
705 OIC_LOG(INFO, TAG, "there is no scanned device");
709 if (g_context && g_deviceList)
711 uint32_t length = u_arraylist_length(g_deviceList);
712 for (uint32_t index = 0; index < length; index++)
714 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
717 OIC_LOG(ERROR, TAG, "jarrayObj is null");
721 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
724 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
728 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
731 OIC_LOG(ERROR, TAG, "setAddress is null");
735 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
737 if (!strcmp(setAddress, address))
739 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
741 // connect to gatt server
742 ret = CALEClientStopScan();
743 if (CA_STATUS_OK != ret)
745 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
751 (*env)->DeleteGlobalRef(env, g_sendBuffer);
754 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
755 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
756 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
758 // Target device to send message is just one.
761 ret = CALEClientSendData(env, jarrayObj);
762 if (CA_STATUS_OK != ret)
764 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
768 OIC_LOG(INFO, TAG, "wake up");
771 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
775 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
777 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
778 // if there is no connection state.
779 ca_mutex_lock(g_threadMutex);
780 if (!g_isFinishedSendData)
782 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
783 ca_cond_wait(g_threadCond, g_threadMutex);
784 OIC_LOG(DEBUG, TAG, "the data was sent");
786 ca_mutex_unlock(g_threadMutex);
790 (*g_jvm)->DetachCurrentThread(g_jvm);
793 // start LE Scan again
794 ret = CALEClientStartScan();
795 if (CA_STATUS_OK != ret)
797 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
798 ca_mutex_unlock(g_threadSendMutex);
802 ca_mutex_unlock(g_threadSendMutex);
803 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
804 return CALECheckSendState(address);
809 // start LE Scan again
810 ret = CALEClientStartScan();
811 if (CA_STATUS_OK != ret)
813 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
814 ca_mutex_unlock(g_threadSendMutex);
817 (*g_jvm)->DetachCurrentThread(g_jvm);
824 (*g_jvm)->DetachCurrentThread(g_jvm);
827 if (g_clientErrorCallback)
829 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
831 ca_mutex_unlock(g_threadSendMutex);
832 return CA_SEND_FAILED;
835 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
836 const uint32_t dataLen)
838 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
839 VERIFY_NON_NULL(data, TAG, "data is null");
840 VERIFY_NON_NULL(env, TAG, "env is null");
844 OIC_LOG(ERROR, TAG, "g_deviceList is null");
845 return CA_STATUS_FAILED;
848 ca_mutex_lock(g_threadSendMutex);
850 CALEClientSetSendFinishFlag(false);
852 OIC_LOG(DEBUG, TAG, "set byteArray for data");
855 (*env)->DeleteGlobalRef(env, g_sendBuffer);
859 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
860 if (CA_STATUS_OK != res)
862 OIC_LOG(INFO, TAG, "there is no scanned device");
866 // connect to gatt server
867 res = CALEClientStopScan();
868 if (CA_STATUS_OK != res)
870 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
871 ca_mutex_unlock(g_threadSendMutex);
874 uint32_t length = u_arraylist_length(g_deviceList);
875 g_targetCnt = length;
877 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
878 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
879 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
881 for (uint32_t index = 0; index < length; index++)
883 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
886 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
890 res = CALEClientSendData(env, jarrayObj);
891 if (res != CA_STATUS_OK)
893 OIC_LOG(ERROR, TAG, "BT device - send has failed");
896 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
899 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
903 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
906 OIC_LOG(ERROR, TAG, "address is not available");
910 (*env)->ReleaseStringUTFChars(env, jni_address, address);
913 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
915 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
916 ca_mutex_lock(g_threadMutex);
917 if (!g_isFinishedSendData)
919 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
920 ca_cond_wait(g_threadCond, g_threadMutex);
921 OIC_LOG(DEBUG, TAG, "the data was sent");
923 ca_mutex_unlock(g_threadMutex);
925 // start LE Scan again
926 res = CALEClientStartScan();
927 if (CA_STATUS_OK != res)
929 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
930 ca_mutex_unlock(g_threadSendMutex);
934 ca_mutex_unlock(g_threadSendMutex);
935 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
939 res = CALEClientStartScan();
940 if (CA_STATUS_OK != res)
942 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
943 ca_mutex_unlock(g_threadSendMutex);
947 ca_mutex_unlock(g_threadSendMutex);
948 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
949 return CA_SEND_FAILED;
952 CAResult_t CALECheckSendState(const char* address)
954 VERIFY_NON_NULL(address, TAG, "address is null");
956 ca_mutex_lock(g_deviceStateListMutex);
957 CALEState_t* state = CALEClientGetStateInfo(address);
960 OIC_LOG(ERROR, TAG, "state is null");
961 ca_mutex_unlock(g_deviceStateListMutex);
962 return CA_SEND_FAILED;
965 if (STATE_SEND_SUCCESS != state->sendState)
967 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
968 ca_mutex_unlock(g_deviceStateListMutex);
969 return CA_SEND_FAILED;
972 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
973 ca_mutex_unlock(g_deviceStateListMutex);
977 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
979 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
980 VERIFY_NON_NULL(device, TAG, "device is null");
981 VERIFY_NON_NULL(env, TAG, "env is null");
983 // get BLE address from bluetooth device object.
984 char* address = NULL;
985 CALEState_t* state = NULL;
986 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
989 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
990 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
993 OIC_LOG(ERROR, TAG, "address is not available");
994 return CA_STATUS_FAILED;
996 ca_mutex_lock(g_deviceStateListMutex);
997 state = CALEClientGetStateInfo(address);
998 ca_mutex_unlock(g_deviceStateListMutex);
999 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1004 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1006 // cancel previous connection request before connection
1007 // if there is gatt object in g_gattObjectList.
1010 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1013 OIC_LOG(ERROR, TAG, "address is not available");
1014 return CA_STATUS_FAILED;
1017 jobject gatt = CALEClientGetGattObjInList(env, address);
1020 CAResult_t res = CALEClientDisconnect(env, gatt);
1021 if (CA_STATUS_OK != res)
1023 OIC_LOG(INFO, TAG, "there is no gatt object");
1026 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1029 // connection request
1030 jobject newGatt = CALEClientConnect(env, device, CALEClientGetAutoConnectFlag());
1031 if (NULL == newGatt)
1033 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1034 return CA_STATUS_FAILED;
1039 if (STATE_CONNECTED == state->connectedState)
1041 OIC_LOG(INFO, TAG, "GATT has already connected");
1044 OIC_LOG(ERROR, TAG, "jni_address is not available");
1045 return CA_STATUS_FAILED;
1048 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1051 OIC_LOG(ERROR, TAG, "address is not available");
1052 return CA_STATUS_FAILED;
1055 jobject gatt = CALEClientGetGattObjInList(env, address);
1058 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1059 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1060 return CA_STATUS_FAILED;
1063 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1064 if (CA_STATUS_OK != ret)
1066 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1067 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1070 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1074 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1076 // cancel previous connection request before connection
1077 // if there is gatt object in g_gattObjectList.
1080 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1083 OIC_LOG(ERROR, TAG, "address is not available");
1084 return CA_STATUS_FAILED;
1087 jobject gatt = CALEClientGetGattObjInList(env, address);
1090 CAResult_t res = CALEClientDisconnect(env, gatt);
1091 if (CA_STATUS_OK != res)
1093 OIC_LOG(INFO, TAG, "there is no gatt object");
1096 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1099 OIC_LOG(DEBUG, TAG, "start to connect LE");
1100 jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
1103 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1104 return CA_STATUS_FAILED;
1109 return CA_STATUS_OK;
1112 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1114 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1115 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1117 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1118 if (!jni_cid_gattdevice_list)
1120 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1124 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1125 "()Landroid/bluetooth/BluetoothDevice;");
1126 if (!jni_mid_getDevice)
1128 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1132 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1133 if (!jni_obj_device)
1135 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1139 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1142 OIC_LOG(ERROR, TAG, "jni_address is null");
1152 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1155 OIC_LOG(DEBUG, TAG, "Gatt Close");
1156 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1157 VERIFY_NON_NULL(env, TAG, "env is null");
1159 // get BluetoothGatt class
1160 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1161 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1162 if (!jni_cid_BluetoothGatt)
1164 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1165 return CA_STATUS_FAILED;
1168 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1169 if (!jni_mid_closeGatt)
1171 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1172 return CA_STATUS_OK;
1175 // call disconnect gatt method
1176 OIC_LOG(DEBUG, TAG, "request to close GATT");
1177 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1179 if ((*env)->ExceptionCheck(env))
1181 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1182 (*env)->ExceptionDescribe(env);
1183 (*env)->ExceptionClear(env);
1184 return CA_STATUS_FAILED;
1187 return CA_STATUS_OK;
1190 CAResult_t CALEClientStartScan()
1192 if (!g_isStartedMulticastServer)
1194 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1195 return CA_STATUS_FAILED;
1198 if (!g_isStartedLEClient)
1200 OIC_LOG(ERROR, TAG, "LE client is not started");
1201 return CA_STATUS_FAILED;
1206 OIC_LOG(ERROR, TAG, "g_jvm is null");
1207 return CA_STATUS_FAILED;
1210 if (g_isStartedScan)
1212 OIC_LOG(INFO, TAG, "scanning is already started");
1213 return CA_STATUS_OK;
1216 bool isAttached = false;
1218 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1221 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1223 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1226 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1227 return CA_STATUS_FAILED;
1232 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1234 CAResult_t ret = CA_STATUS_OK;
1235 // scan gatt server with UUID
1236 if (g_leScanCallback && g_uuidList)
1239 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1241 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1243 if (CA_STATUS_OK != ret)
1245 if (CA_ADAPTER_NOT_ENABLED == ret)
1247 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1251 OIC_LOG(ERROR, TAG, "start scan has failed");
1258 (*g_jvm)->DetachCurrentThread(g_jvm);
1264 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1266 VERIFY_NON_NULL(callback, TAG, "callback is null");
1267 VERIFY_NON_NULL(env, TAG, "env is null");
1269 if (!CALEIsEnableBTAdapter(env))
1271 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1272 return CA_ADAPTER_NOT_ENABLED;
1275 // get default bt adapter class
1276 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1277 if (!jni_cid_BTAdapter)
1279 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1280 return CA_STATUS_FAILED;
1283 // get remote bt adapter method
1284 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1285 "getDefaultAdapter",
1286 METHODID_OBJECTNONPARAM);
1287 if (!jni_mid_getDefaultAdapter)
1289 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1290 return CA_STATUS_FAILED;
1293 // get start le scan method
1294 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1295 "(Landroid/bluetooth/BluetoothAdapter$"
1296 "LeScanCallback;)Z");
1297 if (!jni_mid_startLeScan)
1299 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1300 return CA_STATUS_FAILED;
1303 // gat bt adapter object
1304 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1305 jni_mid_getDefaultAdapter);
1306 if (!jni_obj_BTAdapter)
1308 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1309 return CA_STATUS_FAILED;
1312 // call start le scan method
1313 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1314 jni_mid_startLeScan, callback);
1315 if (!jni_obj_startLeScan)
1317 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1318 return CA_STATUS_FAILED;
1322 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1323 CALEClientSetScanFlag(true);
1326 return CA_STATUS_OK;
1329 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1331 VERIFY_NON_NULL(callback, TAG, "callback is null");
1332 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1333 VERIFY_NON_NULL(env, TAG, "env is null");
1335 if (!CALEIsEnableBTAdapter(env))
1337 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1338 return CA_ADAPTER_NOT_ENABLED;
1341 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1342 if (!jni_cid_BTAdapter)
1344 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1345 return CA_STATUS_FAILED;
1348 // get remote bt adapter method
1349 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1350 "getDefaultAdapter",
1351 METHODID_OBJECTNONPARAM);
1352 if (!jni_mid_getDefaultAdapter)
1354 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1355 return CA_STATUS_FAILED;
1358 // get start le scan method
1359 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1360 "([Ljava/util/UUID;Landroid/bluetooth/"
1361 "BluetoothAdapter$LeScanCallback;)Z");
1362 if (!jni_mid_startLeScan)
1364 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1365 return CA_STATUS_FAILED;
1368 // get bt adapter object
1369 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1370 jni_mid_getDefaultAdapter);
1371 if (!jni_obj_BTAdapter)
1373 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1374 return CA_STATUS_FAILED;
1377 // call start le scan method
1378 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1379 jni_mid_startLeScan, uuids, callback);
1380 if (!jni_obj_startLeScan)
1382 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1383 return CA_STATUS_FAILED;
1387 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1388 CALEClientSetScanFlag(true);
1391 return CA_STATUS_OK;
1394 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1396 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1397 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1400 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1403 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1407 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1408 "(Ljava/lang/String;)"
1409 "Ljava/util/UUID;");
1410 if (!jni_mid_fromString)
1412 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1416 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1417 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1421 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1425 return jni_obj_uuid;
1428 CAResult_t CALEClientStopScan()
1432 OIC_LOG(ERROR, TAG, "g_jvm is null");
1433 return CA_STATUS_FAILED;
1436 if (!g_isStartedScan)
1438 OIC_LOG(INFO, TAG, "scanning is already stopped");
1439 return CA_STATUS_OK;
1442 bool isAttached = false;
1444 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1447 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1448 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1451 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1452 return CA_STATUS_FAILED;
1457 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1458 if (CA_STATUS_OK != ret)
1460 if (CA_ADAPTER_NOT_ENABLED == ret)
1462 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1466 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1471 CALEClientSetScanFlag(false);
1476 (*g_jvm)->DetachCurrentThread(g_jvm);
1482 void CALEClientSetScanFlag(bool flag)
1484 ca_mutex_lock(g_scanMutex);
1485 g_isStartedScan = flag;
1486 ca_mutex_unlock(g_scanMutex);
1489 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1491 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1492 VERIFY_NON_NULL(callback, TAG, "callback is null");
1493 VERIFY_NON_NULL(env, TAG, "env is null");
1495 if (!CALEIsEnableBTAdapter(env))
1497 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1498 return CA_ADAPTER_NOT_ENABLED;
1501 // get default bt adapter class
1502 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1503 if (!jni_cid_BTAdapter)
1505 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1506 return CA_STATUS_FAILED;
1509 // get remote bt adapter method
1510 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1511 "getDefaultAdapter",
1512 METHODID_OBJECTNONPARAM);
1513 if (!jni_mid_getDefaultAdapter)
1515 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1516 return CA_STATUS_FAILED;
1519 // get start le scan method
1520 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1521 "(Landroid/bluetooth/"
1522 "BluetoothAdapter$LeScanCallback;)V");
1523 if (!jni_mid_stopLeScan)
1525 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1526 return CA_STATUS_FAILED;
1529 // gat bt adapter object
1530 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1531 jni_mid_getDefaultAdapter);
1532 if (!jni_obj_BTAdapter)
1534 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1535 return CA_STATUS_FAILED;
1538 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1539 // call start le scan method
1540 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1541 if ((*env)->ExceptionCheck(env))
1543 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1544 (*env)->ExceptionDescribe(env);
1545 (*env)->ExceptionClear(env);
1546 return CA_STATUS_FAILED;
1549 return CA_STATUS_OK;
1552 void CALEClientSetAutoConnectFlag(jboolean flag)
1554 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1555 g_autoConnectFlag = flag;
1558 jboolean CALEClientGetAutoConnectFlag()
1560 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", g_autoConnectFlag);
1561 return g_autoConnectFlag;
1564 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1566 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1567 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1568 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1570 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1571 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1574 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1577 OIC_LOG(ERROR, TAG, "address is not available");
1581 // close the gatt service
1582 jobject gatt = CALEClientGetGattObjInList(env, address);
1585 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1586 if (CA_STATUS_OK != res)
1588 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1589 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1593 // clean previous gatt object after close profile service
1594 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1595 if (CA_STATUS_OK != res)
1597 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1598 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1602 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1605 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1608 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1612 // add new gatt object into g_gattObjectList
1613 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1614 if (CA_STATUS_OK != res)
1616 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1623 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1625 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1626 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1627 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1629 if (!CALEIsEnableBTAdapter(env))
1631 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1635 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1638 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1642 // get BluetoothDevice class
1643 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1644 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1645 if (!jni_cid_BluetoothDevice)
1647 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1651 // get connectGatt method
1652 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1653 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1654 "(Landroid/content/Context;ZLandroid/"
1655 "bluetooth/BluetoothGattCallback;)"
1656 "Landroid/bluetooth/BluetoothGatt;");
1657 if (!jni_mid_connectGatt)
1659 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1663 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1664 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1665 jni_mid_connectGatt,
1667 autoconnect, g_leGattCallback);
1668 if (!jni_obj_connectGatt)
1670 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1671 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1672 CALEClientUpdateSendCnt(env);
1677 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1679 return jni_obj_connectGatt;
1682 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1684 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1686 VERIFY_NON_NULL(env, TAG, "env is null");
1687 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1689 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1690 if (!jni_cid_BTAdapter)
1692 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1693 return CA_STATUS_FAILED;
1696 // get remote bt adapter method
1697 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1698 "getDefaultAdapter",
1699 METHODID_OBJECTNONPARAM);
1700 if (!jni_mid_getDefaultAdapter)
1702 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1703 return CA_STATUS_FAILED;
1706 // gat bt adapter object
1707 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1708 jni_mid_getDefaultAdapter);
1709 if (!jni_obj_BTAdapter)
1711 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1712 return CA_STATUS_FAILED;
1715 // get closeProfileProxy method
1716 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1717 "closeProfileProxy",
1718 "(ILandroid/bluetooth/"
1719 "BluetoothProfile;)V");
1720 if (!jni_mid_closeProfileProxy)
1722 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1723 return CA_STATUS_FAILED;
1726 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1727 if (!jni_cid_BTProfile)
1729 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1730 return CA_STATUS_FAILED;
1733 // GATT - Constant value : 7 (0x00000007)
1734 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1738 OIC_LOG(ERROR, TAG, "id_gatt is null");
1739 return CA_STATUS_FAILED;
1742 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1744 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1745 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1746 if ((*env)->ExceptionCheck(env))
1748 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1749 (*env)->ExceptionDescribe(env);
1750 (*env)->ExceptionClear(env);
1751 return CA_STATUS_FAILED;
1754 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1755 return CA_STATUS_OK;
1759 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1761 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1762 VERIFY_NON_NULL(env, TAG, "env is null");
1763 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1765 // get BluetoothGatt class
1766 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1767 if (!jni_cid_BluetoothGatt)
1769 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1770 return CA_STATUS_FAILED;
1773 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1774 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1775 "disconnect", "()V");
1776 if (!jni_mid_disconnectGatt)
1778 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1779 return CA_STATUS_FAILED;
1782 // call disconnect gatt method
1783 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1784 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1785 if ((*env)->ExceptionCheck(env))
1787 OIC_LOG(ERROR, TAG, "disconnect has failed");
1788 (*env)->ExceptionDescribe(env);
1789 (*env)->ExceptionClear(env);
1790 return CA_STATUS_FAILED;
1793 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1795 return CA_STATUS_OK;
1798 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1800 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1801 VERIFY_NON_NULL(env, TAG, "env is null");
1803 if (!g_gattObjectList)
1805 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1806 return CA_STATUS_OK;
1809 uint32_t length = u_arraylist_length(g_gattObjectList);
1810 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1811 for (uint32_t index = 0; index < length; index++)
1813 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1814 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1817 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1820 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1821 if (CA_STATUS_OK != res)
1823 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1828 return CA_STATUS_OK;
1831 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1833 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1834 VERIFY_NON_NULL(env, TAG, "env is null");
1836 if (!g_gattObjectList)
1838 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1839 return CA_STATUS_OK;
1842 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1845 OIC_LOG(ERROR, TAG, "address is null");
1846 return CA_STATUS_FAILED;
1849 uint32_t length = u_arraylist_length(g_gattObjectList);
1850 for (uint32_t index = 0; index < length; index++)
1852 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1855 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1859 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1860 if (!jni_setAddress)
1862 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1863 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1864 return CA_STATUS_FAILED;
1867 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1870 OIC_LOG(ERROR, TAG, "setAddress is null");
1871 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1872 return CA_STATUS_FAILED;
1875 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1876 if (!strcmp(address, setAddress))
1878 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1879 if (CA_STATUS_OK != res)
1881 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1882 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1883 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1884 return CA_STATUS_FAILED;
1886 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1887 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1888 return CA_STATUS_OK;
1890 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1892 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1894 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1895 return CA_STATUS_OK;
1898 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1900 VERIFY_NON_NULL(env, TAG, "env is null");
1901 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1903 if (!CALEIsEnableBTAdapter(env))
1905 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1906 return CA_ADAPTER_NOT_ENABLED;
1909 // get BluetoothGatt class
1910 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1911 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1912 if (!jni_cid_BluetoothGatt)
1914 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1915 return CA_STATUS_FAILED;
1918 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1919 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1920 "discoverServices", "()Z");
1921 if (!jni_mid_discoverServices)
1923 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1924 return CA_STATUS_FAILED;
1926 // call disconnect gatt method
1927 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1928 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1931 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1932 return CA_STATUS_FAILED;
1935 return CA_STATUS_OK;
1938 static void CALEWriteCharacteristicThread(void* object)
1940 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1942 bool isAttached = false;
1944 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1947 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1948 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1952 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1958 jobject gatt = (jobject)object;
1959 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1960 if (CA_STATUS_OK != ret)
1962 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1967 (*g_jvm)->DetachCurrentThread(g_jvm);
1971 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1973 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1974 VERIFY_NON_NULL(env, TAG, "env is null");
1977 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1978 if (!jni_obj_character)
1980 CALEClientSendFinish(env, gatt);
1981 return CA_STATUS_FAILED;
1984 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1985 if (CA_STATUS_OK != ret)
1987 CALEClientSendFinish(env, gatt);
1988 return CA_STATUS_FAILED;
1991 // wait for callback for write Characteristic with success to sent data
1992 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1993 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1994 if (!g_isSignalSetFlag)
1996 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1997 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
1998 g_threadWriteCharacteristicMutex,
1999 WAIT_TIME_WRITE_CHARACTERISTIC))
2001 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2002 g_isSignalSetFlag = false;
2003 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2004 return CA_STATUS_FAILED;
2007 // reset flag set by writeCharacteristic Callback
2008 g_isSignalSetFlag = false;
2009 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2011 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2012 return CA_STATUS_OK;
2015 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2017 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2018 VERIFY_NON_NULL(env, TAG, "env is null");
2019 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2021 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2022 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2023 CALEWriteCharacteristicThread, (void*)gattParam))
2025 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2026 return CA_STATUS_FAILED;
2029 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2030 return CA_STATUS_OK;
2033 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2034 jobject gattCharacteristic)
2036 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2037 VERIFY_NON_NULL(env, TAG, "env is null");
2038 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2039 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2041 if (!CALEIsEnableBTAdapter(env))
2043 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2044 return CA_STATUS_FAILED;
2047 // get BluetoothGatt class
2048 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2049 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2050 if (!jni_cid_BluetoothGatt)
2052 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2053 return CA_STATUS_FAILED;
2056 OIC_LOG(DEBUG, TAG, "write characteristic method");
2057 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2058 "writeCharacteristic",
2059 "(Landroid/bluetooth/"
2060 "BluetoothGattCharacteristic;)Z");
2061 if (!jni_mid_writeCharacteristic)
2063 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2064 return CA_STATUS_FAILED;
2067 // call disconnect gatt method
2068 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2069 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2070 jni_mid_writeCharacteristic,
2071 gattCharacteristic);
2074 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2078 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2079 return CA_STATUS_FAILED;
2082 return CA_STATUS_OK;
2085 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2087 VERIFY_NON_NULL(env, TAG, "env is null");
2088 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2090 if (!CALEIsEnableBTAdapter(env))
2092 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2093 return CA_STATUS_FAILED;
2096 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2097 if (!jni_cid_BluetoothGatt)
2099 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2100 return CA_STATUS_FAILED;
2103 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2106 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2107 return CA_STATUS_FAILED;
2110 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2111 if (!jni_obj_GattCharacteristic)
2113 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2114 return CA_STATUS_FAILED;
2117 OIC_LOG(DEBUG, TAG, "read characteristic method");
2118 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2119 "readCharacteristic",
2120 "(Landroid/bluetooth/"
2121 "BluetoothGattCharacteristic;)Z");
2122 if (!jni_mid_readCharacteristic)
2124 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2125 return CA_STATUS_FAILED;
2128 // call disconnect gatt method
2129 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2130 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2131 jni_obj_GattCharacteristic);
2134 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2138 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2139 return CA_STATUS_FAILED;
2142 return CA_STATUS_OK;
2145 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2146 jobject characteristic)
2148 VERIFY_NON_NULL(env, TAG, "env is null");
2149 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2150 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2152 if (!CALEIsEnableBTAdapter(env))
2154 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2155 return CA_ADAPTER_NOT_ENABLED;
2158 // get BluetoothGatt class
2159 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2160 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2161 if (!jni_cid_BluetoothGatt)
2163 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2164 return CA_STATUS_FAILED;
2167 // set Characteristic Notification
2168 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2169 "setCharacteristicNotification",
2170 "(Landroid/bluetooth/"
2171 "BluetoothGattCharacteristic;Z)Z");
2172 if (!jni_mid_setNotification)
2174 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2175 return CA_STATUS_FAILED;
2178 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2179 characteristic, JNI_TRUE);
2180 if (JNI_TRUE == ret)
2182 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2186 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2187 return CA_STATUS_FAILED;
2190 return CA_STATUS_OK;
2193 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2195 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2196 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2197 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2199 if (!CALEIsEnableBTAdapter(env))
2201 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2205 // get BluetoothGatt class
2206 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2207 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2208 if (!jni_cid_BluetoothGatt)
2210 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2214 jmethodID jni_mid_getService = (*env)->GetMethodID(
2215 env, jni_cid_BluetoothGatt, "getService",
2216 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2217 if (!jni_mid_getService)
2219 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2223 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2224 if (!jni_obj_service_uuid)
2226 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2230 // get bluetooth gatt service
2231 OIC_LOG(DEBUG, TAG, "request to get service");
2232 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2233 jni_obj_service_uuid);
2234 if (!jni_obj_gattService)
2236 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2240 // get bluetooth gatt service class
2241 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2242 env, "android/bluetooth/BluetoothGattService");
2243 if (!jni_cid_BluetoothGattService)
2245 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2249 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2250 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2251 "getCharacteristic",
2252 "(Ljava/util/UUID;)"
2253 "Landroid/bluetooth/"
2254 "BluetoothGattCharacteristic;");
2255 if (!jni_mid_getCharacteristic)
2257 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2261 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2264 OIC_LOG(ERROR, TAG, "uuid is null");
2268 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2269 if (!jni_obj_tx_uuid)
2271 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2272 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2276 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2277 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2278 jni_mid_getCharacteristic,
2281 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2282 return jni_obj_GattCharacteristic;
2285 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2287 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2288 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2289 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2290 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2292 if (!CALEIsEnableBTAdapter(env))
2294 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2298 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2301 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2305 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2306 if (!jni_obj_GattCharacteristic)
2308 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2312 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2313 "/BluetoothGattCharacteristic");
2314 if (!jni_cid_BTGattCharacteristic)
2316 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2320 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2321 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2323 if (!jni_mid_setValue)
2325 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2329 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2331 if (JNI_TRUE == ret)
2333 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2337 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2342 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2343 "setWriteType", "(I)V");
2344 if (!jni_mid_setWriteType)
2346 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2350 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2351 "WRITE_TYPE_NO_RESPONSE", "I");
2352 if (!jni_fid_no_response)
2354 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2358 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2359 jni_fid_no_response);
2361 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2363 return jni_obj_GattCharacteristic;
2366 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2368 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2369 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2371 if (!CALEIsEnableBTAdapter(env))
2373 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2377 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2378 "BluetoothGattCharacteristic");
2379 if (!jni_cid_BTGattCharacteristic)
2381 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2385 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2386 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2388 if (!jni_mid_getValue)
2390 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2394 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2396 return jni_obj_data_array;
2399 CAResult_t CALEClientCreateUUIDList()
2403 OIC_LOG(ERROR, TAG, "g_jvm is null");
2404 return CA_STATUS_FAILED;
2407 bool isAttached = false;
2409 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2412 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2413 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2417 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2418 return CA_STATUS_FAILED;
2423 // create new object array
2424 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2425 if (!jni_cid_uuid_list)
2427 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2431 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2432 jni_cid_uuid_list, NULL);
2433 if (!jni_obj_uuid_list)
2435 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2440 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2443 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2446 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2448 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2452 (*g_jvm)->DetachCurrentThread(g_jvm);
2455 return CA_STATUS_OK;
2462 (*g_jvm)->DetachCurrentThread(g_jvm);
2464 return CA_STATUS_FAILED;
2467 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2468 jobject characteristic)
2470 VERIFY_NON_NULL(env, TAG, "env is null");
2471 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2472 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2474 if (!CALEIsEnableBTAdapter(env))
2476 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2477 return CA_ADAPTER_NOT_ENABLED;
2480 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2481 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2482 "BluetoothGattCharacteristic");
2483 if (!jni_cid_BTGattCharacteristic)
2485 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2486 return CA_STATUS_FAILED;
2489 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2490 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2492 "(Ljava/util/UUID;)Landroid/bluetooth/"
2493 "BluetoothGattDescriptor;");
2494 if (!jni_mid_getDescriptor)
2496 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2497 return CA_STATUS_FAILED;
2500 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2501 if (!jni_obj_cc_uuid)
2503 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2504 return CA_STATUS_FAILED;
2507 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2508 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2509 jni_mid_getDescriptor, jni_obj_cc_uuid);
2510 if (!jni_obj_descriptor)
2512 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2513 return CA_NOT_SUPPORTED;
2516 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2517 jclass jni_cid_descriptor = (*env)->FindClass(env,
2518 "android/bluetooth/BluetoothGattDescriptor");
2519 if (!jni_cid_descriptor)
2521 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2522 return CA_STATUS_FAILED;
2525 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2526 if (!jni_mid_setValue)
2528 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2529 return CA_STATUS_FAILED;
2532 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2533 "ENABLE_NOTIFICATION_VALUE", "[B");
2534 if (!jni_fid_NotiValue)
2536 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2537 return CA_STATUS_FAILED;
2540 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2542 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2543 env, jni_obj_descriptor, jni_mid_setValue,
2544 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2547 OIC_LOG(DEBUG, TAG, "setValue success");
2551 OIC_LOG(ERROR, TAG, "setValue has failed");
2552 return CA_STATUS_FAILED;
2555 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2558 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2559 return CA_STATUS_FAILED;
2562 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2563 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2564 "(Landroid/bluetooth/"
2565 "BluetoothGattDescriptor;)Z");
2566 if (!jni_mid_writeDescriptor)
2568 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2569 return CA_STATUS_FAILED;
2572 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2573 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2574 jni_obj_descriptor);
2577 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2581 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2582 return CA_STATUS_FAILED;
2585 return CA_STATUS_OK;
2588 void CALEClientCreateScanDeviceList(JNIEnv *env)
2590 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2591 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2593 ca_mutex_lock(g_deviceListMutex);
2594 // create new object array
2595 if (g_deviceList == NULL)
2597 OIC_LOG(DEBUG, TAG, "Create device list");
2599 g_deviceList = u_arraylist_create();
2601 ca_mutex_unlock(g_deviceListMutex);
2604 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2606 VERIFY_NON_NULL(device, TAG, "device is null");
2607 VERIFY_NON_NULL(env, TAG, "env is null");
2609 ca_mutex_lock(g_deviceListMutex);
2613 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2614 ca_mutex_unlock(g_deviceListMutex);
2615 return CA_STATUS_FAILED;
2618 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2619 if (!jni_remoteAddress)
2621 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2622 ca_mutex_unlock(g_deviceListMutex);
2623 return CA_STATUS_FAILED;
2626 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2629 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2630 ca_mutex_unlock(g_deviceListMutex);
2631 return CA_STATUS_FAILED;
2634 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2636 jobject gdevice = (*env)->NewGlobalRef(env, device);
2637 u_arraylist_add(g_deviceList, gdevice);
2638 ca_cond_signal(g_deviceDescCond);
2639 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2641 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2643 ca_mutex_unlock(g_deviceListMutex);
2645 return CA_STATUS_OK;
2648 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2650 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2651 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2655 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2659 uint32_t length = u_arraylist_length(g_deviceList);
2660 for (uint32_t index = 0; index < length; index++)
2662 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2665 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2669 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2670 if (!jni_setAddress)
2672 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2676 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2679 OIC_LOG(ERROR, TAG, "setAddress is null");
2683 if (!strcmp(remoteAddress, setAddress))
2685 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2689 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2692 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2697 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2699 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2700 VERIFY_NON_NULL(env, TAG, "env is null");
2702 ca_mutex_lock(g_deviceListMutex);
2706 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2707 ca_mutex_unlock(g_deviceListMutex);
2708 return CA_STATUS_FAILED;
2711 uint32_t length = u_arraylist_length(g_deviceList);
2712 for (uint32_t index = 0; index < length; index++)
2714 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2717 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2720 (*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);
2785 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2786 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2788 if (NULL == u_arraylist_remove(g_deviceList, index))
2790 OIC_LOG(ERROR, TAG, "List removal failed.");
2791 ca_mutex_unlock(g_deviceListMutex);
2792 return CA_STATUS_FAILED;
2794 ca_mutex_unlock(g_deviceListMutex);
2795 return CA_STATUS_OK;
2797 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2798 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2801 ca_mutex_unlock(g_deviceListMutex);
2802 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2804 return CA_STATUS_OK;
2811 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2813 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2814 VERIFY_NON_NULL(env, TAG, "env is null");
2815 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2817 ca_mutex_lock(g_gattObjectMutex);
2819 if (!g_gattObjectList)
2821 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2822 ca_mutex_unlock(g_gattObjectMutex);
2823 return CA_STATUS_FAILED;
2826 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2827 if (!jni_remoteAddress)
2829 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2830 ca_mutex_unlock(g_gattObjectMutex);
2831 return CA_STATUS_FAILED;
2834 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2837 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2838 ca_mutex_unlock(g_gattObjectMutex);
2839 return CA_STATUS_FAILED;
2842 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2843 if (!CALEClientIsGattObjInList(env, remoteAddress))
2845 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2846 u_arraylist_add(g_gattObjectList, newGatt);
2847 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2850 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2851 ca_mutex_unlock(g_gattObjectMutex);
2852 return CA_STATUS_OK;
2855 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2857 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2858 VERIFY_NON_NULL(env, TAG, "env is null");
2859 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2861 uint32_t length = u_arraylist_length(g_gattObjectList);
2862 for (uint32_t index = 0; index < length; index++)
2865 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2868 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2872 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2873 if (!jni_setAddress)
2875 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2879 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2882 OIC_LOG(ERROR, TAG, "setAddress is null");
2886 if (!strcmp(remoteAddress, setAddress))
2888 OIC_LOG(DEBUG, TAG, "the device is already set");
2889 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2894 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2899 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2903 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2905 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2906 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2907 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2909 ca_mutex_lock(g_gattObjectMutex);
2910 uint32_t length = u_arraylist_length(g_gattObjectList);
2911 for (uint32_t index = 0; index < length; index++)
2913 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2916 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2917 ca_mutex_unlock(g_gattObjectMutex);
2921 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2922 if (!jni_setAddress)
2924 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2925 ca_mutex_unlock(g_gattObjectMutex);
2929 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2932 OIC_LOG(ERROR, TAG, "setAddress is null");
2933 ca_mutex_unlock(g_gattObjectMutex);
2937 if (!strcmp(remoteAddress, setAddress))
2939 OIC_LOG(DEBUG, TAG, "the device is already set");
2940 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2941 ca_mutex_unlock(g_gattObjectMutex);
2944 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2947 ca_mutex_unlock(g_gattObjectMutex);
2948 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2952 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2954 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2955 VERIFY_NON_NULL(env, TAG, "env is null");
2957 ca_mutex_lock(g_gattObjectMutex);
2958 if (!g_gattObjectList)
2960 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2961 ca_mutex_unlock(g_gattObjectMutex);
2962 return CA_STATUS_OK;
2965 uint32_t length = u_arraylist_length(g_gattObjectList);
2966 for (uint32_t index = 0; index < length; index++)
2968 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2971 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2974 (*env)->DeleteGlobalRef(env, jarrayObj);
2977 OICFree(g_gattObjectList);
2978 g_gattObjectList = NULL;
2979 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2980 ca_mutex_unlock(g_gattObjectMutex);
2981 return CA_STATUS_OK;
2984 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2986 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2987 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2988 VERIFY_NON_NULL(env, TAG, "env is null");
2990 ca_mutex_lock(g_gattObjectMutex);
2991 if (!g_gattObjectList)
2993 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2994 ca_mutex_unlock(g_gattObjectMutex);
2995 return CA_STATUS_OK;
2998 uint32_t length = u_arraylist_length(g_gattObjectList);
2999 for (uint32_t index = 0; index < length; index++)
3001 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3004 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3005 ca_mutex_unlock(g_gattObjectMutex);
3006 return CA_STATUS_FAILED;
3009 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3010 if (!jni_setAddress)
3012 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3013 ca_mutex_unlock(g_gattObjectMutex);
3014 return CA_STATUS_FAILED;
3017 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3020 OIC_LOG(ERROR, TAG, "setAddress is null");
3021 ca_mutex_unlock(g_gattObjectMutex);
3022 return CA_STATUS_FAILED;
3025 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3026 if (!jni_remoteAddress)
3028 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3029 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3030 ca_mutex_unlock(g_gattObjectMutex);
3031 return CA_STATUS_FAILED;
3034 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3037 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3038 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3039 ca_mutex_unlock(g_gattObjectMutex);
3040 return CA_STATUS_FAILED;
3043 if (!strcmp(setAddress, remoteAddress))
3045 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3046 (*env)->DeleteGlobalRef(env, jarrayObj);
3047 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3048 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3050 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3052 OIC_LOG(ERROR, TAG, "List removal failed.");
3053 ca_mutex_unlock(g_gattObjectMutex);
3054 return CA_STATUS_FAILED;
3056 ca_mutex_unlock(g_gattObjectMutex);
3057 return CA_STATUS_OK;
3059 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3060 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3063 ca_mutex_unlock(g_gattObjectMutex);
3064 OIC_LOG(DEBUG, TAG, "there are no target object");
3065 return CA_STATUS_OK;
3068 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3070 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3071 VERIFY_NON_NULL(addr, TAG, "addr is null");
3072 VERIFY_NON_NULL(env, TAG, "env is null");
3074 ca_mutex_lock(g_gattObjectMutex);
3075 if (!g_gattObjectList)
3077 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3078 ca_mutex_unlock(g_gattObjectMutex);
3079 return CA_STATUS_OK;
3082 uint32_t length = u_arraylist_length(g_gattObjectList);
3083 for (uint32_t index = 0; index < length; index++)
3085 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3088 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3089 ca_mutex_unlock(g_gattObjectMutex);
3090 return CA_STATUS_FAILED;
3093 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3094 if (!jni_setAddress)
3096 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3097 ca_mutex_unlock(g_gattObjectMutex);
3098 return CA_STATUS_FAILED;
3101 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3104 OIC_LOG(ERROR, TAG, "setAddress is null");
3105 ca_mutex_unlock(g_gattObjectMutex);
3106 return CA_STATUS_FAILED;
3109 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3112 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3113 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3114 ca_mutex_unlock(g_gattObjectMutex);
3115 return CA_STATUS_FAILED;
3118 if (!strcmp(setAddress, remoteAddress))
3120 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3121 (*env)->DeleteGlobalRef(env, jarrayObj);
3123 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3124 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3125 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3127 OIC_LOG(ERROR, TAG, "List removal failed.");
3128 ca_mutex_unlock(g_gattObjectMutex);
3129 return CA_STATUS_FAILED;
3131 ca_mutex_unlock(g_gattObjectMutex);
3132 return CA_STATUS_OK;
3134 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3135 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3138 ca_mutex_unlock(g_gattObjectMutex);
3139 OIC_LOG(DEBUG, TAG, "there are no target object");
3140 return CA_STATUS_FAILED;
3143 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3145 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3147 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3148 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3150 // get Bluetooth Address
3151 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3152 if (!jni_btTargetAddress)
3154 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3158 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3161 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3165 // get method ID of getDevice()
3166 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3167 if (!jni_cid_gattdevice_list)
3169 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3170 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3174 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3175 METHODID_BT_DEVICE);
3176 if (!jni_mid_getDevice)
3178 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3179 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3183 size_t length = u_arraylist_length(g_gattObjectList);
3184 for (size_t index = 0; index < length; index++)
3186 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3189 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3190 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3194 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3195 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3196 if (!jni_obj_device)
3198 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3199 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3203 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3206 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3207 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3211 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3214 OIC_LOG(ERROR, TAG, "btAddress is not available");
3215 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3219 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3220 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3221 if (!strcmp(targetAddress, btAddress))
3223 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3226 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3229 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3231 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3232 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3233 (*env)->DeleteLocalRef(env, jni_btAddress);
3234 (*env)->DeleteLocalRef(env, jni_obj_device);
3235 return jni_LEAddress;
3237 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3238 (*env)->DeleteLocalRef(env, jni_btAddress);
3239 (*env)->DeleteLocalRef(env, jni_obj_device);
3242 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3250 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3251 uint16_t notificationState, uint16_t sendState)
3253 VERIFY_NON_NULL(address, TAG, "address is null");
3255 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3258 OIC_LOG(ERROR, TAG, "out of memory");
3259 return CA_MEMORY_ALLOC_FAILED;
3262 if (strlen(address) > CA_MACADDR_SIZE)
3264 OIC_LOG(ERROR, TAG, "address is not proper");
3266 return CA_STATUS_FAILED;
3269 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3270 newstate->connectedState = connectedState;
3271 newstate->notificationState = notificationState;
3272 newstate->sendState = sendState;
3273 return CALEClientAddDeviceStateToList(newstate);
3276 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3278 VERIFY_NON_NULL(state, TAG, "state is null");
3280 ca_mutex_lock(g_deviceStateListMutex);
3282 if (!g_deviceStateList)
3284 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3285 ca_mutex_unlock(g_deviceStateListMutex);
3286 return CA_STATUS_FAILED;
3289 if (CALEClientIsDeviceInList(state->address))
3291 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3294 OIC_LOG(ERROR, TAG, "curState is null");
3295 ca_mutex_unlock(g_deviceStateListMutex);
3296 return CA_STATUS_FAILED;
3299 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3301 state->notificationState = curState->notificationState;
3304 // delete previous state for update new state
3305 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3306 if (CA_STATUS_OK != res)
3308 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3309 ca_mutex_unlock(g_deviceStateListMutex);
3313 u_arraylist_add(g_deviceStateList, state); // update new state
3314 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3315 state->connectedState, state->notificationState, state->address);
3317 ca_mutex_unlock(g_deviceStateListMutex);
3318 return CA_STATUS_OK;
3321 bool CALEClientIsDeviceInList(const char* remoteAddress)
3323 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3325 if (!g_deviceStateList)
3327 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3331 uint32_t length = u_arraylist_length(g_deviceStateList);
3332 for (uint32_t index = 0; index < length; index++)
3334 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3337 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3341 if (!strcmp(remoteAddress, state->address))
3343 OIC_LOG(DEBUG, TAG, "the device is already set");
3352 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3356 CAResult_t CALEClientRemoveAllDeviceState()
3358 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3360 ca_mutex_lock(g_deviceStateListMutex);
3361 if (!g_deviceStateList)
3363 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3364 ca_mutex_unlock(g_deviceStateListMutex);
3365 return CA_STATUS_FAILED;
3368 uint32_t length = u_arraylist_length(g_deviceStateList);
3369 for (uint32_t index = 0; index < length; index++)
3371 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3374 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3380 OICFree(g_deviceStateList);
3381 g_deviceStateList = NULL;
3382 ca_mutex_unlock(g_deviceStateListMutex);
3384 return CA_STATUS_OK;
3387 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3389 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3390 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3392 if (!g_deviceStateList)
3394 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3395 return CA_STATUS_FAILED;
3398 uint32_t length = u_arraylist_length(g_deviceStateList);
3399 for (uint32_t index = 0; index < length; index++)
3401 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3404 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3408 if (!strcmp(state->address, remoteAddress))
3410 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3412 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3414 if (NULL == targetState)
3416 OIC_LOG(ERROR, TAG, "List removal failed.");
3417 return CA_STATUS_FAILED;
3420 OICFree(targetState);
3421 return CA_STATUS_OK;
3425 return CA_STATUS_OK;
3428 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3430 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3431 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3433 if (!g_deviceStateList)
3435 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3439 uint32_t length = u_arraylist_length(g_deviceStateList);
3440 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3442 for (uint32_t index = 0; index < length; index++)
3444 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3447 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3451 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3452 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3454 if (!strcmp(state->address, remoteAddress))
3456 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3463 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3465 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3466 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3468 ca_mutex_lock(g_deviceStateListMutex);
3469 if (!g_deviceStateList)
3471 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3472 ca_mutex_unlock(g_deviceStateListMutex);
3476 uint32_t length = u_arraylist_length(g_deviceStateList);
3477 for (uint32_t index = 0; index < length; index++)
3479 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3482 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3486 if (!strcmp(state->address, remoteAddress))
3488 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3490 if (STATE_CONNECTED == state->connectedState)
3492 ca_mutex_unlock(g_deviceStateListMutex);
3497 ca_mutex_unlock(g_deviceStateListMutex);
3502 ca_mutex_unlock(g_deviceStateListMutex);
3506 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3508 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3509 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3511 ca_mutex_lock(g_deviceStateListMutex);
3512 if (!g_deviceStateList)
3514 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3515 ca_mutex_unlock(g_deviceStateListMutex);
3519 uint32_t length = u_arraylist_length(g_deviceStateList);
3520 for (uint32_t index = 0; index < length; index++)
3522 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3525 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3529 if (!strcmp(state->address, remoteAddress))
3531 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3533 if (STATE_CHARACTER_SET == state->notificationState)
3535 ca_mutex_unlock(g_deviceStateListMutex);
3540 ca_mutex_unlock(g_deviceStateListMutex);
3546 ca_mutex_unlock(g_deviceStateListMutex);
3550 void CALEClientCreateDeviceList()
3552 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3554 // create new object array
3555 if (!g_gattObjectList)
3557 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3559 g_gattObjectList = u_arraylist_create();
3562 if (!g_deviceStateList)
3564 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3566 g_deviceStateList = u_arraylist_create();
3571 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3573 g_deviceList = u_arraylist_create();
3578 * Check Sent Count for remove g_sendBuffer
3580 void CALEClientUpdateSendCnt(JNIEnv *env)
3582 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3584 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3586 ca_mutex_lock(g_threadMutex);
3590 if (g_targetCnt <= g_currentSentCnt)
3593 g_currentSentCnt = 0;
3597 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3598 g_sendBuffer = NULL;
3600 // notity the thread
3601 ca_cond_signal(g_threadCond);
3603 CALEClientSetSendFinishFlag(true);
3604 OIC_LOG(DEBUG, TAG, "set signal for send data");
3607 ca_mutex_unlock(g_threadMutex);
3610 CAResult_t CALEClientInitGattMutexVaraibles()
3612 if (NULL == g_bleReqRespClientCbMutex)
3614 g_bleReqRespClientCbMutex = ca_mutex_new();
3615 if (NULL == g_bleReqRespClientCbMutex)
3617 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3618 return CA_STATUS_FAILED;
3622 if (NULL == g_bleServerBDAddressMutex)
3624 g_bleServerBDAddressMutex = ca_mutex_new();
3625 if (NULL == g_bleServerBDAddressMutex)
3627 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3628 return CA_STATUS_FAILED;
3632 if (NULL == g_threadMutex)
3634 g_threadMutex = ca_mutex_new();
3635 if (NULL == g_threadMutex)
3637 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3638 return CA_STATUS_FAILED;
3642 if (NULL == g_threadSendMutex)
3644 g_threadSendMutex = ca_mutex_new();
3645 if (NULL == g_threadSendMutex)
3647 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3648 return CA_STATUS_FAILED;
3652 if (NULL == g_deviceListMutex)
3654 g_deviceListMutex = ca_mutex_new();
3655 if (NULL == g_deviceListMutex)
3657 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3658 return CA_STATUS_FAILED;
3662 if (NULL == g_gattObjectMutex)
3664 g_gattObjectMutex = ca_mutex_new();
3665 if (NULL == g_gattObjectMutex)
3667 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3668 return CA_STATUS_FAILED;
3672 if (NULL == g_deviceStateListMutex)
3674 g_deviceStateListMutex = ca_mutex_new();
3675 if (NULL == g_deviceStateListMutex)
3677 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3678 return CA_STATUS_FAILED;
3682 if (NULL == g_SendFinishMutex)
3684 g_SendFinishMutex = ca_mutex_new();
3685 if (NULL == g_SendFinishMutex)
3687 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3688 return CA_STATUS_FAILED;
3692 if (NULL == g_scanMutex)
3694 g_scanMutex = ca_mutex_new();
3695 if (NULL == g_scanMutex)
3697 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3698 return CA_STATUS_FAILED;
3702 if (NULL == g_threadWriteCharacteristicMutex)
3704 g_threadWriteCharacteristicMutex = ca_mutex_new();
3705 if (NULL == g_threadWriteCharacteristicMutex)
3707 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3708 return CA_STATUS_FAILED;
3712 return CA_STATUS_OK;
3715 void CALEClientTerminateGattMutexVariables()
3717 ca_mutex_free(g_bleReqRespClientCbMutex);
3718 g_bleReqRespClientCbMutex = NULL;
3720 ca_mutex_free(g_bleServerBDAddressMutex);
3721 g_bleServerBDAddressMutex = NULL;
3723 ca_mutex_free(g_threadMutex);
3724 g_threadMutex = NULL;
3726 ca_mutex_free(g_threadSendMutex);
3727 g_threadSendMutex = NULL;
3729 ca_mutex_free(g_deviceListMutex);
3730 g_deviceListMutex = NULL;
3732 ca_mutex_free(g_SendFinishMutex);
3733 g_SendFinishMutex = NULL;
3735 ca_mutex_free(g_scanMutex);
3738 ca_mutex_free(g_threadWriteCharacteristicMutex);
3739 g_threadWriteCharacteristicMutex = NULL;
3742 void CALEClientSetSendFinishFlag(bool flag)
3744 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3746 ca_mutex_lock(g_SendFinishMutex);
3747 g_isFinishedSendData = flag;
3748 ca_mutex_unlock(g_SendFinishMutex);
3755 CAResult_t CAStartLEGattClient()
3757 CAResult_t res = CALEClientStartMulticastServer();
3758 if (CA_STATUS_OK != res)
3760 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3764 g_isStartedLEClient = true;
3770 void CAStopLEGattClient()
3772 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3776 OIC_LOG(ERROR, TAG, "g_jvm is null");
3780 bool isAttached = false;
3782 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3785 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3786 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3790 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3796 CAResult_t ret = CALEClientDisconnectAll(env);
3797 if (CA_STATUS_OK != ret)
3799 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3802 ret = CALEClientStopScan();
3803 if(CA_STATUS_OK != ret)
3805 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3808 ca_mutex_lock(g_threadMutex);
3809 ca_cond_signal(g_threadCond);
3810 ca_mutex_unlock(g_threadMutex);
3812 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3813 ca_cond_signal(g_threadWriteCharacteristicCond);
3814 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3818 (*g_jvm)->DetachCurrentThread(g_jvm);
3823 CAResult_t CAInitializeLEGattClient()
3825 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3826 CALEClientInitialize();
3827 return CA_STATUS_OK;
3830 void CATerminateLEGattClient()
3832 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3833 CAStopLEGattClient();
3834 CALEClientTerminate();
3837 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3838 uint32_t dataLen, CALETransferType_t type,
3841 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3842 VERIFY_NON_NULL(data, TAG, "data is null");
3843 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3845 if (LE_UNICAST != type || position < 0)
3847 OIC_LOG(ERROR, TAG, "this request is not unicast");
3848 return CA_STATUS_INVALID_PARAM;
3851 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3854 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3856 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3857 VERIFY_NON_NULL(data, TAG, "data is null");
3859 return CALEClientSendMulticastMessage(data, dataLen);
3862 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3864 ca_mutex_lock(g_bleReqRespClientCbMutex);
3865 g_CABLEClientDataReceivedCallback = callback;
3866 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3869 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3871 g_threadPoolHandle = handle;
3874 CAResult_t CAGetLEAddress(char **local_address)
3876 VERIFY_NON_NULL(local_address, TAG, "local_address");
3877 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3878 return CA_NOT_SUPPORTED;
3881 JNIEXPORT void JNICALL
3882 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3885 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3886 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3887 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3888 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3890 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3893 JNIEXPORT void JNICALL
3894 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3897 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3898 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3899 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3900 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3902 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3905 JNIEXPORT void JNICALL
3906 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3909 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3910 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3911 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3913 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3914 if (CA_STATUS_OK != res)
3916 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3920 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
3922 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
3924 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3925 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
3927 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3928 if (!jni_cid_gattdevice_list)
3930 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3934 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3935 METHODID_BT_DEVICE);
3936 if (!jni_mid_getDevice)
3938 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3942 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
3943 if (!jni_obj_device)
3945 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3949 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
3952 OIC_LOG(ERROR, TAG, "jni_address is null");
3956 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
3961 * Class: org_iotivity_ca_jar_caleinterface
3962 * Method: CALeGattConnectionStateChangeCallback
3963 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3965 JNIEXPORT void JNICALL
3966 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3972 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3974 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3975 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3976 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3978 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
3979 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
3980 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
3982 if (gatt_success == status && state_connected == newstate) // le connected
3984 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3990 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3993 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3994 STATE_CHARACTER_NO_CHANGE,
3996 if (CA_STATUS_OK != res)
3998 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3999 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4002 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4004 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4007 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4008 if (CA_STATUS_OK != res)
4010 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4014 res = CALEClientDiscoverServices(env, gatt);
4015 if (CA_STATUS_OK != res)
4017 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4021 else if (state_disconnected == newstate) // le disconnected
4023 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4026 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4030 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4033 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4034 STATE_CHARACTER_UNSET,
4036 if (CA_STATUS_OK != res)
4038 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4039 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4042 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4044 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4047 CAResult_t res = CALEClientGattClose(env, gatt);
4048 if (CA_STATUS_OK != res)
4050 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4053 if (gatt_success == status)
4055 // that state is a general reason to disconnect BLE.
4056 // its means manual disconnected message from BT platform.
4057 // in this case Scanning has to start again and clean previous data.
4058 CAResult_t res = CALEClientStartScan();
4059 if (CA_STATUS_OK != res)
4061 if (CA_ADAPTER_NOT_ENABLED == res)
4063 // scan will be started with start server when adapter is enabled
4064 OIC_LOG(INFO, TAG, "Adapter was disabled");
4068 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4073 else if (GATT_ERROR == status)
4075 // when we get GATT ERROR(0x85), gatt connection can be called again.
4076 OIC_LOG(INFO, TAG, "retry gatt connect");
4078 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4081 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4085 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4088 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4092 jobject newGatt = CALEClientConnect(env, btObject, CALEClientGetAutoConnectFlag());
4095 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4102 if (CALECheckConnectionStateValue(status))
4104 // this state is unexpected reason to disconnect
4105 // if the reason is suitable, connection logic of the device will be destroyed.
4106 OIC_LOG(INFO, TAG, "connection logic destroy");
4111 // other reason is expected to running background connection in BT platform.
4112 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4113 CALEClientUpdateSendCnt(env);
4120 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4121 g_sendBuffer = NULL;
4129 CALEClientSendFinish(env, gatt);
4134 * Class: org_iotivity_ca_jar_caleinterface
4135 * Method: CALeGattServicesDiscoveredCallback
4136 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4138 JNIEXPORT void JNICALL
4139 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4144 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4145 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4146 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4147 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4149 if (0 != status) // discovery error
4151 CALEClientSendFinish(env, gatt);
4155 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4158 CALEClientSendFinish(env, gatt);
4162 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4165 CALEClientSendFinish(env, gatt);
4169 if (!CALEClientIsSetCharacteristic(address))
4171 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4174 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4178 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4179 if (!jni_obj_GattCharacteristic)
4181 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4185 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4186 jni_obj_GattCharacteristic);
4187 if (CA_STATUS_OK != res)
4189 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4193 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4194 if (CA_STATUS_OK != res)
4196 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4199 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4200 if (CA_STATUS_OK != res)
4202 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4208 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4210 if (CA_STATUS_OK != res)
4212 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4220 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4221 if (CA_STATUS_OK != res)
4223 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4228 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4229 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4234 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4235 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4236 CALEClientSendFinish(env, gatt);
4241 * Class: org_iotivity_ca_jar_caleinterface
4242 * Method: CALeGattCharacteristicWritjclasseCallback
4243 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4245 JNIEXPORT void JNICALL
4246 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4247 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4250 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4251 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4252 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4253 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4255 // send success & signal
4256 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4262 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4268 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4269 if (gatt_success != status) // error case
4271 OIC_LOG(ERROR, TAG, "send failure");
4274 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4275 if (CA_STATUS_OK != res)
4277 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4278 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4279 g_isSignalSetFlag = true;
4280 ca_cond_signal(g_threadWriteCharacteristicCond);
4281 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4283 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4284 STATE_CHARACTER_SET,
4286 if (CA_STATUS_OK != res)
4288 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4291 if (g_clientErrorCallback)
4293 jint length = (*env)->GetArrayLength(env, data);
4294 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4297 CALEClientSendFinish(env, gatt);
4303 OIC_LOG(DEBUG, TAG, "send success");
4304 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4305 STATE_SEND_SUCCESS);
4306 if (CA_STATUS_OK != res)
4308 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4311 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4312 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4313 g_isSignalSetFlag = true;
4314 ca_cond_signal(g_threadWriteCharacteristicCond);
4315 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4317 CALEClientUpdateSendCnt(env);
4320 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4326 CALEClientSendFinish(env, gatt);
4331 * Class: org_iotivity_ca_jar_caleinterface
4332 * Method: CALeGattCharacteristicChangedCallback
4333 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4335 JNIEXPORT void JNICALL
4336 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4337 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4339 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4340 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4341 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4342 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4343 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4345 // get Byte Array and convert to uint8_t*
4346 jint length = (*env)->GetArrayLength(env, data);
4349 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4351 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4352 jni_byte_responseData);
4354 uint8_t* receivedData = OICMalloc(length);
4357 OIC_LOG(ERROR, TAG, "receivedData is null");
4361 memcpy(receivedData, jni_byte_responseData, length);
4362 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4364 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4367 OIC_LOG(ERROR, TAG, "jni_address is null");
4368 OICFree(receivedData);
4372 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4375 OIC_LOG(ERROR, TAG, "address is null");
4376 OICFree(receivedData);
4380 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4381 receivedData, length);
4383 ca_mutex_lock(g_bleServerBDAddressMutex);
4384 uint32_t sentLength = 0;
4385 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4387 ca_mutex_unlock(g_bleServerBDAddressMutex);
4389 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4393 * Class: org_iotivity_ca_jar_caleinterface
4394 * Method: CALeGattDescriptorWriteCallback
4395 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4397 JNIEXPORT void JNICALL
4398 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4402 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4403 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4404 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4405 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4407 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4408 if (gatt_success != status) // error
4415 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4416 if (CA_STATUS_OK != res)
4418 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4427 CALEClientSendFinish(env, gatt);