1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define GATT_CONNECTION_PRIORITY_BALANCED 0
46 #define GATT_FAILURE 257
47 #define GATT_INSUFFICIENT_AUTHENTICATION 5
48 #define GATT_INSUFFICIENT_ENCRYPTION 15
49 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
50 #define GATT_INVALID_OFFSET 7
51 #define GATT_READ_NOT_PERMITTED 2
52 #define GATT_REQUEST_NOT_SUPPORTED 6
53 #define GATT_WRITE_NOT_PERMITTED 3
55 static ca_thread_pool_t g_threadPoolHandle = NULL;
58 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
59 static u_arraylist_t *g_gattObjectList = NULL;
60 static u_arraylist_t *g_deviceStateList = NULL;
62 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
63 static CABLEErrorHandleCallback g_clientErrorCallback;
64 static jobject g_leScanCallback = NULL;
65 static jobject g_leGattCallback = NULL;
66 static jobject g_context = NULL;
67 static jobjectArray g_uuidList = NULL;
69 // it will be prevent to start send logic when adapter has stopped.
70 static bool g_isStartedLEClient = false;
71 static bool g_isStartedScan = false;
73 static jbyteArray g_sendBuffer = NULL;
74 static uint32_t g_targetCnt = 0;
75 static uint32_t g_currentSentCnt = 0;
76 static bool g_isFinishedSendData = false;
77 static ca_mutex g_SendFinishMutex = NULL;
78 static ca_mutex g_threadMutex = NULL;
79 static ca_cond g_threadCond = NULL;
80 static ca_cond g_deviceDescCond = NULL;
82 static ca_mutex g_threadSendMutex = NULL;
83 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
84 static ca_cond g_threadWriteCharacteristicCond = NULL;
85 static bool g_isSignalSetFlag = false;
87 static ca_mutex g_bleReqRespClientCbMutex = NULL;
88 static ca_mutex g_bleServerBDAddressMutex = NULL;
90 static ca_mutex g_deviceListMutex = NULL;
91 static ca_mutex g_gattObjectMutex = NULL;
92 static ca_mutex g_deviceStateListMutex = NULL;
94 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
95 static ca_cond g_deviceScanRetryDelayCond = NULL;
97 static ca_mutex g_scanMutex = NULL;
99 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
102 * check if retry logic for connection routine has to be stopped or not.
103 * in case of error value including this method, connection routine has to be stopped.
104 * since there is no retry logic for this error reason in this client.
105 * @param state constant value of bluetoothgatt.
106 * @return true - waiting for background connection in BT platform.
107 * false - connection routine has to be stopped.
109 static bool CALECheckConnectionStateValue(jint state)
113 case GATT_CONNECTION_PRIORITY_BALANCED:
115 case GATT_INSUFFICIENT_AUTHENTICATION:
116 case GATT_INSUFFICIENT_ENCRYPTION:
117 case GATT_INVALID_ATTRIBUTE_LENGTH:
118 case GATT_INVALID_OFFSET:
119 case GATT_READ_NOT_PERMITTED:
120 case GATT_REQUEST_NOT_SUPPORTED:
121 case GATT_WRITE_NOT_PERMITTED:
128 void CALEClientJniInit()
130 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
131 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
134 void CALEClientJNISetContext()
136 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
137 g_context = (jobject) CANativeJNIGetContext();
140 CAResult_t CALECreateJniInterfaceObject()
142 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
146 OIC_LOG(ERROR, TAG, "g_context is null");
147 return CA_STATUS_FAILED;
152 OIC_LOG(ERROR, TAG, "g_jvm is null");
153 return CA_STATUS_FAILED;
156 bool isAttached = false;
158 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
161 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
162 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
166 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
167 return CA_STATUS_FAILED;
172 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
173 if (!jni_LEInterface)
175 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
179 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
180 "(Landroid/content/Context;)V");
181 if (!LeInterfaceConstructorMethod)
183 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
187 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
188 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
192 (*g_jvm)->DetachCurrentThread(g_jvm);
201 (*g_jvm)->DetachCurrentThread(g_jvm);
204 return CA_STATUS_FAILED;
207 CAResult_t CALEClientInitialize()
209 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
215 OIC_LOG(ERROR, TAG, "g_jvm is null");
216 return CA_STATUS_FAILED;
219 bool isAttached = false;
221 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
224 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
225 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
229 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
230 return CA_STATUS_FAILED;
235 CAResult_t ret = CALECheckPlatformVersion(env, 18);
236 if (CA_STATUS_OK != ret)
238 OIC_LOG(ERROR, TAG, "it is not supported");
242 (*g_jvm)->DetachCurrentThread(g_jvm);
248 ret = CALEClientInitGattMutexVaraibles();
249 if (CA_STATUS_OK != ret)
251 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
252 CALEClientTerminateGattMutexVariables();
256 (*g_jvm)->DetachCurrentThread(g_jvm);
262 g_deviceDescCond = ca_cond_new();
264 // init mutex for send logic
265 g_threadCond = ca_cond_new();
266 g_threadWriteCharacteristicCond = ca_cond_new();
267 g_deviceScanRetryDelayCond = ca_cond_new();
269 CALEClientCreateDeviceList();
270 CALEClientJNISetContext();
272 ret = CALEClientCreateUUIDList();
273 if (CA_STATUS_OK != ret)
275 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
279 (*g_jvm)->DetachCurrentThread(g_jvm);
285 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
286 if (CA_STATUS_OK != ret)
288 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
292 (*g_jvm)->DetachCurrentThread(g_jvm);
297 g_isStartedLEClient = true;
301 (*g_jvm)->DetachCurrentThread(g_jvm);
307 void CALEClientTerminate()
309 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
313 OIC_LOG(ERROR, TAG, "g_jvm is null");
317 bool isAttached = false;
319 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
322 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
323 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
327 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
333 if (g_leScanCallback)
335 (*env)->DeleteGlobalRef(env, g_leScanCallback);
336 g_leScanCallback = NULL;
339 if (g_leGattCallback)
341 (*env)->DeleteGlobalRef(env, g_leGattCallback);
342 g_leGattCallback = NULL;
347 (*env)->DeleteGlobalRef(env, g_sendBuffer);
353 (*env)->DeleteGlobalRef(env, g_uuidList);
357 CAResult_t ret = CALEClientRemoveAllDeviceState();
358 if (CA_STATUS_OK != ret)
360 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
363 ret = CALEClientRemoveAllScanDevices(env);
364 if (CA_STATUS_OK != ret)
366 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
369 ret = CALEClientRemoveAllGattObjs(env);
370 if (CA_STATUS_OK != ret)
372 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
375 CALEClientSetScanFlag(false);
376 CALEClientSetSendFinishFlag(true);
378 CALEClientTerminateGattMutexVariables();
379 CALEClientDestroyJniInterface();
381 ca_cond_free(g_deviceDescCond);
382 ca_cond_free(g_threadCond);
383 ca_cond_free(g_threadWriteCharacteristicCond);
384 ca_cond_free(g_deviceScanRetryDelayCond);
386 g_deviceDescCond = NULL;
388 g_threadWriteCharacteristicCond = NULL;
389 g_deviceScanRetryDelayCond = NULL;
391 g_isSignalSetFlag = false;
395 (*g_jvm)->DetachCurrentThread(g_jvm);
399 CAResult_t CALEClientDestroyJniInterface()
401 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
405 OIC_LOG(ERROR, TAG, "g_jvm is null");
406 return CA_STATUS_FAILED;
409 bool isAttached = false;
411 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
414 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
415 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
419 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
420 return CA_STATUS_FAILED;
425 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
426 if (!jni_LeInterface)
428 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
432 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
433 "destroyLeInterface",
435 if (!jni_InterfaceDestroyMethod)
437 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
441 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
443 if ((*env)->ExceptionCheck(env))
445 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
446 (*env)->ExceptionDescribe(env);
447 (*env)->ExceptionClear(env);
451 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
455 (*g_jvm)->DetachCurrentThread(g_jvm);
464 (*g_jvm)->DetachCurrentThread(g_jvm);
467 return CA_STATUS_FAILED;
470 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
472 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
473 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
477 CAResult_t res = CALEClientDisconnect(env, gatt);
478 if (CA_STATUS_OK != res)
480 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
483 CALEClientUpdateSendCnt(env);
486 CAResult_t CALEClientSendUnicastMessage(const char* address,
488 const uint32_t dataLen)
490 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
491 VERIFY_NON_NULL(address, TAG, "address is null");
492 VERIFY_NON_NULL(data, TAG, "data is null");
494 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
497 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
498 const uint32_t dataLen)
500 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
501 VERIFY_NON_NULL(data, TAG, "data is null");
505 OIC_LOG(ERROR, TAG, "g_jvm is null");
506 return CA_STATUS_FAILED;
509 bool isAttached = false;
511 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
514 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
515 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
519 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
520 return CA_STATUS_FAILED;
525 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
526 if (CA_STATUS_OK != ret)
528 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
533 (*g_jvm)->DetachCurrentThread(g_jvm);
539 CAResult_t CALEClientStartUnicastServer(const char* address)
541 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
543 return CA_NOT_SUPPORTED;
546 CAResult_t CALEClientStartMulticastServer()
548 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
550 return CA_NOT_SUPPORTED;
553 void CALEClientStopUnicastServer()
555 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
558 void CALEClientStopMulticastServer()
560 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
563 void CALEClientSetCallback(CAPacketReceiveCallback callback)
565 g_packetReceiveCallback = callback;
568 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
570 g_clientErrorCallback = callback;
573 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
575 VERIFY_NON_NULL(env, TAG, "env");
579 return CA_STATUS_FAILED;
582 if (0 == u_arraylist_length(g_deviceList) // multicast
583 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
585 // Wait for LE peripherals to be discovered.
587 // Number of times to wait for discovery to complete.
588 static size_t const RETRIES = 5;
590 static uint64_t const TIMEOUT =
591 2 * MICROSECS_PER_SEC; // Microseconds
593 bool devicesDiscovered = false;
594 for (size_t i = 0; i < RETRIES; ++i)
596 OIC_LOG(DEBUG, TAG, "waiting for target device");
597 if (ca_cond_wait_for(g_deviceDescCond,
599 TIMEOUT) == CA_WAIT_SUCCESS)
601 ca_mutex_lock(g_deviceListMutex);
602 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
603 ca_mutex_unlock(g_deviceListMutex);
605 if (0 < scannedDeviceLen)
607 if (!address // multicast
608 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
610 devicesDiscovered = true;
617 OIC_LOG(INFO, TAG, "waiting..");
619 ca_mutex_lock(g_deviceScanRetryDelayMutex);
620 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
621 g_deviceScanRetryDelayMutex,
622 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
624 OIC_LOG(INFO, TAG, "finish to waiting for target device");
625 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
628 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
636 // time out for scanning devices
637 if (!devicesDiscovered)
639 return CA_STATUS_FAILED;
647 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
648 const uint32_t dataLen)
650 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
652 VERIFY_NON_NULL(address, TAG, "address is null");
653 VERIFY_NON_NULL(data, TAG, "data is null");
657 OIC_LOG(ERROR, TAG, "g_jvm is null");
658 return CA_STATUS_FAILED;
661 bool isAttached = false;
663 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
666 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
667 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
670 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
671 return CA_STATUS_FAILED;
676 ca_mutex_lock(g_threadSendMutex);
678 CALEClientSetSendFinishFlag(false);
680 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
681 if (CA_STATUS_OK != ret)
683 OIC_LOG(INFO, TAG, "there is no scanned device");
687 if (g_context && g_deviceList)
689 uint32_t length = u_arraylist_length(g_deviceList);
690 for (uint32_t index = 0; index < length; index++)
692 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
695 OIC_LOG(ERROR, TAG, "jarrayObj is null");
699 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
702 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
706 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
709 OIC_LOG(ERROR, TAG, "setAddress is null");
713 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
715 if (!strcmp(setAddress, address))
717 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
719 // connect to gatt server
720 ret = CALEClientStopScan();
721 if (CA_STATUS_OK != ret)
723 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
729 (*env)->DeleteGlobalRef(env, g_sendBuffer);
732 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
733 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
734 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
736 // Target device to send message is just one.
739 ret = CALEClientSendData(env, jarrayObj);
740 if (CA_STATUS_OK != ret)
742 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
746 OIC_LOG(INFO, TAG, "wake up");
749 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
753 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
755 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
756 // if there is no connection state.
757 ca_mutex_lock(g_threadMutex);
758 if (!g_isFinishedSendData)
760 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
761 ca_cond_wait(g_threadCond, g_threadMutex);
762 OIC_LOG(DEBUG, TAG, "the data was sent");
764 ca_mutex_unlock(g_threadMutex);
768 (*g_jvm)->DetachCurrentThread(g_jvm);
771 // start LE Scan again
772 ret = CALEClientStartScan();
773 if (CA_STATUS_OK != ret)
775 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
776 ca_mutex_unlock(g_threadSendMutex);
780 ca_mutex_unlock(g_threadSendMutex);
781 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
782 return CALECheckSendState(address);
787 // start LE Scan again
788 ret = CALEClientStartScan();
789 if (CA_STATUS_OK != ret)
791 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
792 ca_mutex_unlock(g_threadSendMutex);
795 (*g_jvm)->DetachCurrentThread(g_jvm);
802 (*g_jvm)->DetachCurrentThread(g_jvm);
805 if (g_clientErrorCallback)
807 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
809 ca_mutex_unlock(g_threadSendMutex);
810 return CA_SEND_FAILED;
813 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
814 const uint32_t dataLen)
816 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
817 VERIFY_NON_NULL(data, TAG, "data is null");
818 VERIFY_NON_NULL(env, TAG, "env is null");
822 OIC_LOG(ERROR, TAG, "g_deviceList is null");
823 return CA_STATUS_FAILED;
826 ca_mutex_lock(g_threadSendMutex);
828 CALEClientSetSendFinishFlag(false);
830 OIC_LOG(DEBUG, TAG, "set byteArray for data");
833 (*env)->DeleteGlobalRef(env, g_sendBuffer);
837 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
838 if (CA_STATUS_OK != res)
840 OIC_LOG(INFO, TAG, "there is no scanned device");
844 // connect to gatt server
845 res = CALEClientStopScan();
846 if (CA_STATUS_OK != res)
848 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
849 ca_mutex_unlock(g_threadSendMutex);
852 uint32_t length = u_arraylist_length(g_deviceList);
853 g_targetCnt = length;
855 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
856 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
857 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
859 for (uint32_t index = 0; index < length; index++)
861 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
864 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
868 res = CALEClientSendData(env, jarrayObj);
869 if (res != CA_STATUS_OK)
871 OIC_LOG(ERROR, TAG, "BT device - send has failed");
874 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
877 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
881 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
884 OIC_LOG(ERROR, TAG, "address is not available");
888 (*env)->ReleaseStringUTFChars(env, jni_address, address);
891 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
893 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
894 ca_mutex_lock(g_threadMutex);
895 if (!g_isFinishedSendData)
897 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
898 ca_cond_wait(g_threadCond, g_threadMutex);
899 OIC_LOG(DEBUG, TAG, "the data was sent");
901 ca_mutex_unlock(g_threadMutex);
903 // start LE Scan again
904 res = CALEClientStartScan();
905 if (CA_STATUS_OK != res)
907 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
908 ca_mutex_unlock(g_threadSendMutex);
912 ca_mutex_unlock(g_threadSendMutex);
913 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
917 res = CALEClientStartScan();
918 if (CA_STATUS_OK != res)
920 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
921 ca_mutex_unlock(g_threadSendMutex);
925 ca_mutex_unlock(g_threadSendMutex);
926 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
927 return CA_SEND_FAILED;
930 CAResult_t CALECheckSendState(const char* address)
932 VERIFY_NON_NULL(address, TAG, "address is null");
934 ca_mutex_lock(g_deviceStateListMutex);
935 CALEState_t* state = CALEClientGetStateInfo(address);
938 OIC_LOG(ERROR, TAG, "state is null");
939 ca_mutex_unlock(g_deviceStateListMutex);
940 return CA_SEND_FAILED;
943 if (STATE_SEND_SUCCESS != state->sendState)
945 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
946 ca_mutex_unlock(g_deviceStateListMutex);
947 return CA_SEND_FAILED;
950 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
951 ca_mutex_unlock(g_deviceStateListMutex);
955 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
957 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
958 VERIFY_NON_NULL(device, TAG, "device is null");
959 VERIFY_NON_NULL(env, TAG, "env is null");
961 // get BLE address from bluetooth device object.
962 char* address = NULL;
963 CALEState_t* state = NULL;
964 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
967 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
968 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
971 OIC_LOG(ERROR, TAG, "address is not available");
972 return CA_STATUS_FAILED;
974 ca_mutex_lock(g_deviceStateListMutex);
975 state = CALEClientGetStateInfo(address);
976 ca_mutex_unlock(g_deviceStateListMutex);
977 (*env)->ReleaseStringUTFChars(env, jni_address, address);
982 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
984 // cancel previous connection request before connection
985 // if there is gatt object in g_gattObjectList.
988 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
991 OIC_LOG(ERROR, TAG, "address is not available");
992 return CA_STATUS_FAILED;
995 jobject gatt = CALEClientGetGattObjInList(env, address);
998 CAResult_t res = CALEClientDisconnect(env, gatt);
999 if (CA_STATUS_OK != res)
1001 OIC_LOG(INFO, TAG, "there is no gatt object");
1004 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1007 // connection request
1008 jobject newGatt = CALEClientConnect(env, device,
1010 if (NULL == newGatt)
1012 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1013 return CA_STATUS_FAILED;
1018 if (STATE_CONNECTED == state->connectedState)
1020 OIC_LOG(INFO, TAG, "GATT has already connected");
1023 OIC_LOG(ERROR, TAG, "jni_address is not available");
1024 return CA_STATUS_FAILED;
1027 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1030 OIC_LOG(ERROR, TAG, "address is not available");
1031 return CA_STATUS_FAILED;
1034 jobject gatt = CALEClientGetGattObjInList(env, address);
1037 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1038 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1039 return CA_STATUS_FAILED;
1042 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1043 if (CA_STATUS_OK != ret)
1045 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1046 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1049 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1053 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1055 // cancel previous connection request before connection
1056 // if there is gatt object in g_gattObjectList.
1059 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1062 OIC_LOG(ERROR, TAG, "address is not available");
1063 return CA_STATUS_FAILED;
1066 jobject gatt = CALEClientGetGattObjInList(env, address);
1069 CAResult_t res = CALEClientDisconnect(env, gatt);
1070 if (CA_STATUS_OK != res)
1072 OIC_LOG(INFO, TAG, "there is no gatt object");
1075 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1078 OIC_LOG(DEBUG, TAG, "start to connect LE");
1079 jobject gatt = CALEClientConnect(env, device,
1080 CALEClientGetAutoConnectFlag(env, jni_address));
1083 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1084 return CA_STATUS_FAILED;
1089 return CA_STATUS_OK;
1092 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1094 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1095 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1097 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1098 if (!jni_cid_gattdevice_list)
1100 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1104 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1105 "()Landroid/bluetooth/BluetoothDevice;");
1106 if (!jni_mid_getDevice)
1108 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1112 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1113 if (!jni_obj_device)
1115 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1119 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1122 OIC_LOG(ERROR, TAG, "jni_address is null");
1132 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1135 OIC_LOG(DEBUG, TAG, "Gatt Close");
1136 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1137 VERIFY_NON_NULL(env, TAG, "env is null");
1139 // get BluetoothGatt class
1140 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1141 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1142 if (!jni_cid_BluetoothGatt)
1144 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1145 return CA_STATUS_FAILED;
1148 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1149 if (!jni_mid_closeGatt)
1151 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1152 return CA_STATUS_OK;
1155 // call disconnect gatt method
1156 OIC_LOG(DEBUG, TAG, "request to close GATT");
1157 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1159 if ((*env)->ExceptionCheck(env))
1161 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1162 (*env)->ExceptionDescribe(env);
1163 (*env)->ExceptionClear(env);
1164 return CA_STATUS_FAILED;
1167 return CA_STATUS_OK;
1170 CAResult_t CALEClientStartScan()
1172 if (!g_isStartedLEClient)
1174 OIC_LOG(ERROR, TAG, "LE client is not started");
1175 return CA_STATUS_FAILED;
1180 OIC_LOG(ERROR, TAG, "g_jvm is null");
1181 return CA_STATUS_FAILED;
1184 if (g_isStartedScan)
1186 OIC_LOG(INFO, TAG, "scanning is already started");
1187 return CA_STATUS_OK;
1190 bool isAttached = false;
1192 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1195 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1197 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1200 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1201 return CA_STATUS_FAILED;
1206 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1208 CAResult_t ret = CA_STATUS_OK;
1209 // scan gatt server with UUID
1210 if (g_leScanCallback && g_uuidList)
1213 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1215 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1217 if (CA_STATUS_OK != ret)
1219 if (CA_ADAPTER_NOT_ENABLED == ret)
1221 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1225 OIC_LOG(ERROR, TAG, "start scan has failed");
1232 (*g_jvm)->DetachCurrentThread(g_jvm);
1238 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1240 VERIFY_NON_NULL(callback, TAG, "callback is null");
1241 VERIFY_NON_NULL(env, TAG, "env is null");
1243 if (!CALEIsEnableBTAdapter(env))
1245 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1246 return CA_ADAPTER_NOT_ENABLED;
1249 // get default bt adapter class
1250 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1251 if (!jni_cid_BTAdapter)
1253 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1254 return CA_STATUS_FAILED;
1257 // get remote bt adapter method
1258 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1259 "getDefaultAdapter",
1260 METHODID_OBJECTNONPARAM);
1261 if (!jni_mid_getDefaultAdapter)
1263 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1264 return CA_STATUS_FAILED;
1267 // get start le scan method
1268 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1269 "(Landroid/bluetooth/BluetoothAdapter$"
1270 "LeScanCallback;)Z");
1271 if (!jni_mid_startLeScan)
1273 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1274 return CA_STATUS_FAILED;
1277 // gat bt adapter object
1278 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1279 jni_mid_getDefaultAdapter);
1280 if (!jni_obj_BTAdapter)
1282 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1283 return CA_STATUS_FAILED;
1286 // call start le scan method
1287 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1288 jni_mid_startLeScan, callback);
1289 if (!jni_obj_startLeScan)
1291 OIC_LOG(INFO, TAG, "startLeScan is failed");
1295 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1296 CALEClientSetScanFlag(true);
1299 return CA_STATUS_OK;
1302 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1304 VERIFY_NON_NULL(callback, TAG, "callback is null");
1305 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1306 VERIFY_NON_NULL(env, TAG, "env is null");
1308 if (!CALEIsEnableBTAdapter(env))
1310 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1311 return CA_ADAPTER_NOT_ENABLED;
1314 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1315 if (!jni_cid_BTAdapter)
1317 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1318 return CA_STATUS_FAILED;
1321 // get remote bt adapter method
1322 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1323 "getDefaultAdapter",
1324 METHODID_OBJECTNONPARAM);
1325 if (!jni_mid_getDefaultAdapter)
1327 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1328 return CA_STATUS_FAILED;
1331 // get start le scan method
1332 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1333 "([Ljava/util/UUID;Landroid/bluetooth/"
1334 "BluetoothAdapter$LeScanCallback;)Z");
1335 if (!jni_mid_startLeScan)
1337 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1338 return CA_STATUS_FAILED;
1341 // get bt adapter object
1342 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1343 jni_mid_getDefaultAdapter);
1344 if (!jni_obj_BTAdapter)
1346 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1347 return CA_STATUS_FAILED;
1350 // call start le scan method
1351 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1352 jni_mid_startLeScan, uuids, callback);
1353 if (!jni_obj_startLeScan)
1355 OIC_LOG(INFO, TAG, "startLeScan With UUID is failed");
1359 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1360 CALEClientSetScanFlag(true);
1363 return CA_STATUS_OK;
1366 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1368 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1369 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1372 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1375 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1379 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1380 "(Ljava/lang/String;)"
1381 "Ljava/util/UUID;");
1382 if (!jni_mid_fromString)
1384 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1388 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1389 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1393 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1397 return jni_obj_uuid;
1400 CAResult_t CALEClientStopScan()
1404 OIC_LOG(ERROR, TAG, "g_jvm is null");
1405 return CA_STATUS_FAILED;
1408 if (!g_isStartedScan)
1410 OIC_LOG(INFO, TAG, "scanning is already stopped");
1411 return CA_STATUS_OK;
1414 bool isAttached = false;
1416 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1419 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1420 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1423 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1424 return CA_STATUS_FAILED;
1429 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1430 if (CA_STATUS_OK != ret)
1432 if (CA_ADAPTER_NOT_ENABLED == ret)
1434 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1438 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1443 CALEClientSetScanFlag(false);
1448 (*g_jvm)->DetachCurrentThread(g_jvm);
1454 void CALEClientSetScanFlag(bool flag)
1456 ca_mutex_lock(g_scanMutex);
1457 g_isStartedScan = flag;
1458 ca_mutex_unlock(g_scanMutex);
1461 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1463 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1464 VERIFY_NON_NULL(callback, TAG, "callback is null");
1465 VERIFY_NON_NULL(env, TAG, "env is null");
1467 if (!CALEIsEnableBTAdapter(env))
1469 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1470 return CA_ADAPTER_NOT_ENABLED;
1473 // get default bt adapter class
1474 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1475 if (!jni_cid_BTAdapter)
1477 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1478 return CA_STATUS_FAILED;
1481 // get remote bt adapter method
1482 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1483 "getDefaultAdapter",
1484 METHODID_OBJECTNONPARAM);
1485 if (!jni_mid_getDefaultAdapter)
1487 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1488 return CA_STATUS_FAILED;
1491 // get start le scan method
1492 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1493 "(Landroid/bluetooth/"
1494 "BluetoothAdapter$LeScanCallback;)V");
1495 if (!jni_mid_stopLeScan)
1497 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1498 return CA_STATUS_FAILED;
1501 // gat bt adapter object
1502 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1503 jni_mid_getDefaultAdapter);
1504 if (!jni_obj_BTAdapter)
1506 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1507 return CA_STATUS_FAILED;
1510 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1511 // call start le scan method
1512 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1513 if ((*env)->ExceptionCheck(env))
1515 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1516 (*env)->ExceptionDescribe(env);
1517 (*env)->ExceptionClear(env);
1518 return CA_STATUS_FAILED;
1521 return CA_STATUS_OK;
1524 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1526 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1527 VERIFY_NON_NULL(env, TAG, "env");
1528 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1530 ca_mutex_lock(g_deviceStateListMutex);
1532 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1535 OIC_LOG(ERROR, TAG, "address is not available");
1536 return CA_STATUS_FAILED;
1539 if (CALEClientIsDeviceInList(address))
1541 CALEState_t* curState = CALEClientGetStateInfo(address);
1544 OIC_LOG(ERROR, TAG, "curState is null");
1545 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1546 ca_mutex_unlock(g_deviceStateListMutex);
1547 return CA_STATUS_FAILED;
1549 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1551 curState->autoConnectFlag = flag;
1554 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1555 ca_mutex_unlock(g_deviceStateListMutex);
1556 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1557 return CA_STATUS_OK;
1560 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1562 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1563 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1564 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1566 ca_mutex_lock(g_deviceStateListMutex);
1568 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1571 OIC_LOG(ERROR, TAG, "address is not available");
1575 CALEState_t* curState = CALEClientGetStateInfo(address);
1578 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1579 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1580 ca_mutex_unlock(g_deviceStateListMutex);
1583 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1585 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1586 ca_mutex_unlock(g_deviceStateListMutex);
1588 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1589 return curState->autoConnectFlag;
1592 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1594 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1595 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1596 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1598 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1599 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1602 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1605 OIC_LOG(ERROR, TAG, "address is not available");
1609 // close the gatt service
1610 jobject gatt = CALEClientGetGattObjInList(env, address);
1613 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1614 if (CA_STATUS_OK != res)
1616 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1617 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1621 // clean previous gatt object after close profile service
1622 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1623 if (CA_STATUS_OK != res)
1625 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1626 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1630 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1633 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1636 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1640 // add new gatt object into g_gattObjectList
1641 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1642 if (CA_STATUS_OK != res)
1644 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1651 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1653 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1654 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1655 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1657 if (!g_leGattCallback)
1659 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1663 if (!CALEIsEnableBTAdapter(env))
1665 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1669 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1672 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1676 // get BluetoothDevice class
1677 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1678 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1679 if (!jni_cid_BluetoothDevice)
1681 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1685 // get connectGatt method
1686 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1687 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1688 "(Landroid/content/Context;ZLandroid/"
1689 "bluetooth/BluetoothGattCallback;)"
1690 "Landroid/bluetooth/BluetoothGatt;");
1691 if (!jni_mid_connectGatt)
1693 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1697 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1698 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1699 jni_mid_connectGatt,
1701 autoconnect, g_leGattCallback);
1702 if (!jni_obj_connectGatt)
1704 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1705 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1706 CALEClientUpdateSendCnt(env);
1711 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1713 return jni_obj_connectGatt;
1716 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1718 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1720 VERIFY_NON_NULL(env, TAG, "env is null");
1721 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1723 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1724 if (!jni_cid_BTAdapter)
1726 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1727 return CA_STATUS_FAILED;
1730 // get remote bt adapter method
1731 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1732 "getDefaultAdapter",
1733 METHODID_OBJECTNONPARAM);
1734 if (!jni_mid_getDefaultAdapter)
1736 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1737 return CA_STATUS_FAILED;
1740 // gat bt adapter object
1741 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1742 jni_mid_getDefaultAdapter);
1743 if (!jni_obj_BTAdapter)
1745 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1746 return CA_STATUS_FAILED;
1749 // get closeProfileProxy method
1750 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1751 "closeProfileProxy",
1752 "(ILandroid/bluetooth/"
1753 "BluetoothProfile;)V");
1754 if (!jni_mid_closeProfileProxy)
1756 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1757 return CA_STATUS_FAILED;
1760 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1761 if (!jni_cid_BTProfile)
1763 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1764 return CA_STATUS_FAILED;
1767 // GATT - Constant value : 7 (0x00000007)
1768 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1772 OIC_LOG(ERROR, TAG, "id_gatt is null");
1773 return CA_STATUS_FAILED;
1776 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1778 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1779 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1780 if ((*env)->ExceptionCheck(env))
1782 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1783 (*env)->ExceptionDescribe(env);
1784 (*env)->ExceptionClear(env);
1785 return CA_STATUS_FAILED;
1788 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1789 return CA_STATUS_OK;
1793 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1795 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1796 VERIFY_NON_NULL(env, TAG, "env is null");
1797 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1799 // get BluetoothGatt class
1800 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1801 if (!jni_cid_BluetoothGatt)
1803 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1804 return CA_STATUS_FAILED;
1807 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1808 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1809 "disconnect", "()V");
1810 if (!jni_mid_disconnectGatt)
1812 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1813 return CA_STATUS_FAILED;
1816 // call disconnect gatt method
1817 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1818 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1819 if ((*env)->ExceptionCheck(env))
1821 OIC_LOG(ERROR, TAG, "disconnect has failed");
1822 (*env)->ExceptionDescribe(env);
1823 (*env)->ExceptionClear(env);
1824 return CA_STATUS_FAILED;
1827 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1829 return CA_STATUS_OK;
1832 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1834 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1835 VERIFY_NON_NULL(env, TAG, "env is null");
1837 if (!g_gattObjectList)
1839 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1840 return CA_STATUS_OK;
1843 uint32_t length = u_arraylist_length(g_gattObjectList);
1844 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1845 for (uint32_t index = 0; index < length; index++)
1847 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1848 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1851 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1854 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1855 if (CA_STATUS_OK != res)
1857 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1862 return CA_STATUS_OK;
1865 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1867 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1868 VERIFY_NON_NULL(env, TAG, "env is null");
1870 if (!g_gattObjectList)
1872 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1873 return CA_STATUS_OK;
1876 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1879 OIC_LOG(ERROR, TAG, "address is null");
1880 return CA_STATUS_FAILED;
1883 uint32_t length = u_arraylist_length(g_gattObjectList);
1884 for (uint32_t index = 0; index < length; index++)
1886 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1889 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1893 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1894 if (!jni_setAddress)
1896 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1897 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1898 return CA_STATUS_FAILED;
1901 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1904 OIC_LOG(ERROR, TAG, "setAddress is null");
1905 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1906 return CA_STATUS_FAILED;
1909 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1910 if (!strcmp(address, setAddress))
1912 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1913 if (CA_STATUS_OK != res)
1915 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1916 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1917 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1918 return CA_STATUS_FAILED;
1920 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1921 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1922 return CA_STATUS_OK;
1924 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1926 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1928 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1929 return CA_STATUS_OK;
1932 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1934 VERIFY_NON_NULL(env, TAG, "env is null");
1935 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1937 if (!CALEIsEnableBTAdapter(env))
1939 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1940 return CA_ADAPTER_NOT_ENABLED;
1943 // get BluetoothGatt class
1944 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1945 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1946 if (!jni_cid_BluetoothGatt)
1948 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1949 return CA_STATUS_FAILED;
1952 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1953 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1954 "discoverServices", "()Z");
1955 if (!jni_mid_discoverServices)
1957 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1958 return CA_STATUS_FAILED;
1960 // call disconnect gatt method
1961 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1962 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1965 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1966 return CA_STATUS_FAILED;
1969 return CA_STATUS_OK;
1972 static void CALEWriteCharacteristicThread(void* object)
1974 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1976 bool isAttached = false;
1978 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1981 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1982 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1986 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1992 jobject gatt = (jobject)object;
1993 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1994 if (CA_STATUS_OK != ret)
1996 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2001 (*g_jvm)->DetachCurrentThread(g_jvm);
2005 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2007 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2008 VERIFY_NON_NULL(env, TAG, "env is null");
2011 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2012 if (!jni_obj_character)
2014 CALEClientSendFinish(env, gatt);
2015 return CA_STATUS_FAILED;
2018 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2019 if (CA_STATUS_OK != ret)
2021 CALEClientSendFinish(env, gatt);
2022 return CA_STATUS_FAILED;
2025 // wait for callback for write Characteristic with success to sent data
2026 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2027 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2028 if (!g_isSignalSetFlag)
2030 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2031 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2032 g_threadWriteCharacteristicMutex,
2033 WAIT_TIME_WRITE_CHARACTERISTIC))
2035 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2036 g_isSignalSetFlag = false;
2037 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2038 return CA_STATUS_FAILED;
2041 // reset flag set by writeCharacteristic Callback
2042 g_isSignalSetFlag = false;
2043 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2045 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2046 return CA_STATUS_OK;
2049 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2051 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2052 VERIFY_NON_NULL(env, TAG, "env is null");
2053 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2055 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2056 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2057 CALEWriteCharacteristicThread, (void*)gattParam))
2059 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2060 return CA_STATUS_FAILED;
2063 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2064 return CA_STATUS_OK;
2067 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2068 jobject gattCharacteristic)
2070 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2071 VERIFY_NON_NULL(env, TAG, "env is null");
2072 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2073 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2075 if (!CALEIsEnableBTAdapter(env))
2077 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2078 return CA_STATUS_FAILED;
2081 // get BluetoothGatt class
2082 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2083 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2084 if (!jni_cid_BluetoothGatt)
2086 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2087 return CA_STATUS_FAILED;
2090 OIC_LOG(DEBUG, TAG, "write characteristic method");
2091 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2092 "writeCharacteristic",
2093 "(Landroid/bluetooth/"
2094 "BluetoothGattCharacteristic;)Z");
2095 if (!jni_mid_writeCharacteristic)
2097 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2098 return CA_STATUS_FAILED;
2101 // call disconnect gatt method
2102 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2103 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2104 jni_mid_writeCharacteristic,
2105 gattCharacteristic);
2108 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2112 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2113 return CA_STATUS_FAILED;
2116 return CA_STATUS_OK;
2119 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2121 VERIFY_NON_NULL(env, TAG, "env is null");
2122 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2124 if (!CALEIsEnableBTAdapter(env))
2126 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2127 return CA_STATUS_FAILED;
2130 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2131 if (!jni_cid_BluetoothGatt)
2133 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2134 return CA_STATUS_FAILED;
2137 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2140 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2141 return CA_STATUS_FAILED;
2144 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2145 if (!jni_obj_GattCharacteristic)
2147 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2148 return CA_STATUS_FAILED;
2151 OIC_LOG(DEBUG, TAG, "read characteristic method");
2152 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2153 "readCharacteristic",
2154 "(Landroid/bluetooth/"
2155 "BluetoothGattCharacteristic;)Z");
2156 if (!jni_mid_readCharacteristic)
2158 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2159 return CA_STATUS_FAILED;
2162 // call disconnect gatt method
2163 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2164 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2165 jni_obj_GattCharacteristic);
2168 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2172 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2173 return CA_STATUS_FAILED;
2176 return CA_STATUS_OK;
2179 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2180 jobject characteristic)
2182 VERIFY_NON_NULL(env, TAG, "env is null");
2183 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2184 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2186 if (!CALEIsEnableBTAdapter(env))
2188 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2189 return CA_ADAPTER_NOT_ENABLED;
2192 // get BluetoothGatt class
2193 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2194 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2195 if (!jni_cid_BluetoothGatt)
2197 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2198 return CA_STATUS_FAILED;
2201 // set Characteristic Notification
2202 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2203 "setCharacteristicNotification",
2204 "(Landroid/bluetooth/"
2205 "BluetoothGattCharacteristic;Z)Z");
2206 if (!jni_mid_setNotification)
2208 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2209 return CA_STATUS_FAILED;
2212 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2213 characteristic, JNI_TRUE);
2214 if (JNI_TRUE == ret)
2216 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2220 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2221 return CA_STATUS_FAILED;
2224 return CA_STATUS_OK;
2227 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2229 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2230 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2231 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2233 if (!CALEIsEnableBTAdapter(env))
2235 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2239 // get BluetoothGatt class
2240 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2241 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2242 if (!jni_cid_BluetoothGatt)
2244 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2248 jmethodID jni_mid_getService = (*env)->GetMethodID(
2249 env, jni_cid_BluetoothGatt, "getService",
2250 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2251 if (!jni_mid_getService)
2253 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2257 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2258 if (!jni_obj_service_uuid)
2260 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2264 // get bluetooth gatt service
2265 OIC_LOG(DEBUG, TAG, "request to get service");
2266 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2267 jni_obj_service_uuid);
2268 if (!jni_obj_gattService)
2270 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2274 // get bluetooth gatt service class
2275 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2276 env, "android/bluetooth/BluetoothGattService");
2277 if (!jni_cid_BluetoothGattService)
2279 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2283 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2284 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2285 "getCharacteristic",
2286 "(Ljava/util/UUID;)"
2287 "Landroid/bluetooth/"
2288 "BluetoothGattCharacteristic;");
2289 if (!jni_mid_getCharacteristic)
2291 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2295 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2298 OIC_LOG(ERROR, TAG, "uuid is null");
2302 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2303 if (!jni_obj_tx_uuid)
2305 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2306 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2310 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2311 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2312 jni_mid_getCharacteristic,
2315 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2316 return jni_obj_GattCharacteristic;
2319 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2321 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2322 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2323 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2324 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2326 if (!CALEIsEnableBTAdapter(env))
2328 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2332 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2335 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2339 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2340 if (!jni_obj_GattCharacteristic)
2342 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2346 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2347 "/BluetoothGattCharacteristic");
2348 if (!jni_cid_BTGattCharacteristic)
2350 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2354 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2355 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2357 if (!jni_mid_setValue)
2359 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2363 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2365 if (JNI_TRUE == ret)
2367 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2371 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2376 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2377 "setWriteType", "(I)V");
2378 if (!jni_mid_setWriteType)
2380 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2384 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2385 "WRITE_TYPE_NO_RESPONSE", "I");
2386 if (!jni_fid_no_response)
2388 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2392 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2393 jni_fid_no_response);
2395 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2397 return jni_obj_GattCharacteristic;
2400 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2402 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2403 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2405 if (!CALEIsEnableBTAdapter(env))
2407 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2411 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2412 "BluetoothGattCharacteristic");
2413 if (!jni_cid_BTGattCharacteristic)
2415 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2419 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2420 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2422 if (!jni_mid_getValue)
2424 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2428 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2430 return jni_obj_data_array;
2433 CAResult_t CALEClientCreateUUIDList()
2437 OIC_LOG(ERROR, TAG, "g_jvm is null");
2438 return CA_STATUS_FAILED;
2441 bool isAttached = false;
2443 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2446 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2447 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2451 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2452 return CA_STATUS_FAILED;
2457 // create new object array
2458 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2459 if (!jni_cid_uuid_list)
2461 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2465 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2466 jni_cid_uuid_list, NULL);
2467 if (!jni_obj_uuid_list)
2469 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2474 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2477 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2480 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2482 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2486 (*g_jvm)->DetachCurrentThread(g_jvm);
2489 return CA_STATUS_OK;
2496 (*g_jvm)->DetachCurrentThread(g_jvm);
2498 return CA_STATUS_FAILED;
2501 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2502 jobject characteristic)
2504 VERIFY_NON_NULL(env, TAG, "env is null");
2505 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2506 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2508 if (!CALEIsEnableBTAdapter(env))
2510 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2511 return CA_ADAPTER_NOT_ENABLED;
2514 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2515 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2516 "BluetoothGattCharacteristic");
2517 if (!jni_cid_BTGattCharacteristic)
2519 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2520 return CA_STATUS_FAILED;
2523 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2524 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2526 "(Ljava/util/UUID;)Landroid/bluetooth/"
2527 "BluetoothGattDescriptor;");
2528 if (!jni_mid_getDescriptor)
2530 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2531 return CA_STATUS_FAILED;
2534 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2535 if (!jni_obj_cc_uuid)
2537 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2538 return CA_STATUS_FAILED;
2541 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2542 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2543 jni_mid_getDescriptor, jni_obj_cc_uuid);
2544 if (!jni_obj_descriptor)
2546 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2547 return CA_NOT_SUPPORTED;
2550 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2551 jclass jni_cid_descriptor = (*env)->FindClass(env,
2552 "android/bluetooth/BluetoothGattDescriptor");
2553 if (!jni_cid_descriptor)
2555 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2556 return CA_STATUS_FAILED;
2559 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2560 if (!jni_mid_setValue)
2562 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2563 return CA_STATUS_FAILED;
2566 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2567 "ENABLE_NOTIFICATION_VALUE", "[B");
2568 if (!jni_fid_NotiValue)
2570 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2571 return CA_STATUS_FAILED;
2574 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2576 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2577 env, jni_obj_descriptor, jni_mid_setValue,
2578 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2581 OIC_LOG(DEBUG, TAG, "setValue success");
2585 OIC_LOG(ERROR, TAG, "setValue has failed");
2586 return CA_STATUS_FAILED;
2589 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2592 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2593 return CA_STATUS_FAILED;
2596 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2597 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2598 "(Landroid/bluetooth/"
2599 "BluetoothGattDescriptor;)Z");
2600 if (!jni_mid_writeDescriptor)
2602 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2603 return CA_STATUS_FAILED;
2606 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2607 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2608 jni_obj_descriptor);
2611 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2615 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2616 return CA_STATUS_FAILED;
2619 return CA_STATUS_OK;
2622 void CALEClientCreateScanDeviceList(JNIEnv *env)
2624 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2625 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2627 ca_mutex_lock(g_deviceListMutex);
2628 // create new object array
2629 if (g_deviceList == NULL)
2631 OIC_LOG(DEBUG, TAG, "Create device list");
2633 g_deviceList = u_arraylist_create();
2635 ca_mutex_unlock(g_deviceListMutex);
2638 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2640 VERIFY_NON_NULL(device, TAG, "device is null");
2641 VERIFY_NON_NULL(env, TAG, "env is null");
2643 ca_mutex_lock(g_deviceListMutex);
2647 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2649 CALEClientSetScanFlag(false);
2650 if(CA_STATUS_OK != CALEClientStopScan())
2652 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2655 ca_mutex_unlock(g_deviceListMutex);
2656 return CA_STATUS_FAILED;
2659 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2660 if (!jni_remoteAddress)
2662 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2663 ca_mutex_unlock(g_deviceListMutex);
2664 return CA_STATUS_FAILED;
2667 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2670 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2671 ca_mutex_unlock(g_deviceListMutex);
2672 return CA_STATUS_FAILED;
2675 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2677 jobject gdevice = (*env)->NewGlobalRef(env, device);
2678 u_arraylist_add(g_deviceList, gdevice);
2679 ca_cond_signal(g_deviceDescCond);
2680 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2682 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2684 ca_mutex_unlock(g_deviceListMutex);
2686 return CA_STATUS_OK;
2689 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2691 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2692 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2696 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2700 uint32_t length = u_arraylist_length(g_deviceList);
2701 for (uint32_t index = 0; index < length; index++)
2703 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2706 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2710 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2711 if (!jni_setAddress)
2713 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2717 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2720 OIC_LOG(ERROR, TAG, "setAddress is null");
2724 if (!strcmp(remoteAddress, setAddress))
2726 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2730 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2733 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2738 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2740 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2741 VERIFY_NON_NULL(env, TAG, "env is null");
2743 ca_mutex_lock(g_deviceListMutex);
2747 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2748 ca_mutex_unlock(g_deviceListMutex);
2749 return CA_STATUS_FAILED;
2752 uint32_t length = u_arraylist_length(g_deviceList);
2753 for (uint32_t index = 0; index < length; index++)
2755 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2758 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2761 (*env)->DeleteGlobalRef(env, jarrayObj);
2765 OICFree(g_deviceList);
2766 g_deviceList = NULL;
2768 ca_mutex_unlock(g_deviceListMutex);
2769 return CA_STATUS_OK;
2772 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2774 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2775 VERIFY_NON_NULL(address, TAG, "address is null");
2776 VERIFY_NON_NULL(env, TAG, "env is null");
2778 ca_mutex_lock(g_deviceListMutex);
2782 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2783 ca_mutex_unlock(g_deviceListMutex);
2784 return CA_STATUS_FAILED;
2787 uint32_t length = u_arraylist_length(g_deviceList);
2788 for (uint32_t index = 0; index < length; index++)
2790 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2793 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2794 ca_mutex_unlock(g_deviceListMutex);
2795 return CA_STATUS_FAILED;
2798 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2799 if (!jni_setAddress)
2801 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2802 ca_mutex_unlock(g_deviceListMutex);
2803 return CA_STATUS_FAILED;
2806 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2809 OIC_LOG(ERROR, TAG, "setAddress is null");
2810 ca_mutex_unlock(g_deviceListMutex);
2811 return CA_STATUS_FAILED;
2814 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2817 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2818 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2819 ca_mutex_unlock(g_deviceListMutex);
2820 return CA_STATUS_FAILED;
2823 if (!strcmp(setAddress, remoteAddress))
2825 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2826 (*env)->DeleteGlobalRef(env, jarrayObj);
2828 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2829 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2831 if (NULL == u_arraylist_remove(g_deviceList, index))
2833 OIC_LOG(ERROR, TAG, "List removal failed.");
2834 ca_mutex_unlock(g_deviceListMutex);
2835 return CA_STATUS_FAILED;
2837 ca_mutex_unlock(g_deviceListMutex);
2838 return CA_STATUS_OK;
2840 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2841 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2844 ca_mutex_unlock(g_deviceListMutex);
2845 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2847 return CA_STATUS_OK;
2854 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2856 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2857 VERIFY_NON_NULL(env, TAG, "env is null");
2858 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2860 ca_mutex_lock(g_gattObjectMutex);
2862 if (!g_gattObjectList)
2864 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2865 ca_mutex_unlock(g_gattObjectMutex);
2866 return CA_STATUS_FAILED;
2869 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2870 if (!jni_remoteAddress)
2872 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2873 ca_mutex_unlock(g_gattObjectMutex);
2874 return CA_STATUS_FAILED;
2877 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2880 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2881 ca_mutex_unlock(g_gattObjectMutex);
2882 return CA_STATUS_FAILED;
2885 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2886 if (!CALEClientIsGattObjInList(env, remoteAddress))
2888 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2889 u_arraylist_add(g_gattObjectList, newGatt);
2890 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2893 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2894 ca_mutex_unlock(g_gattObjectMutex);
2895 return CA_STATUS_OK;
2898 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2900 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2901 VERIFY_NON_NULL(env, TAG, "env is null");
2902 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2904 uint32_t length = u_arraylist_length(g_gattObjectList);
2905 for (uint32_t index = 0; index < length; index++)
2908 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2911 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2915 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2916 if (!jni_setAddress)
2918 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2922 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2925 OIC_LOG(ERROR, TAG, "setAddress is null");
2929 if (!strcmp(remoteAddress, setAddress))
2931 OIC_LOG(DEBUG, TAG, "the device is already set");
2932 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2937 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2942 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2946 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2948 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2949 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2950 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2952 ca_mutex_lock(g_gattObjectMutex);
2953 uint32_t length = u_arraylist_length(g_gattObjectList);
2954 for (uint32_t index = 0; index < length; index++)
2956 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2959 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2960 ca_mutex_unlock(g_gattObjectMutex);
2964 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2965 if (!jni_setAddress)
2967 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2968 ca_mutex_unlock(g_gattObjectMutex);
2972 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2975 OIC_LOG(ERROR, TAG, "setAddress is null");
2976 ca_mutex_unlock(g_gattObjectMutex);
2980 if (!strcmp(remoteAddress, setAddress))
2982 OIC_LOG(DEBUG, TAG, "the device is already set");
2983 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2984 ca_mutex_unlock(g_gattObjectMutex);
2987 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2990 ca_mutex_unlock(g_gattObjectMutex);
2991 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2995 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2997 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2998 VERIFY_NON_NULL(env, TAG, "env is null");
3000 ca_mutex_lock(g_gattObjectMutex);
3001 if (!g_gattObjectList)
3003 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3004 ca_mutex_unlock(g_gattObjectMutex);
3005 return CA_STATUS_OK;
3008 uint32_t length = u_arraylist_length(g_gattObjectList);
3009 for (uint32_t index = 0; index < length; index++)
3011 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3014 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3017 (*env)->DeleteGlobalRef(env, jarrayObj);
3021 OICFree(g_gattObjectList);
3022 g_gattObjectList = NULL;
3023 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3024 ca_mutex_unlock(g_gattObjectMutex);
3025 return CA_STATUS_OK;
3028 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3030 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3031 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3032 VERIFY_NON_NULL(env, TAG, "env is null");
3034 ca_mutex_lock(g_gattObjectMutex);
3035 if (!g_gattObjectList)
3037 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3038 ca_mutex_unlock(g_gattObjectMutex);
3039 return CA_STATUS_OK;
3042 uint32_t length = u_arraylist_length(g_gattObjectList);
3043 for (uint32_t index = 0; index < length; index++)
3045 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3048 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3049 ca_mutex_unlock(g_gattObjectMutex);
3050 return CA_STATUS_FAILED;
3053 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3054 if (!jni_setAddress)
3056 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3057 ca_mutex_unlock(g_gattObjectMutex);
3058 return CA_STATUS_FAILED;
3061 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3064 OIC_LOG(ERROR, TAG, "setAddress is null");
3065 ca_mutex_unlock(g_gattObjectMutex);
3066 return CA_STATUS_FAILED;
3069 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3070 if (!jni_remoteAddress)
3072 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3073 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3074 ca_mutex_unlock(g_gattObjectMutex);
3075 return CA_STATUS_FAILED;
3078 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3081 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3082 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3083 ca_mutex_unlock(g_gattObjectMutex);
3084 return CA_STATUS_FAILED;
3087 if (!strcmp(setAddress, remoteAddress))
3089 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3090 (*env)->DeleteGlobalRef(env, jarrayObj);
3092 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3093 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3095 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3097 OIC_LOG(ERROR, TAG, "List removal failed.");
3098 ca_mutex_unlock(g_gattObjectMutex);
3099 return CA_STATUS_FAILED;
3101 ca_mutex_unlock(g_gattObjectMutex);
3102 return CA_STATUS_OK;
3104 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3105 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3108 ca_mutex_unlock(g_gattObjectMutex);
3109 OIC_LOG(DEBUG, TAG, "there are no target object");
3110 return CA_STATUS_OK;
3113 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3115 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3116 VERIFY_NON_NULL(addr, TAG, "addr is null");
3117 VERIFY_NON_NULL(env, TAG, "env is null");
3119 ca_mutex_lock(g_gattObjectMutex);
3120 if (!g_gattObjectList)
3122 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3123 ca_mutex_unlock(g_gattObjectMutex);
3124 return CA_STATUS_OK;
3127 uint32_t length = u_arraylist_length(g_gattObjectList);
3128 for (uint32_t index = 0; index < length; index++)
3130 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3133 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3134 ca_mutex_unlock(g_gattObjectMutex);
3135 return CA_STATUS_FAILED;
3138 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3139 if (!jni_setAddress)
3141 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3142 ca_mutex_unlock(g_gattObjectMutex);
3143 return CA_STATUS_FAILED;
3146 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3149 OIC_LOG(ERROR, TAG, "setAddress is null");
3150 ca_mutex_unlock(g_gattObjectMutex);
3151 return CA_STATUS_FAILED;
3154 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3157 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3158 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3159 ca_mutex_unlock(g_gattObjectMutex);
3160 return CA_STATUS_FAILED;
3163 if (!strcmp(setAddress, remoteAddress))
3165 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3166 (*env)->DeleteGlobalRef(env, jarrayObj);
3168 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3169 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3170 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3172 OIC_LOG(ERROR, TAG, "List removal failed.");
3173 ca_mutex_unlock(g_gattObjectMutex);
3174 return CA_STATUS_FAILED;
3176 ca_mutex_unlock(g_gattObjectMutex);
3177 return CA_STATUS_OK;
3179 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3180 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3183 ca_mutex_unlock(g_gattObjectMutex);
3184 OIC_LOG(DEBUG, TAG, "there are no target object");
3185 return CA_STATUS_FAILED;
3188 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3190 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3192 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3193 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3195 // get Bluetooth Address
3196 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3197 if (!jni_btTargetAddress)
3199 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3203 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3206 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3210 // get method ID of getDevice()
3211 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3212 if (!jni_cid_gattdevice_list)
3214 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3215 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3219 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3220 METHODID_BT_DEVICE);
3221 if (!jni_mid_getDevice)
3223 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3224 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3228 size_t length = u_arraylist_length(g_gattObjectList);
3229 for (size_t index = 0; index < length; index++)
3231 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3234 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3235 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3239 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3240 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3241 if (!jni_obj_device)
3243 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3244 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3248 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3251 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3252 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3256 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3259 OIC_LOG(ERROR, TAG, "btAddress is not available");
3260 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3264 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3265 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3266 if (!strcmp(targetAddress, btAddress))
3268 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3271 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3274 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3276 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3277 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3278 (*env)->DeleteLocalRef(env, jni_btAddress);
3279 (*env)->DeleteLocalRef(env, jni_obj_device);
3280 return jni_LEAddress;
3282 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3283 (*env)->DeleteLocalRef(env, jni_btAddress);
3284 (*env)->DeleteLocalRef(env, jni_obj_device);
3287 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3295 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3296 uint16_t notificationState, uint16_t sendState)
3298 VERIFY_NON_NULL(address, TAG, "address is null");
3300 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3303 OIC_LOG(ERROR, TAG, "out of memory");
3304 return CA_MEMORY_ALLOC_FAILED;
3307 if (strlen(address) > CA_MACADDR_SIZE)
3309 OIC_LOG(ERROR, TAG, "address is not proper");
3311 return CA_STATUS_FAILED;
3314 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3315 newstate->connectedState = connectedState;
3316 newstate->notificationState = notificationState;
3317 newstate->sendState = sendState;
3318 return CALEClientAddDeviceStateToList(newstate);
3321 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3323 VERIFY_NON_NULL(state, TAG, "state is null");
3325 ca_mutex_lock(g_deviceStateListMutex);
3327 if (!g_deviceStateList)
3329 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3330 ca_mutex_unlock(g_deviceStateListMutex);
3331 return CA_STATUS_FAILED;
3334 if (CALEClientIsDeviceInList(state->address))
3336 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3339 OIC_LOG(ERROR, TAG, "curState is null");
3340 ca_mutex_unlock(g_deviceStateListMutex);
3341 return CA_STATUS_FAILED;
3344 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3346 state->notificationState = curState->notificationState;
3348 state->autoConnectFlag = curState->autoConnectFlag;
3350 // delete previous state for update new state
3351 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3352 if (CA_STATUS_OK != res)
3354 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3355 ca_mutex_unlock(g_deviceStateListMutex);
3359 u_arraylist_add(g_deviceStateList, state); // update new state
3360 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
3361 state->connectedState, state->notificationState,
3362 state->address, state->autoConnectFlag);
3364 ca_mutex_unlock(g_deviceStateListMutex);
3365 return CA_STATUS_OK;
3368 bool CALEClientIsDeviceInList(const char* remoteAddress)
3370 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3372 if (!g_deviceStateList)
3374 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3378 uint32_t length = u_arraylist_length(g_deviceStateList);
3379 for (uint32_t index = 0; index < length; index++)
3381 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3384 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3388 if (!strcmp(remoteAddress, state->address))
3390 OIC_LOG(DEBUG, TAG, "the device is already set");
3399 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3403 CAResult_t CALEClientRemoveAllDeviceState()
3405 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3407 ca_mutex_lock(g_deviceStateListMutex);
3408 if (!g_deviceStateList)
3410 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3411 ca_mutex_unlock(g_deviceStateListMutex);
3412 return CA_STATUS_FAILED;
3415 uint32_t length = u_arraylist_length(g_deviceStateList);
3416 for (uint32_t index = 0; index < length; index++)
3418 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3421 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3427 OICFree(g_deviceStateList);
3428 g_deviceStateList = NULL;
3429 ca_mutex_unlock(g_deviceStateListMutex);
3431 return CA_STATUS_OK;
3434 CAResult_t CALEClientResetDeviceStateForAll()
3436 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3438 ca_mutex_lock(g_deviceStateListMutex);
3439 if (!g_deviceStateList)
3441 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3442 ca_mutex_unlock(g_deviceStateListMutex);
3443 return CA_STATUS_FAILED;
3446 size_t length = u_arraylist_length(g_deviceStateList);
3447 for (size_t index = 0; index < length; index++)
3449 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3452 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3456 // autoConnectFlag value will be not changed,
3457 // since it has reset only termination case.
3458 state->connectedState = STATE_DISCONNECTED;
3459 state->notificationState = STATE_CHARACTER_UNSET;
3460 state->sendState = STATE_SEND_NONE;
3462 ca_mutex_unlock(g_deviceStateListMutex);
3464 return CA_STATUS_OK;
3467 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3469 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3470 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3472 if (!g_deviceStateList)
3474 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3475 return CA_STATUS_FAILED;
3478 uint32_t length = u_arraylist_length(g_deviceStateList);
3479 for (uint32_t index = 0; index < length; index++)
3481 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3484 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3488 if (!strcmp(state->address, remoteAddress))
3490 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3492 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3494 if (NULL == targetState)
3496 OIC_LOG(ERROR, TAG, "List removal failed.");
3497 return CA_STATUS_FAILED;
3500 OICFree(targetState);
3501 return CA_STATUS_OK;
3505 return CA_STATUS_OK;
3508 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3510 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3511 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3513 if (!g_deviceStateList)
3515 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3519 uint32_t length = u_arraylist_length(g_deviceStateList);
3520 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3522 for (uint32_t index = 0; index < length; index++)
3524 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3527 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3531 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3532 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3534 if (!strcmp(state->address, remoteAddress))
3536 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3543 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3545 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3546 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3548 ca_mutex_lock(g_deviceStateListMutex);
3549 if (!g_deviceStateList)
3551 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3552 ca_mutex_unlock(g_deviceStateListMutex);
3556 uint32_t length = u_arraylist_length(g_deviceStateList);
3557 for (uint32_t index = 0; index < length; index++)
3559 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3562 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3566 if (!strcmp(state->address, remoteAddress))
3568 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3570 if (STATE_CONNECTED == state->connectedState)
3572 ca_mutex_unlock(g_deviceStateListMutex);
3577 ca_mutex_unlock(g_deviceStateListMutex);
3582 ca_mutex_unlock(g_deviceStateListMutex);
3586 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3588 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3589 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3591 ca_mutex_lock(g_deviceStateListMutex);
3592 if (!g_deviceStateList)
3594 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3595 ca_mutex_unlock(g_deviceStateListMutex);
3599 uint32_t length = u_arraylist_length(g_deviceStateList);
3600 for (uint32_t index = 0; index < length; index++)
3602 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3605 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3609 if (!strcmp(state->address, remoteAddress))
3611 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3613 if (STATE_CHARACTER_SET == state->notificationState)
3615 ca_mutex_unlock(g_deviceStateListMutex);
3620 ca_mutex_unlock(g_deviceStateListMutex);
3626 ca_mutex_unlock(g_deviceStateListMutex);
3630 void CALEClientCreateDeviceList()
3632 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3634 // create new object array
3635 if (!g_gattObjectList)
3637 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3639 g_gattObjectList = u_arraylist_create();
3642 if (!g_deviceStateList)
3644 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3646 g_deviceStateList = u_arraylist_create();
3651 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3653 g_deviceList = u_arraylist_create();
3658 * Check Sent Count for remove g_sendBuffer
3660 void CALEClientUpdateSendCnt(JNIEnv *env)
3662 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3664 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3666 ca_mutex_lock(g_threadMutex);
3670 if (g_targetCnt <= g_currentSentCnt)
3673 g_currentSentCnt = 0;
3677 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3678 g_sendBuffer = NULL;
3680 // notity the thread
3681 ca_cond_signal(g_threadCond);
3683 CALEClientSetSendFinishFlag(true);
3684 OIC_LOG(DEBUG, TAG, "set signal for send data");
3687 ca_mutex_unlock(g_threadMutex);
3690 CAResult_t CALEClientInitGattMutexVaraibles()
3692 if (NULL == g_bleReqRespClientCbMutex)
3694 g_bleReqRespClientCbMutex = ca_mutex_new();
3695 if (NULL == g_bleReqRespClientCbMutex)
3697 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3698 return CA_STATUS_FAILED;
3702 if (NULL == g_bleServerBDAddressMutex)
3704 g_bleServerBDAddressMutex = ca_mutex_new();
3705 if (NULL == g_bleServerBDAddressMutex)
3707 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3708 return CA_STATUS_FAILED;
3712 if (NULL == g_threadMutex)
3714 g_threadMutex = ca_mutex_new();
3715 if (NULL == g_threadMutex)
3717 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3718 return CA_STATUS_FAILED;
3722 if (NULL == g_threadSendMutex)
3724 g_threadSendMutex = ca_mutex_new();
3725 if (NULL == g_threadSendMutex)
3727 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3728 return CA_STATUS_FAILED;
3732 if (NULL == g_deviceListMutex)
3734 g_deviceListMutex = ca_mutex_new();
3735 if (NULL == g_deviceListMutex)
3737 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3738 return CA_STATUS_FAILED;
3742 if (NULL == g_gattObjectMutex)
3744 g_gattObjectMutex = ca_mutex_new();
3745 if (NULL == g_gattObjectMutex)
3747 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3748 return CA_STATUS_FAILED;
3752 if (NULL == g_deviceStateListMutex)
3754 g_deviceStateListMutex = ca_mutex_new();
3755 if (NULL == g_deviceStateListMutex)
3757 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3758 return CA_STATUS_FAILED;
3762 if (NULL == g_SendFinishMutex)
3764 g_SendFinishMutex = ca_mutex_new();
3765 if (NULL == g_SendFinishMutex)
3767 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3768 return CA_STATUS_FAILED;
3772 if (NULL == g_scanMutex)
3774 g_scanMutex = ca_mutex_new();
3775 if (NULL == g_scanMutex)
3777 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3778 return CA_STATUS_FAILED;
3782 if (NULL == g_threadWriteCharacteristicMutex)
3784 g_threadWriteCharacteristicMutex = ca_mutex_new();
3785 if (NULL == g_threadWriteCharacteristicMutex)
3787 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3788 return CA_STATUS_FAILED;
3792 if (NULL == g_deviceScanRetryDelayMutex)
3794 g_deviceScanRetryDelayMutex = ca_mutex_new();
3795 if (NULL == g_deviceScanRetryDelayMutex)
3797 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3798 return CA_STATUS_FAILED;
3802 return CA_STATUS_OK;
3805 void CALEClientTerminateGattMutexVariables()
3807 ca_mutex_free(g_bleReqRespClientCbMutex);
3808 g_bleReqRespClientCbMutex = NULL;
3810 ca_mutex_free(g_bleServerBDAddressMutex);
3811 g_bleServerBDAddressMutex = NULL;
3813 ca_mutex_free(g_threadMutex);
3814 g_threadMutex = NULL;
3816 ca_mutex_free(g_threadSendMutex);
3817 g_threadSendMutex = NULL;
3819 ca_mutex_free(g_deviceListMutex);
3820 g_deviceListMutex = NULL;
3822 ca_mutex_free(g_SendFinishMutex);
3823 g_SendFinishMutex = NULL;
3825 ca_mutex_free(g_scanMutex);
3828 ca_mutex_free(g_threadWriteCharacteristicMutex);
3829 g_threadWriteCharacteristicMutex = NULL;
3831 ca_mutex_free(g_deviceScanRetryDelayMutex);
3832 g_deviceScanRetryDelayMutex = NULL;
3835 void CALEClientSetSendFinishFlag(bool flag)
3837 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3839 ca_mutex_lock(g_SendFinishMutex);
3840 g_isFinishedSendData = flag;
3841 ca_mutex_unlock(g_SendFinishMutex);
3848 CAResult_t CAStartLEGattClient()
3850 // init mutex for send logic
3851 if (!g_deviceDescCond)
3853 g_deviceDescCond = ca_cond_new();
3858 g_threadCond = ca_cond_new();
3861 if (!g_threadWriteCharacteristicCond)
3863 g_threadWriteCharacteristicCond = ca_cond_new();
3866 CAResult_t ret = CALEClientStartScan();
3867 if (CA_STATUS_OK != ret)
3869 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3873 g_isStartedLEClient = true;
3874 return CA_STATUS_OK;
3877 void CAStopLEGattClient()
3879 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3883 OIC_LOG(ERROR, TAG, "g_jvm is null");
3887 bool isAttached = false;
3889 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3892 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3893 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3897 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3903 CAResult_t ret = CALEClientDisconnectAll(env);
3904 if (CA_STATUS_OK != ret)
3906 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3909 ret = CALEClientStopScan();
3910 if(CA_STATUS_OK != ret)
3912 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3915 ca_mutex_lock(g_threadMutex);
3916 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3917 ca_cond_signal(g_threadCond);
3918 CALEClientSetSendFinishFlag(true);
3919 ca_mutex_unlock(g_threadMutex);
3921 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3922 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3923 ca_cond_signal(g_threadWriteCharacteristicCond);
3924 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3926 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3927 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3928 ca_cond_signal(g_deviceScanRetryDelayCond);
3929 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3931 ca_cond_free(g_deviceDescCond);
3932 ca_cond_free(g_threadCond);
3933 ca_cond_free(g_threadWriteCharacteristicCond);
3934 ca_cond_free(g_deviceScanRetryDelayCond);
3936 g_deviceDescCond = NULL;
3937 g_threadCond = NULL;
3938 g_threadWriteCharacteristicCond = NULL;
3939 g_deviceScanRetryDelayCond = NULL;
3943 (*g_jvm)->DetachCurrentThread(g_jvm);
3948 CAResult_t CAInitializeLEGattClient()
3950 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3951 CALEClientInitialize();
3952 return CA_STATUS_OK;
3955 void CATerminateLEGattClient()
3957 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3958 CAStopLEGattClient();
3959 CALEClientTerminate();
3962 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3963 uint32_t dataLen, CALETransferType_t type,
3966 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3967 VERIFY_NON_NULL(data, TAG, "data is null");
3968 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3970 if (LE_UNICAST != type || position < 0)
3972 OIC_LOG(ERROR, TAG, "this request is not unicast");
3973 return CA_STATUS_INVALID_PARAM;
3976 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3979 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3981 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3982 VERIFY_NON_NULL(data, TAG, "data is null");
3984 return CALEClientSendMulticastMessage(data, dataLen);
3987 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3989 ca_mutex_lock(g_bleReqRespClientCbMutex);
3990 g_CABLEClientDataReceivedCallback = callback;
3991 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3994 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3996 g_threadPoolHandle = handle;
3999 CAResult_t CAGetLEAddress(char **local_address)
4001 VERIFY_NON_NULL(local_address, TAG, "local_address");
4002 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4003 return CA_NOT_SUPPORTED;
4006 JNIEXPORT void JNICALL
4007 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4010 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4011 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4012 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4013 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4015 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4018 JNIEXPORT void JNICALL
4019 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4022 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4023 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4024 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4025 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4027 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4030 JNIEXPORT void JNICALL
4031 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4034 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4035 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4036 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4038 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4039 if (CA_STATUS_OK != res)
4041 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4045 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4047 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4049 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4050 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4052 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4053 if (!jni_cid_gattdevice_list)
4055 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4059 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4060 METHODID_BT_DEVICE);
4061 if (!jni_mid_getDevice)
4063 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4067 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4068 if (!jni_obj_device)
4070 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4074 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4077 OIC_LOG(ERROR, TAG, "jni_address is null");
4081 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4086 * Class: org_iotivity_ca_jar_caleinterface
4087 * Method: CALeGattConnectionStateChangeCallback
4088 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4090 JNIEXPORT void JNICALL
4091 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4097 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4099 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4100 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4101 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4103 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4104 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4105 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4107 if (gatt_success == status && state_connected == newstate) // le connected
4109 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4115 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4118 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4119 STATE_CHARACTER_NO_CHANGE,
4121 if (CA_STATUS_OK != res)
4123 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4124 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4127 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4129 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4132 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4133 if (CA_STATUS_OK != res)
4135 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4139 res = CALEClientDiscoverServices(env, gatt);
4140 if (CA_STATUS_OK != res)
4142 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4146 else if (state_disconnected == newstate) // le disconnected
4148 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4151 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4155 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4158 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4159 STATE_CHARACTER_UNSET,
4161 if (CA_STATUS_OK != res)
4163 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4164 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4167 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4169 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4172 CAResult_t res = CALEClientGattClose(env, gatt);
4173 if (CA_STATUS_OK != res)
4175 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4178 if (gatt_success == status)
4180 // that state is a general reason to disconnect BLE.
4181 // its means manual disconnected message from BT platform.
4182 // in this case Scanning has to start again and clean previous data.
4183 CAResult_t res = CALEClientStartScan();
4184 if (CA_STATUS_OK != res)
4186 if (CA_ADAPTER_NOT_ENABLED == res)
4188 // scan will be started with start server when adapter is enabled
4189 OIC_LOG(INFO, TAG, "Adapter was disabled");
4193 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4198 else if (GATT_ERROR == status)
4200 // when we get GATT ERROR(0x85), gatt connection can be called again.
4201 OIC_LOG(INFO, TAG, "retry gatt connect");
4203 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4206 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4210 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4213 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4217 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4220 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4228 if (CALECheckConnectionStateValue(status))
4230 // this state is unexpected reason to disconnect
4231 // if the reason is suitable, connection logic of the device will be destroyed.
4232 OIC_LOG(INFO, TAG, "connection logic destroy");
4237 // other reason is expected to running background connection in BT platform.
4238 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4239 CALEClientUpdateSendCnt(env);
4246 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4247 g_sendBuffer = NULL;
4255 CALEClientSendFinish(env, gatt);
4260 * Class: org_iotivity_ca_jar_caleinterface
4261 * Method: CALeGattServicesDiscoveredCallback
4262 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4264 JNIEXPORT void JNICALL
4265 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4270 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4271 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4272 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4273 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4275 if (0 != status) // discovery error
4277 CALEClientSendFinish(env, gatt);
4281 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4284 CALEClientSendFinish(env, gatt);
4288 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4291 CALEClientSendFinish(env, gatt);
4295 if (!CALEClientIsSetCharacteristic(address))
4297 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4300 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4304 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4305 if (!jni_obj_GattCharacteristic)
4307 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4311 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4312 jni_obj_GattCharacteristic);
4313 if (CA_STATUS_OK != res)
4315 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4319 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4320 if (CA_STATUS_OK != res)
4322 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4325 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4326 if (CA_STATUS_OK != res)
4328 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4334 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4336 if (CA_STATUS_OK != res)
4338 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4346 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4347 if (CA_STATUS_OK != res)
4349 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4354 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4355 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4360 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4361 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4362 CALEClientSendFinish(env, gatt);
4367 * Class: org_iotivity_ca_jar_caleinterface
4368 * Method: CALeGattCharacteristicWritjclasseCallback
4369 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4371 JNIEXPORT void JNICALL
4372 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4373 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4376 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4377 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4378 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4379 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4381 // send success & signal
4382 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4388 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4394 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4395 if (gatt_success != status) // error case
4397 OIC_LOG(ERROR, TAG, "send failure");
4400 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4401 if (CA_STATUS_OK != res)
4403 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4404 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4405 g_isSignalSetFlag = true;
4406 ca_cond_signal(g_threadWriteCharacteristicCond);
4407 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4409 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4410 STATE_CHARACTER_SET,
4412 if (CA_STATUS_OK != res)
4414 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4417 if (g_clientErrorCallback)
4419 jint length = (*env)->GetArrayLength(env, data);
4420 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4423 CALEClientSendFinish(env, gatt);
4429 OIC_LOG(DEBUG, TAG, "send success");
4430 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4431 STATE_SEND_SUCCESS);
4432 if (CA_STATUS_OK != res)
4434 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4437 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4438 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4439 g_isSignalSetFlag = true;
4440 ca_cond_signal(g_threadWriteCharacteristicCond);
4441 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4443 CALEClientUpdateSendCnt(env);
4446 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4452 CALEClientSendFinish(env, gatt);
4457 * Class: org_iotivity_ca_jar_caleinterface
4458 * Method: CALeGattCharacteristicChangedCallback
4459 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4461 JNIEXPORT void JNICALL
4462 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4463 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4465 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4466 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4467 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4468 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4469 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4471 // get Byte Array and convert to uint8_t*
4472 jint length = (*env)->GetArrayLength(env, data);
4475 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4477 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4478 jni_byte_responseData);
4480 uint8_t* receivedData = OICMalloc(length);
4483 OIC_LOG(ERROR, TAG, "receivedData is null");
4487 memcpy(receivedData, jni_byte_responseData, length);
4488 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4490 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4493 OIC_LOG(ERROR, TAG, "jni_address is null");
4494 OICFree(receivedData);
4498 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4501 OIC_LOG(ERROR, TAG, "address is null");
4502 OICFree(receivedData);
4506 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4507 receivedData, length);
4509 ca_mutex_lock(g_bleServerBDAddressMutex);
4510 uint32_t sentLength = 0;
4511 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4513 ca_mutex_unlock(g_bleServerBDAddressMutex);
4515 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4519 * Class: org_iotivity_ca_jar_caleinterface
4520 * Method: CALeGattDescriptorWriteCallback
4521 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4523 JNIEXPORT void JNICALL
4524 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4528 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4529 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4530 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4531 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4533 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4534 if (gatt_success != status) // error
4541 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4542 if (CA_STATUS_OK != res)
4544 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4553 CALEClientSendFinish(env, gatt);