1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define GATT_CONNECTION_PRIORITY_BALANCED 0
46 #define GATT_FAILURE 257
47 #define GATT_INSUFFICIENT_AUTHENTICATION 5
48 #define GATT_INSUFFICIENT_ENCRYPTION 15
49 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
50 #define GATT_INVALID_OFFSET 7
51 #define GATT_READ_NOT_PERMITTED 2
52 #define GATT_REQUEST_NOT_SUPPORTED 6
53 #define GATT_WRITE_NOT_PERMITTED 3
55 static ca_thread_pool_t g_threadPoolHandle = NULL;
58 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
59 static u_arraylist_t *g_gattObjectList = NULL;
60 static u_arraylist_t *g_deviceStateList = NULL;
62 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
63 static CABLEErrorHandleCallback g_clientErrorCallback;
64 static jobject g_leScanCallback = NULL;
65 static jobject g_leGattCallback = NULL;
66 static jobject g_context = NULL;
67 static jobjectArray g_uuidList = NULL;
69 // it will be prevent to start send logic when adapter has stopped.
70 static bool g_isStartedLEClient = false;
71 static bool g_isStartedScan = false;
73 static jbyteArray g_sendBuffer = NULL;
74 static uint32_t g_targetCnt = 0;
75 static uint32_t g_currentSentCnt = 0;
76 static bool g_isFinishedSendData = false;
77 static ca_mutex g_SendFinishMutex = NULL;
78 static ca_mutex g_threadMutex = NULL;
79 static ca_cond g_threadCond = NULL;
80 static ca_cond g_deviceDescCond = NULL;
82 static ca_mutex g_threadSendMutex = NULL;
83 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
84 static ca_cond g_threadWriteCharacteristicCond = NULL;
85 static bool g_isSignalSetFlag = false;
87 static ca_mutex g_bleReqRespClientCbMutex = NULL;
88 static ca_mutex g_bleServerBDAddressMutex = NULL;
90 static ca_mutex g_deviceListMutex = NULL;
91 static ca_mutex g_gattObjectMutex = NULL;
92 static ca_mutex g_deviceStateListMutex = NULL;
94 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
95 static ca_cond g_deviceScanRetryDelayCond = NULL;
97 static ca_mutex g_scanMutex = NULL;
99 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
102 * check if retry logic for connection routine has to be stopped or not.
103 * in case of error value including this method, connection routine has to be stopped.
104 * since there is no retry logic for this error reason in this client.
105 * @param state constant value of bluetoothgatt.
106 * @return true - waiting for background connection in BT platform.
107 * false - connection routine has to be stopped.
109 static bool CALECheckConnectionStateValue(jint state)
113 case GATT_CONNECTION_PRIORITY_BALANCED:
115 case GATT_INSUFFICIENT_AUTHENTICATION:
116 case GATT_INSUFFICIENT_ENCRYPTION:
117 case GATT_INVALID_ATTRIBUTE_LENGTH:
118 case GATT_INVALID_OFFSET:
119 case GATT_READ_NOT_PERMITTED:
120 case GATT_REQUEST_NOT_SUPPORTED:
121 case GATT_WRITE_NOT_PERMITTED:
128 void CALEClientJniInit()
130 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
131 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
134 void CALEClientJNISetContext()
136 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
137 g_context = (jobject) CANativeJNIGetContext();
140 CAResult_t CALECreateJniInterfaceObject()
142 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
146 OIC_LOG(ERROR, TAG, "g_context is null");
147 return CA_STATUS_FAILED;
152 OIC_LOG(ERROR, TAG, "g_jvm is null");
153 return CA_STATUS_FAILED;
156 bool isAttached = false;
158 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
161 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
162 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
166 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
167 return CA_STATUS_FAILED;
172 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
173 if (!jni_LEInterface)
175 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
179 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
180 "(Landroid/content/Context;)V");
181 if (!LeInterfaceConstructorMethod)
183 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
187 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
188 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
192 (*g_jvm)->DetachCurrentThread(g_jvm);
201 (*g_jvm)->DetachCurrentThread(g_jvm);
204 return CA_STATUS_FAILED;
207 CAResult_t CALEClientInitialize()
209 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
215 OIC_LOG(ERROR, TAG, "g_jvm is null");
216 return CA_STATUS_FAILED;
219 bool isAttached = false;
221 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
224 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
225 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
229 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
230 return CA_STATUS_FAILED;
235 CAResult_t ret = CALECheckPlatformVersion(env, 18);
236 if (CA_STATUS_OK != ret)
238 OIC_LOG(ERROR, TAG, "it is not supported");
242 (*g_jvm)->DetachCurrentThread(g_jvm);
248 ret = CALEClientInitGattMutexVaraibles();
249 if (CA_STATUS_OK != ret)
251 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
252 CALEClientTerminateGattMutexVariables();
256 (*g_jvm)->DetachCurrentThread(g_jvm);
262 g_deviceDescCond = ca_cond_new();
264 // init mutex for send logic
265 g_threadCond = ca_cond_new();
266 g_threadWriteCharacteristicCond = ca_cond_new();
267 g_deviceScanRetryDelayCond = ca_cond_new();
269 CALEClientCreateDeviceList();
270 CALEClientJNISetContext();
272 ret = CALEClientCreateUUIDList();
273 if (CA_STATUS_OK != ret)
275 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
279 (*g_jvm)->DetachCurrentThread(g_jvm);
285 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
286 if (CA_STATUS_OK != ret)
288 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
292 (*g_jvm)->DetachCurrentThread(g_jvm);
297 g_isStartedLEClient = true;
301 (*g_jvm)->DetachCurrentThread(g_jvm);
307 void CALEClientTerminate()
309 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
313 OIC_LOG(ERROR, TAG, "g_jvm is null");
317 bool isAttached = false;
319 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
322 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
323 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
327 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
333 if (g_leScanCallback)
335 (*env)->DeleteGlobalRef(env, g_leScanCallback);
336 g_leScanCallback = NULL;
339 if (g_leGattCallback)
341 (*env)->DeleteGlobalRef(env, g_leGattCallback);
342 g_leGattCallback = NULL;
347 (*env)->DeleteGlobalRef(env, g_sendBuffer);
353 (*env)->DeleteGlobalRef(env, g_uuidList);
357 CAResult_t ret = CALEClientRemoveAllDeviceState();
358 if (CA_STATUS_OK != ret)
360 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
363 ret = CALEClientRemoveAllScanDevices(env);
364 if (CA_STATUS_OK != ret)
366 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
369 ret = CALEClientRemoveAllGattObjs(env);
370 if (CA_STATUS_OK != ret)
372 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
375 CALEClientSetScanFlag(false);
376 CALEClientSetSendFinishFlag(true);
378 CALEClientTerminateGattMutexVariables();
379 CALEClientDestroyJniInterface();
381 ca_cond_free(g_deviceDescCond);
382 ca_cond_free(g_threadCond);
383 ca_cond_free(g_threadWriteCharacteristicCond);
384 ca_cond_free(g_deviceScanRetryDelayCond);
386 g_deviceDescCond = NULL;
388 g_threadWriteCharacteristicCond = NULL;
389 g_deviceScanRetryDelayCond = NULL;
391 g_isSignalSetFlag = false;
395 (*g_jvm)->DetachCurrentThread(g_jvm);
399 CAResult_t CALEClientDestroyJniInterface()
401 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
405 OIC_LOG(ERROR, TAG, "g_jvm is null");
406 return CA_STATUS_FAILED;
409 bool isAttached = false;
411 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
414 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
415 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
419 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
420 return CA_STATUS_FAILED;
425 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
426 if (!jni_LeInterface)
428 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
432 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
433 "destroyLeInterface",
435 if (!jni_InterfaceDestroyMethod)
437 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
441 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
443 if ((*env)->ExceptionCheck(env))
445 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
446 (*env)->ExceptionDescribe(env);
447 (*env)->ExceptionClear(env);
451 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
455 (*g_jvm)->DetachCurrentThread(g_jvm);
464 (*g_jvm)->DetachCurrentThread(g_jvm);
467 return CA_STATUS_FAILED;
470 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
472 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
473 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
477 CAResult_t res = CALEClientDisconnect(env, gatt);
478 if (CA_STATUS_OK != res)
480 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
483 CALEClientUpdateSendCnt(env);
486 CAResult_t CALEClientSendUnicastMessage(const char* address,
488 const uint32_t dataLen)
490 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
491 VERIFY_NON_NULL(address, TAG, "address is null");
492 VERIFY_NON_NULL(data, TAG, "data is null");
494 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
497 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
498 const uint32_t dataLen)
500 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
501 VERIFY_NON_NULL(data, TAG, "data is null");
505 OIC_LOG(ERROR, TAG, "g_jvm is null");
506 return CA_STATUS_FAILED;
509 bool isAttached = false;
511 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
514 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
515 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
519 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
520 return CA_STATUS_FAILED;
525 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
526 if (CA_STATUS_OK != ret)
528 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
533 (*g_jvm)->DetachCurrentThread(g_jvm);
539 CAResult_t CALEClientStartUnicastServer(const char* address)
541 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
543 return CA_NOT_SUPPORTED;
546 CAResult_t CALEClientStartMulticastServer()
548 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
550 return CA_NOT_SUPPORTED;
553 void CALEClientStopUnicastServer()
555 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
558 void CALEClientStopMulticastServer()
560 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
563 void CALEClientSetCallback(CAPacketReceiveCallback callback)
565 g_packetReceiveCallback = callback;
568 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
570 g_clientErrorCallback = callback;
573 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
575 VERIFY_NON_NULL(env, TAG, "env");
579 return CA_STATUS_FAILED;
582 if (0 == u_arraylist_length(g_deviceList) // multicast
583 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
585 // Wait for LE peripherals to be discovered.
587 // Number of times to wait for discovery to complete.
588 static size_t const RETRIES = 5;
590 static uint64_t const TIMEOUT =
591 2 * MICROSECS_PER_SEC; // Microseconds
593 bool devicesDiscovered = false;
594 for (size_t i = 0; i < RETRIES; ++i)
596 OIC_LOG(DEBUG, TAG, "waiting for target device");
597 if (ca_cond_wait_for(g_deviceDescCond,
599 TIMEOUT) == CA_WAIT_SUCCESS)
601 ca_mutex_lock(g_deviceListMutex);
602 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
603 ca_mutex_unlock(g_deviceListMutex);
605 if (0 < scannedDeviceLen)
607 if (!address // multicast
608 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
610 devicesDiscovered = true;
617 OIC_LOG(INFO, TAG, "waiting..");
619 ca_mutex_lock(g_deviceScanRetryDelayMutex);
620 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
621 g_deviceScanRetryDelayMutex,
622 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
624 OIC_LOG(INFO, TAG, "finish to waiting for target device");
625 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
628 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
631 // checking whether a target device is found while waiting for time-out.
632 if (CALEClientIsDeviceInScanDeviceList(env, address))
634 devicesDiscovered = true;
643 // time out for scanning devices
644 if (!devicesDiscovered)
646 return CA_STATUS_FAILED;
654 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
655 const uint32_t dataLen)
657 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
659 VERIFY_NON_NULL(address, TAG, "address is null");
660 VERIFY_NON_NULL(data, TAG, "data is null");
664 OIC_LOG(ERROR, TAG, "g_jvm is null");
665 return CA_STATUS_FAILED;
668 bool isAttached = false;
670 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
673 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
674 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
677 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
678 return CA_STATUS_FAILED;
683 ca_mutex_lock(g_threadSendMutex);
685 CALEClientSetSendFinishFlag(false);
687 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
688 if (CA_STATUS_OK != ret)
690 OIC_LOG(INFO, TAG, "there is no scanned device");
694 if (g_context && g_deviceList)
696 uint32_t length = u_arraylist_length(g_deviceList);
697 for (uint32_t index = 0; index < length; index++)
699 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
702 OIC_LOG(ERROR, TAG, "jarrayObj is null");
706 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
709 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
713 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
716 OIC_LOG(ERROR, TAG, "setAddress is null");
720 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
722 if (!strcmp(setAddress, address))
724 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
726 // connect to gatt server
727 ret = CALEClientStopScan();
728 if (CA_STATUS_OK != ret)
730 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
736 (*env)->DeleteGlobalRef(env, g_sendBuffer);
739 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
740 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
741 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
743 // Target device to send message is just one.
746 ret = CALEClientSendData(env, jarrayObj);
747 if (CA_STATUS_OK != ret)
749 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
753 OIC_LOG(INFO, TAG, "wake up");
756 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
760 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
762 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
763 // if there is no connection state.
764 ca_mutex_lock(g_threadMutex);
765 if (!g_isFinishedSendData)
767 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
768 ca_cond_wait(g_threadCond, g_threadMutex);
769 OIC_LOG(DEBUG, TAG, "the data was sent");
771 ca_mutex_unlock(g_threadMutex);
775 (*g_jvm)->DetachCurrentThread(g_jvm);
778 // start LE Scan again
779 ret = CALEClientStartScan();
780 if (CA_STATUS_OK != ret)
782 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
783 ca_mutex_unlock(g_threadSendMutex);
787 ca_mutex_unlock(g_threadSendMutex);
788 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
789 return CALECheckSendState(address);
794 // start LE Scan again
795 ret = CALEClientStartScan();
796 if (CA_STATUS_OK != ret)
798 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
799 ca_mutex_unlock(g_threadSendMutex);
802 (*g_jvm)->DetachCurrentThread(g_jvm);
809 (*g_jvm)->DetachCurrentThread(g_jvm);
812 if (g_clientErrorCallback)
814 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
816 ca_mutex_unlock(g_threadSendMutex);
817 return CA_SEND_FAILED;
820 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
821 const uint32_t dataLen)
823 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
824 VERIFY_NON_NULL(data, TAG, "data is null");
825 VERIFY_NON_NULL(env, TAG, "env is null");
829 OIC_LOG(ERROR, TAG, "g_deviceList is null");
830 return CA_STATUS_FAILED;
833 ca_mutex_lock(g_threadSendMutex);
835 CALEClientSetSendFinishFlag(false);
837 OIC_LOG(DEBUG, TAG, "set byteArray for data");
840 (*env)->DeleteGlobalRef(env, g_sendBuffer);
844 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
845 if (CA_STATUS_OK != res)
847 OIC_LOG(INFO, TAG, "there is no scanned device");
851 // connect to gatt server
852 res = CALEClientStopScan();
853 if (CA_STATUS_OK != res)
855 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
856 ca_mutex_unlock(g_threadSendMutex);
859 uint32_t length = u_arraylist_length(g_deviceList);
860 g_targetCnt = length;
862 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
863 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
864 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
866 for (uint32_t index = 0; index < length; index++)
868 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
871 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
875 res = CALEClientSendData(env, jarrayObj);
876 if (res != CA_STATUS_OK)
878 OIC_LOG(ERROR, TAG, "BT device - send has failed");
881 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
884 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
888 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
891 OIC_LOG(ERROR, TAG, "address is not available");
895 (*env)->ReleaseStringUTFChars(env, jni_address, address);
898 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
900 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
901 ca_mutex_lock(g_threadMutex);
902 if (!g_isFinishedSendData)
904 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
905 ca_cond_wait(g_threadCond, g_threadMutex);
906 OIC_LOG(DEBUG, TAG, "the data was sent");
908 ca_mutex_unlock(g_threadMutex);
910 // start LE Scan again
911 res = CALEClientStartScan();
912 if (CA_STATUS_OK != res)
914 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
915 ca_mutex_unlock(g_threadSendMutex);
919 ca_mutex_unlock(g_threadSendMutex);
920 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
924 res = CALEClientStartScan();
925 if (CA_STATUS_OK != res)
927 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
928 ca_mutex_unlock(g_threadSendMutex);
932 ca_mutex_unlock(g_threadSendMutex);
933 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
934 return CA_SEND_FAILED;
937 CAResult_t CALECheckSendState(const char* address)
939 VERIFY_NON_NULL(address, TAG, "address is null");
941 ca_mutex_lock(g_deviceStateListMutex);
942 CALEState_t* state = CALEClientGetStateInfo(address);
945 OIC_LOG(ERROR, TAG, "state is null");
946 ca_mutex_unlock(g_deviceStateListMutex);
947 return CA_SEND_FAILED;
950 if (STATE_SEND_SUCCESS != state->sendState)
952 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
953 ca_mutex_unlock(g_deviceStateListMutex);
954 return CA_SEND_FAILED;
957 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
958 ca_mutex_unlock(g_deviceStateListMutex);
962 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
964 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
965 VERIFY_NON_NULL(device, TAG, "device is null");
966 VERIFY_NON_NULL(env, TAG, "env is null");
968 // get BLE address from bluetooth device object.
969 char* address = NULL;
970 CALEState_t* state = NULL;
971 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
974 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
975 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
978 OIC_LOG(ERROR, TAG, "address is not available");
979 return CA_STATUS_FAILED;
981 ca_mutex_lock(g_deviceStateListMutex);
982 state = CALEClientGetStateInfo(address);
983 ca_mutex_unlock(g_deviceStateListMutex);
984 (*env)->ReleaseStringUTFChars(env, jni_address, address);
989 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
991 // cancel previous connection request before connection
992 // if there is gatt object in g_gattObjectList.
995 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
998 OIC_LOG(ERROR, TAG, "address is not available");
999 return CA_STATUS_FAILED;
1002 jobject gatt = CALEClientGetGattObjInList(env, address);
1005 CAResult_t res = CALEClientDisconnect(env, gatt);
1006 if (CA_STATUS_OK != res)
1008 OIC_LOG(INFO, TAG, "there is no gatt object");
1011 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1014 // connection request
1015 jobject newGatt = CALEClientConnect(env, device,
1017 if (NULL == newGatt)
1019 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1020 return CA_STATUS_FAILED;
1025 if (STATE_CONNECTED == state->connectedState)
1027 OIC_LOG(INFO, TAG, "GATT has already connected");
1030 OIC_LOG(ERROR, TAG, "jni_address is not available");
1031 return CA_STATUS_FAILED;
1034 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1037 OIC_LOG(ERROR, TAG, "address is not available");
1038 return CA_STATUS_FAILED;
1041 jobject gatt = CALEClientGetGattObjInList(env, address);
1044 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1045 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1046 return CA_STATUS_FAILED;
1049 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1050 if (CA_STATUS_OK != ret)
1052 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1053 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1056 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1060 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1062 // cancel previous connection request before connection
1063 // if there is gatt object in g_gattObjectList.
1066 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1069 OIC_LOG(ERROR, TAG, "address is not available");
1070 return CA_STATUS_FAILED;
1073 jobject gatt = CALEClientGetGattObjInList(env, address);
1076 CAResult_t res = CALEClientDisconnect(env, gatt);
1077 if (CA_STATUS_OK != res)
1079 OIC_LOG(INFO, TAG, "there is no gatt object");
1082 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1085 OIC_LOG(DEBUG, TAG, "start to connect LE");
1086 jobject gatt = CALEClientConnect(env, device,
1087 CALEClientGetAutoConnectFlag(env, jni_address));
1090 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1091 return CA_STATUS_FAILED;
1096 return CA_STATUS_OK;
1099 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1101 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1102 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1104 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1105 if (!jni_cid_gattdevice_list)
1107 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1111 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1112 "()Landroid/bluetooth/BluetoothDevice;");
1113 if (!jni_mid_getDevice)
1115 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1119 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1120 if (!jni_obj_device)
1122 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1126 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1129 OIC_LOG(ERROR, TAG, "jni_address is null");
1139 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1142 OIC_LOG(DEBUG, TAG, "Gatt Close");
1143 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1144 VERIFY_NON_NULL(env, TAG, "env is null");
1146 // get BluetoothGatt class
1147 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1148 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1149 if (!jni_cid_BluetoothGatt)
1151 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1152 return CA_STATUS_FAILED;
1155 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1156 if (!jni_mid_closeGatt)
1158 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1159 return CA_STATUS_OK;
1162 // call disconnect gatt method
1163 OIC_LOG(DEBUG, TAG, "request to close GATT");
1164 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1166 if ((*env)->ExceptionCheck(env))
1168 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1169 (*env)->ExceptionDescribe(env);
1170 (*env)->ExceptionClear(env);
1171 return CA_STATUS_FAILED;
1174 return CA_STATUS_OK;
1177 CAResult_t CALEClientStartScan()
1179 if (!g_isStartedLEClient)
1181 OIC_LOG(ERROR, TAG, "LE client is not started");
1182 return CA_STATUS_FAILED;
1187 OIC_LOG(ERROR, TAG, "g_jvm is null");
1188 return CA_STATUS_FAILED;
1191 if (g_isStartedScan)
1193 OIC_LOG(INFO, TAG, "scanning is already started");
1194 return CA_STATUS_OK;
1197 bool isAttached = false;
1199 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1202 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1204 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1207 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1208 return CA_STATUS_FAILED;
1213 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1215 CAResult_t ret = CA_STATUS_OK;
1216 // scan gatt server with UUID
1217 if (g_leScanCallback && g_uuidList)
1220 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1222 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1224 if (CA_STATUS_OK != ret)
1226 if (CA_ADAPTER_NOT_ENABLED == ret)
1228 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1232 OIC_LOG(ERROR, TAG, "start scan has failed");
1239 (*g_jvm)->DetachCurrentThread(g_jvm);
1245 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1247 VERIFY_NON_NULL(callback, TAG, "callback is null");
1248 VERIFY_NON_NULL(env, TAG, "env is null");
1250 if (!CALEIsEnableBTAdapter(env))
1252 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1253 return CA_ADAPTER_NOT_ENABLED;
1256 // get default bt adapter class
1257 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1258 if (!jni_cid_BTAdapter)
1260 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1261 return CA_STATUS_FAILED;
1264 // get remote bt adapter method
1265 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1266 "getDefaultAdapter",
1267 METHODID_OBJECTNONPARAM);
1268 if (!jni_mid_getDefaultAdapter)
1270 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1271 return CA_STATUS_FAILED;
1274 // get start le scan method
1275 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1276 "(Landroid/bluetooth/BluetoothAdapter$"
1277 "LeScanCallback;)Z");
1278 if (!jni_mid_startLeScan)
1280 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1281 return CA_STATUS_FAILED;
1284 // gat bt adapter object
1285 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1286 jni_mid_getDefaultAdapter);
1287 if (!jni_obj_BTAdapter)
1289 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1290 return CA_STATUS_FAILED;
1293 // call start le scan method
1294 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1295 jni_mid_startLeScan, callback);
1296 if (!jni_obj_startLeScan)
1298 OIC_LOG(INFO, TAG, "startLeScan is failed");
1302 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1303 CALEClientSetScanFlag(true);
1306 return CA_STATUS_OK;
1309 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1311 VERIFY_NON_NULL(callback, TAG, "callback is null");
1312 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1313 VERIFY_NON_NULL(env, TAG, "env is null");
1315 if (!CALEIsEnableBTAdapter(env))
1317 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1318 return CA_ADAPTER_NOT_ENABLED;
1321 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1322 if (!jni_cid_BTAdapter)
1324 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1325 return CA_STATUS_FAILED;
1328 // get remote bt adapter method
1329 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1330 "getDefaultAdapter",
1331 METHODID_OBJECTNONPARAM);
1332 if (!jni_mid_getDefaultAdapter)
1334 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1335 return CA_STATUS_FAILED;
1338 // get start le scan method
1339 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1340 "([Ljava/util/UUID;Landroid/bluetooth/"
1341 "BluetoothAdapter$LeScanCallback;)Z");
1342 if (!jni_mid_startLeScan)
1344 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1345 return CA_STATUS_FAILED;
1348 // get bt adapter object
1349 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1350 jni_mid_getDefaultAdapter);
1351 if (!jni_obj_BTAdapter)
1353 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1354 return CA_STATUS_FAILED;
1357 // call start le scan method
1358 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1359 jni_mid_startLeScan, uuids, callback);
1360 if (!jni_obj_startLeScan)
1362 OIC_LOG(INFO, TAG, "startLeScan With UUID is failed");
1366 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1367 CALEClientSetScanFlag(true);
1370 return CA_STATUS_OK;
1373 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1375 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1376 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1379 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1382 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1386 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1387 "(Ljava/lang/String;)"
1388 "Ljava/util/UUID;");
1389 if (!jni_mid_fromString)
1391 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1395 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1396 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1400 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1404 return jni_obj_uuid;
1407 CAResult_t CALEClientStopScan()
1411 OIC_LOG(ERROR, TAG, "g_jvm is null");
1412 return CA_STATUS_FAILED;
1415 if (!g_isStartedScan)
1417 OIC_LOG(INFO, TAG, "scanning is already stopped");
1418 return CA_STATUS_OK;
1421 bool isAttached = false;
1423 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1426 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1427 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1430 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1431 return CA_STATUS_FAILED;
1436 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1437 if (CA_STATUS_OK != ret)
1439 if (CA_ADAPTER_NOT_ENABLED == ret)
1441 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1445 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1450 CALEClientSetScanFlag(false);
1455 (*g_jvm)->DetachCurrentThread(g_jvm);
1461 void CALEClientSetScanFlag(bool flag)
1463 ca_mutex_lock(g_scanMutex);
1464 g_isStartedScan = flag;
1465 ca_mutex_unlock(g_scanMutex);
1468 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1470 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1471 VERIFY_NON_NULL(callback, TAG, "callback is null");
1472 VERIFY_NON_NULL(env, TAG, "env is null");
1474 if (!CALEIsEnableBTAdapter(env))
1476 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1477 return CA_ADAPTER_NOT_ENABLED;
1480 // get default bt adapter class
1481 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1482 if (!jni_cid_BTAdapter)
1484 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1485 return CA_STATUS_FAILED;
1488 // get remote bt adapter method
1489 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1490 "getDefaultAdapter",
1491 METHODID_OBJECTNONPARAM);
1492 if (!jni_mid_getDefaultAdapter)
1494 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1495 return CA_STATUS_FAILED;
1498 // get start le scan method
1499 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1500 "(Landroid/bluetooth/"
1501 "BluetoothAdapter$LeScanCallback;)V");
1502 if (!jni_mid_stopLeScan)
1504 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1505 return CA_STATUS_FAILED;
1508 // gat bt adapter object
1509 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1510 jni_mid_getDefaultAdapter);
1511 if (!jni_obj_BTAdapter)
1513 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1514 return CA_STATUS_FAILED;
1517 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1518 // call start le scan method
1519 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1520 if ((*env)->ExceptionCheck(env))
1522 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1523 (*env)->ExceptionDescribe(env);
1524 (*env)->ExceptionClear(env);
1525 return CA_STATUS_FAILED;
1528 return CA_STATUS_OK;
1531 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1533 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1534 VERIFY_NON_NULL(env, TAG, "env");
1535 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1537 ca_mutex_lock(g_deviceStateListMutex);
1539 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1542 OIC_LOG(ERROR, TAG, "address is not available");
1543 return CA_STATUS_FAILED;
1546 if (CALEClientIsDeviceInList(address))
1548 CALEState_t* curState = CALEClientGetStateInfo(address);
1551 OIC_LOG(ERROR, TAG, "curState is null");
1552 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1553 ca_mutex_unlock(g_deviceStateListMutex);
1554 return CA_STATUS_FAILED;
1556 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1558 curState->autoConnectFlag = flag;
1561 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1562 ca_mutex_unlock(g_deviceStateListMutex);
1563 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1564 return CA_STATUS_OK;
1567 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1569 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1570 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1571 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1573 ca_mutex_lock(g_deviceStateListMutex);
1575 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1578 OIC_LOG(ERROR, TAG, "address is not available");
1582 CALEState_t* curState = CALEClientGetStateInfo(address);
1585 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1586 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1587 ca_mutex_unlock(g_deviceStateListMutex);
1590 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1592 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1593 ca_mutex_unlock(g_deviceStateListMutex);
1595 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1596 return curState->autoConnectFlag;
1599 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1601 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1602 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1603 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1605 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1606 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1609 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1612 OIC_LOG(ERROR, TAG, "address is not available");
1616 // close the gatt service
1617 jobject gatt = CALEClientGetGattObjInList(env, address);
1620 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1621 if (CA_STATUS_OK != res)
1623 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1624 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1628 // clean previous gatt object after close profile service
1629 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1630 if (CA_STATUS_OK != res)
1632 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1633 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1637 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1640 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1643 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1647 // add new gatt object into g_gattObjectList
1648 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1649 if (CA_STATUS_OK != res)
1651 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1658 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1660 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1661 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1662 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1664 if (!g_leGattCallback)
1666 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1670 if (!CALEIsEnableBTAdapter(env))
1672 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1676 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1679 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1683 // get BluetoothDevice class
1684 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1685 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1686 if (!jni_cid_BluetoothDevice)
1688 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1692 // get connectGatt method
1693 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1694 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1695 "(Landroid/content/Context;ZLandroid/"
1696 "bluetooth/BluetoothGattCallback;)"
1697 "Landroid/bluetooth/BluetoothGatt;");
1698 if (!jni_mid_connectGatt)
1700 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1704 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1705 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1706 jni_mid_connectGatt,
1708 autoconnect, g_leGattCallback);
1709 if (!jni_obj_connectGatt)
1711 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1712 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1713 CALEClientUpdateSendCnt(env);
1718 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1720 return jni_obj_connectGatt;
1723 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1725 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1727 VERIFY_NON_NULL(env, TAG, "env is null");
1728 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1730 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1731 if (!jni_cid_BTAdapter)
1733 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1734 return CA_STATUS_FAILED;
1737 // get remote bt adapter method
1738 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1739 "getDefaultAdapter",
1740 METHODID_OBJECTNONPARAM);
1741 if (!jni_mid_getDefaultAdapter)
1743 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1744 return CA_STATUS_FAILED;
1747 // gat bt adapter object
1748 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1749 jni_mid_getDefaultAdapter);
1750 if (!jni_obj_BTAdapter)
1752 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1753 return CA_STATUS_FAILED;
1756 // get closeProfileProxy method
1757 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1758 "closeProfileProxy",
1759 "(ILandroid/bluetooth/"
1760 "BluetoothProfile;)V");
1761 if (!jni_mid_closeProfileProxy)
1763 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1764 return CA_STATUS_FAILED;
1767 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1768 if (!jni_cid_BTProfile)
1770 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1771 return CA_STATUS_FAILED;
1774 // GATT - Constant value : 7 (0x00000007)
1775 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1779 OIC_LOG(ERROR, TAG, "id_gatt is null");
1780 return CA_STATUS_FAILED;
1783 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1785 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1786 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1787 if ((*env)->ExceptionCheck(env))
1789 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1790 (*env)->ExceptionDescribe(env);
1791 (*env)->ExceptionClear(env);
1792 return CA_STATUS_FAILED;
1795 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1796 return CA_STATUS_OK;
1800 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1802 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1803 VERIFY_NON_NULL(env, TAG, "env is null");
1804 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1806 // get BluetoothGatt class
1807 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1808 if (!jni_cid_BluetoothGatt)
1810 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1811 return CA_STATUS_FAILED;
1814 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1815 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1816 "disconnect", "()V");
1817 if (!jni_mid_disconnectGatt)
1819 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1820 return CA_STATUS_FAILED;
1823 // call disconnect gatt method
1824 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1825 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1826 if ((*env)->ExceptionCheck(env))
1828 OIC_LOG(ERROR, TAG, "disconnect has failed");
1829 (*env)->ExceptionDescribe(env);
1830 (*env)->ExceptionClear(env);
1831 return CA_STATUS_FAILED;
1834 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1836 return CA_STATUS_OK;
1839 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1841 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1842 VERIFY_NON_NULL(env, TAG, "env is null");
1844 if (!g_gattObjectList)
1846 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1847 return CA_STATUS_OK;
1850 uint32_t length = u_arraylist_length(g_gattObjectList);
1851 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1852 for (uint32_t index = 0; index < length; index++)
1854 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1855 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1858 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1861 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1862 if (CA_STATUS_OK != res)
1864 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1869 return CA_STATUS_OK;
1872 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1874 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1875 VERIFY_NON_NULL(env, TAG, "env is null");
1877 if (!g_gattObjectList)
1879 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1880 return CA_STATUS_OK;
1883 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1886 OIC_LOG(ERROR, TAG, "address is null");
1887 return CA_STATUS_FAILED;
1890 uint32_t length = u_arraylist_length(g_gattObjectList);
1891 for (uint32_t index = 0; index < length; index++)
1893 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1896 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1900 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1901 if (!jni_setAddress)
1903 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1904 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1905 return CA_STATUS_FAILED;
1908 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1911 OIC_LOG(ERROR, TAG, "setAddress is null");
1912 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1913 return CA_STATUS_FAILED;
1916 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1917 if (!strcmp(address, setAddress))
1919 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1920 if (CA_STATUS_OK != res)
1922 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1923 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1924 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1925 return CA_STATUS_FAILED;
1927 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1928 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1929 return CA_STATUS_OK;
1931 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1933 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1935 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1936 return CA_STATUS_OK;
1939 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1941 VERIFY_NON_NULL(env, TAG, "env is null");
1942 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1944 if (!CALEIsEnableBTAdapter(env))
1946 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1947 return CA_ADAPTER_NOT_ENABLED;
1950 // get BluetoothGatt class
1951 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1952 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1953 if (!jni_cid_BluetoothGatt)
1955 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1956 return CA_STATUS_FAILED;
1959 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1960 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1961 "discoverServices", "()Z");
1962 if (!jni_mid_discoverServices)
1964 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1965 return CA_STATUS_FAILED;
1967 // call disconnect gatt method
1968 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1969 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1972 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1973 return CA_STATUS_FAILED;
1976 return CA_STATUS_OK;
1979 static void CALEWriteCharacteristicThread(void* object)
1981 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1983 bool isAttached = false;
1985 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1988 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1989 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1993 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1999 jobject gatt = (jobject)object;
2000 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2001 if (CA_STATUS_OK != ret)
2003 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2008 (*g_jvm)->DetachCurrentThread(g_jvm);
2012 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2014 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2015 VERIFY_NON_NULL(env, TAG, "env is null");
2018 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2019 if (!jni_obj_character)
2021 CALEClientSendFinish(env, gatt);
2022 return CA_STATUS_FAILED;
2025 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2026 if (CA_STATUS_OK != ret)
2028 CALEClientSendFinish(env, gatt);
2029 return CA_STATUS_FAILED;
2032 // wait for callback for write Characteristic with success to sent data
2033 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2034 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2035 if (!g_isSignalSetFlag)
2037 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2038 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2039 g_threadWriteCharacteristicMutex,
2040 WAIT_TIME_WRITE_CHARACTERISTIC))
2042 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2043 g_isSignalSetFlag = false;
2044 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2045 return CA_STATUS_FAILED;
2048 // reset flag set by writeCharacteristic Callback
2049 g_isSignalSetFlag = false;
2050 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2052 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2053 return CA_STATUS_OK;
2056 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2058 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2059 VERIFY_NON_NULL(env, TAG, "env is null");
2060 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2062 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2063 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2064 CALEWriteCharacteristicThread, (void*)gattParam))
2066 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2067 return CA_STATUS_FAILED;
2070 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2071 return CA_STATUS_OK;
2074 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2075 jobject gattCharacteristic)
2077 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2078 VERIFY_NON_NULL(env, TAG, "env is null");
2079 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2080 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2082 if (!CALEIsEnableBTAdapter(env))
2084 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2085 return CA_STATUS_FAILED;
2088 // get BluetoothGatt class
2089 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2090 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2091 if (!jni_cid_BluetoothGatt)
2093 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2094 return CA_STATUS_FAILED;
2097 OIC_LOG(DEBUG, TAG, "write characteristic method");
2098 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2099 "writeCharacteristic",
2100 "(Landroid/bluetooth/"
2101 "BluetoothGattCharacteristic;)Z");
2102 if (!jni_mid_writeCharacteristic)
2104 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2105 return CA_STATUS_FAILED;
2108 // call disconnect gatt method
2109 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2110 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2111 jni_mid_writeCharacteristic,
2112 gattCharacteristic);
2115 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2119 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2120 return CA_STATUS_FAILED;
2123 return CA_STATUS_OK;
2126 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2128 VERIFY_NON_NULL(env, TAG, "env is null");
2129 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2131 if (!CALEIsEnableBTAdapter(env))
2133 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2134 return CA_STATUS_FAILED;
2137 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2138 if (!jni_cid_BluetoothGatt)
2140 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2141 return CA_STATUS_FAILED;
2144 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2147 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2148 return CA_STATUS_FAILED;
2151 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2152 if (!jni_obj_GattCharacteristic)
2154 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2155 return CA_STATUS_FAILED;
2158 OIC_LOG(DEBUG, TAG, "read characteristic method");
2159 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2160 "readCharacteristic",
2161 "(Landroid/bluetooth/"
2162 "BluetoothGattCharacteristic;)Z");
2163 if (!jni_mid_readCharacteristic)
2165 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2166 return CA_STATUS_FAILED;
2169 // call disconnect gatt method
2170 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2171 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2172 jni_obj_GattCharacteristic);
2175 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2179 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2180 return CA_STATUS_FAILED;
2183 return CA_STATUS_OK;
2186 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2187 jobject characteristic)
2189 VERIFY_NON_NULL(env, TAG, "env is null");
2190 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2191 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2193 if (!CALEIsEnableBTAdapter(env))
2195 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2196 return CA_ADAPTER_NOT_ENABLED;
2199 // get BluetoothGatt class
2200 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2201 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2202 if (!jni_cid_BluetoothGatt)
2204 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2205 return CA_STATUS_FAILED;
2208 // set Characteristic Notification
2209 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2210 "setCharacteristicNotification",
2211 "(Landroid/bluetooth/"
2212 "BluetoothGattCharacteristic;Z)Z");
2213 if (!jni_mid_setNotification)
2215 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2216 return CA_STATUS_FAILED;
2219 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2220 characteristic, JNI_TRUE);
2221 if (JNI_TRUE == ret)
2223 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2227 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2228 return CA_STATUS_FAILED;
2231 return CA_STATUS_OK;
2234 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2236 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2237 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2238 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2240 if (!CALEIsEnableBTAdapter(env))
2242 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2246 // get BluetoothGatt class
2247 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2248 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2249 if (!jni_cid_BluetoothGatt)
2251 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2255 jmethodID jni_mid_getService = (*env)->GetMethodID(
2256 env, jni_cid_BluetoothGatt, "getService",
2257 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2258 if (!jni_mid_getService)
2260 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2264 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2265 if (!jni_obj_service_uuid)
2267 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2271 // get bluetooth gatt service
2272 OIC_LOG(DEBUG, TAG, "request to get service");
2273 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2274 jni_obj_service_uuid);
2275 if (!jni_obj_gattService)
2277 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2281 // get bluetooth gatt service class
2282 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2283 env, "android/bluetooth/BluetoothGattService");
2284 if (!jni_cid_BluetoothGattService)
2286 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2290 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2291 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2292 "getCharacteristic",
2293 "(Ljava/util/UUID;)"
2294 "Landroid/bluetooth/"
2295 "BluetoothGattCharacteristic;");
2296 if (!jni_mid_getCharacteristic)
2298 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2302 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2305 OIC_LOG(ERROR, TAG, "uuid is null");
2309 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2310 if (!jni_obj_tx_uuid)
2312 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2313 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2317 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2318 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2319 jni_mid_getCharacteristic,
2322 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2323 return jni_obj_GattCharacteristic;
2326 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2328 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2329 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2330 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2331 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2333 if (!CALEIsEnableBTAdapter(env))
2335 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2339 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2342 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2346 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2347 if (!jni_obj_GattCharacteristic)
2349 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2353 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2354 "/BluetoothGattCharacteristic");
2355 if (!jni_cid_BTGattCharacteristic)
2357 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2361 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2362 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2364 if (!jni_mid_setValue)
2366 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2370 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2372 if (JNI_TRUE == ret)
2374 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2378 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2383 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2384 "setWriteType", "(I)V");
2385 if (!jni_mid_setWriteType)
2387 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2391 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2392 "WRITE_TYPE_NO_RESPONSE", "I");
2393 if (!jni_fid_no_response)
2395 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2399 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2400 jni_fid_no_response);
2402 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2404 return jni_obj_GattCharacteristic;
2407 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2409 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2410 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2412 if (!CALEIsEnableBTAdapter(env))
2414 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2418 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2419 "BluetoothGattCharacteristic");
2420 if (!jni_cid_BTGattCharacteristic)
2422 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2426 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2427 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2429 if (!jni_mid_getValue)
2431 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2435 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2437 return jni_obj_data_array;
2440 CAResult_t CALEClientCreateUUIDList()
2444 OIC_LOG(ERROR, TAG, "g_jvm is null");
2445 return CA_STATUS_FAILED;
2448 bool isAttached = false;
2450 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2453 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2454 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2458 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2459 return CA_STATUS_FAILED;
2464 // create new object array
2465 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2466 if (!jni_cid_uuid_list)
2468 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2472 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2473 jni_cid_uuid_list, NULL);
2474 if (!jni_obj_uuid_list)
2476 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2481 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2484 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2487 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2489 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2493 (*g_jvm)->DetachCurrentThread(g_jvm);
2496 return CA_STATUS_OK;
2503 (*g_jvm)->DetachCurrentThread(g_jvm);
2505 return CA_STATUS_FAILED;
2508 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2509 jobject characteristic)
2511 VERIFY_NON_NULL(env, TAG, "env is null");
2512 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2513 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2515 if (!CALEIsEnableBTAdapter(env))
2517 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2518 return CA_ADAPTER_NOT_ENABLED;
2521 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2522 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2523 "BluetoothGattCharacteristic");
2524 if (!jni_cid_BTGattCharacteristic)
2526 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2527 return CA_STATUS_FAILED;
2530 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2531 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2533 "(Ljava/util/UUID;)Landroid/bluetooth/"
2534 "BluetoothGattDescriptor;");
2535 if (!jni_mid_getDescriptor)
2537 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2538 return CA_STATUS_FAILED;
2541 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2542 if (!jni_obj_cc_uuid)
2544 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2545 return CA_STATUS_FAILED;
2548 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2549 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2550 jni_mid_getDescriptor, jni_obj_cc_uuid);
2551 if (!jni_obj_descriptor)
2553 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2554 return CA_NOT_SUPPORTED;
2557 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2558 jclass jni_cid_descriptor = (*env)->FindClass(env,
2559 "android/bluetooth/BluetoothGattDescriptor");
2560 if (!jni_cid_descriptor)
2562 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2563 return CA_STATUS_FAILED;
2566 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2567 if (!jni_mid_setValue)
2569 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2570 return CA_STATUS_FAILED;
2573 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2574 "ENABLE_NOTIFICATION_VALUE", "[B");
2575 if (!jni_fid_NotiValue)
2577 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2578 return CA_STATUS_FAILED;
2581 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2583 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2584 env, jni_obj_descriptor, jni_mid_setValue,
2585 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2588 OIC_LOG(DEBUG, TAG, "setValue success");
2592 OIC_LOG(ERROR, TAG, "setValue has failed");
2593 return CA_STATUS_FAILED;
2596 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2599 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2600 return CA_STATUS_FAILED;
2603 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2604 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2605 "(Landroid/bluetooth/"
2606 "BluetoothGattDescriptor;)Z");
2607 if (!jni_mid_writeDescriptor)
2609 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2610 return CA_STATUS_FAILED;
2613 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2614 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2615 jni_obj_descriptor);
2618 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2622 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2623 return CA_STATUS_FAILED;
2626 return CA_STATUS_OK;
2629 void CALEClientCreateScanDeviceList(JNIEnv *env)
2631 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2632 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2634 ca_mutex_lock(g_deviceListMutex);
2635 // create new object array
2636 if (g_deviceList == NULL)
2638 OIC_LOG(DEBUG, TAG, "Create device list");
2640 g_deviceList = u_arraylist_create();
2642 ca_mutex_unlock(g_deviceListMutex);
2645 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2647 VERIFY_NON_NULL(device, TAG, "device is null");
2648 VERIFY_NON_NULL(env, TAG, "env is null");
2650 ca_mutex_lock(g_deviceListMutex);
2654 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2656 CALEClientSetScanFlag(false);
2657 if(CA_STATUS_OK != CALEClientStopScan())
2659 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2662 ca_mutex_unlock(g_deviceListMutex);
2663 return CA_STATUS_FAILED;
2666 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2667 if (!jni_remoteAddress)
2669 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2670 ca_mutex_unlock(g_deviceListMutex);
2671 return CA_STATUS_FAILED;
2674 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2677 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2678 ca_mutex_unlock(g_deviceListMutex);
2679 return CA_STATUS_FAILED;
2682 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2684 jobject gdevice = (*env)->NewGlobalRef(env, device);
2685 u_arraylist_add(g_deviceList, gdevice);
2686 ca_cond_signal(g_deviceDescCond);
2687 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2689 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2691 ca_mutex_unlock(g_deviceListMutex);
2693 return CA_STATUS_OK;
2696 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2698 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2699 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2703 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2707 uint32_t length = u_arraylist_length(g_deviceList);
2708 for (uint32_t index = 0; index < length; index++)
2710 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2713 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2717 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2718 if (!jni_setAddress)
2720 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2724 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2727 OIC_LOG(ERROR, TAG, "setAddress is null");
2731 if (!strcmp(remoteAddress, setAddress))
2733 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2737 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2740 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2745 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2747 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2748 VERIFY_NON_NULL(env, TAG, "env is null");
2750 ca_mutex_lock(g_deviceListMutex);
2754 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2755 ca_mutex_unlock(g_deviceListMutex);
2756 return CA_STATUS_FAILED;
2759 uint32_t length = u_arraylist_length(g_deviceList);
2760 for (uint32_t index = 0; index < length; index++)
2762 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2765 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2768 (*env)->DeleteGlobalRef(env, jarrayObj);
2772 OICFree(g_deviceList);
2773 g_deviceList = NULL;
2775 ca_mutex_unlock(g_deviceListMutex);
2776 return CA_STATUS_OK;
2779 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2781 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2782 VERIFY_NON_NULL(address, TAG, "address is null");
2783 VERIFY_NON_NULL(env, TAG, "env is null");
2785 ca_mutex_lock(g_deviceListMutex);
2789 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2790 ca_mutex_unlock(g_deviceListMutex);
2791 return CA_STATUS_FAILED;
2794 uint32_t length = u_arraylist_length(g_deviceList);
2795 for (uint32_t index = 0; index < length; index++)
2797 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2800 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2801 ca_mutex_unlock(g_deviceListMutex);
2802 return CA_STATUS_FAILED;
2805 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2806 if (!jni_setAddress)
2808 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2809 ca_mutex_unlock(g_deviceListMutex);
2810 return CA_STATUS_FAILED;
2813 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2816 OIC_LOG(ERROR, TAG, "setAddress is null");
2817 ca_mutex_unlock(g_deviceListMutex);
2818 return CA_STATUS_FAILED;
2821 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2824 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2825 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2826 ca_mutex_unlock(g_deviceListMutex);
2827 return CA_STATUS_FAILED;
2830 if (!strcmp(setAddress, remoteAddress))
2832 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2833 (*env)->DeleteGlobalRef(env, jarrayObj);
2835 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2836 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2838 if (NULL == u_arraylist_remove(g_deviceList, index))
2840 OIC_LOG(ERROR, TAG, "List removal failed.");
2841 ca_mutex_unlock(g_deviceListMutex);
2842 return CA_STATUS_FAILED;
2844 ca_mutex_unlock(g_deviceListMutex);
2845 return CA_STATUS_OK;
2847 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2848 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2851 ca_mutex_unlock(g_deviceListMutex);
2852 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2854 return CA_STATUS_OK;
2861 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2863 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2864 VERIFY_NON_NULL(env, TAG, "env is null");
2865 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2867 ca_mutex_lock(g_gattObjectMutex);
2869 if (!g_gattObjectList)
2871 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2872 ca_mutex_unlock(g_gattObjectMutex);
2873 return CA_STATUS_FAILED;
2876 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2877 if (!jni_remoteAddress)
2879 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2880 ca_mutex_unlock(g_gattObjectMutex);
2881 return CA_STATUS_FAILED;
2884 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2887 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2888 ca_mutex_unlock(g_gattObjectMutex);
2889 return CA_STATUS_FAILED;
2892 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2893 if (!CALEClientIsGattObjInList(env, remoteAddress))
2895 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2896 u_arraylist_add(g_gattObjectList, newGatt);
2897 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2900 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2901 ca_mutex_unlock(g_gattObjectMutex);
2902 return CA_STATUS_OK;
2905 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2907 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2908 VERIFY_NON_NULL(env, TAG, "env is null");
2909 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2911 uint32_t length = u_arraylist_length(g_gattObjectList);
2912 for (uint32_t index = 0; index < length; index++)
2915 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2918 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2922 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2923 if (!jni_setAddress)
2925 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2929 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2932 OIC_LOG(ERROR, TAG, "setAddress is null");
2936 if (!strcmp(remoteAddress, setAddress))
2938 OIC_LOG(DEBUG, TAG, "the device is already set");
2939 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2944 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2949 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2953 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2955 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2956 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2957 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2959 ca_mutex_lock(g_gattObjectMutex);
2960 uint32_t length = u_arraylist_length(g_gattObjectList);
2961 for (uint32_t index = 0; index < length; index++)
2963 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2966 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2967 ca_mutex_unlock(g_gattObjectMutex);
2971 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2972 if (!jni_setAddress)
2974 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2975 ca_mutex_unlock(g_gattObjectMutex);
2979 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2982 OIC_LOG(ERROR, TAG, "setAddress is null");
2983 ca_mutex_unlock(g_gattObjectMutex);
2987 if (!strcmp(remoteAddress, setAddress))
2989 OIC_LOG(DEBUG, TAG, "the device is already set");
2990 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2991 ca_mutex_unlock(g_gattObjectMutex);
2994 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2997 ca_mutex_unlock(g_gattObjectMutex);
2998 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3002 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3004 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3005 VERIFY_NON_NULL(env, TAG, "env is null");
3007 ca_mutex_lock(g_gattObjectMutex);
3008 if (!g_gattObjectList)
3010 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3011 ca_mutex_unlock(g_gattObjectMutex);
3012 return CA_STATUS_OK;
3015 uint32_t length = u_arraylist_length(g_gattObjectList);
3016 for (uint32_t index = 0; index < length; index++)
3018 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3021 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3024 (*env)->DeleteGlobalRef(env, jarrayObj);
3028 OICFree(g_gattObjectList);
3029 g_gattObjectList = NULL;
3030 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3031 ca_mutex_unlock(g_gattObjectMutex);
3032 return CA_STATUS_OK;
3035 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3037 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3038 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3039 VERIFY_NON_NULL(env, TAG, "env is null");
3041 ca_mutex_lock(g_gattObjectMutex);
3042 if (!g_gattObjectList)
3044 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3045 ca_mutex_unlock(g_gattObjectMutex);
3046 return CA_STATUS_OK;
3049 uint32_t length = u_arraylist_length(g_gattObjectList);
3050 for (uint32_t index = 0; index < length; index++)
3052 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3055 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3056 ca_mutex_unlock(g_gattObjectMutex);
3057 return CA_STATUS_FAILED;
3060 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3061 if (!jni_setAddress)
3063 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3064 ca_mutex_unlock(g_gattObjectMutex);
3065 return CA_STATUS_FAILED;
3068 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3071 OIC_LOG(ERROR, TAG, "setAddress is null");
3072 ca_mutex_unlock(g_gattObjectMutex);
3073 return CA_STATUS_FAILED;
3076 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3077 if (!jni_remoteAddress)
3079 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3080 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3081 ca_mutex_unlock(g_gattObjectMutex);
3082 return CA_STATUS_FAILED;
3085 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3088 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3089 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3090 ca_mutex_unlock(g_gattObjectMutex);
3091 return CA_STATUS_FAILED;
3094 if (!strcmp(setAddress, remoteAddress))
3096 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3097 (*env)->DeleteGlobalRef(env, jarrayObj);
3099 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3100 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3102 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3104 OIC_LOG(ERROR, TAG, "List removal failed.");
3105 ca_mutex_unlock(g_gattObjectMutex);
3106 return CA_STATUS_FAILED;
3108 ca_mutex_unlock(g_gattObjectMutex);
3109 return CA_STATUS_OK;
3111 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3112 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3115 ca_mutex_unlock(g_gattObjectMutex);
3116 OIC_LOG(DEBUG, TAG, "there are no target object");
3117 return CA_STATUS_OK;
3120 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3122 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3123 VERIFY_NON_NULL(addr, TAG, "addr is null");
3124 VERIFY_NON_NULL(env, TAG, "env is null");
3126 ca_mutex_lock(g_gattObjectMutex);
3127 if (!g_gattObjectList)
3129 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3130 ca_mutex_unlock(g_gattObjectMutex);
3131 return CA_STATUS_OK;
3134 uint32_t length = u_arraylist_length(g_gattObjectList);
3135 for (uint32_t index = 0; index < length; index++)
3137 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3140 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3141 ca_mutex_unlock(g_gattObjectMutex);
3142 return CA_STATUS_FAILED;
3145 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3146 if (!jni_setAddress)
3148 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3149 ca_mutex_unlock(g_gattObjectMutex);
3150 return CA_STATUS_FAILED;
3153 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3156 OIC_LOG(ERROR, TAG, "setAddress is null");
3157 ca_mutex_unlock(g_gattObjectMutex);
3158 return CA_STATUS_FAILED;
3161 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3164 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3165 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3166 ca_mutex_unlock(g_gattObjectMutex);
3167 return CA_STATUS_FAILED;
3170 if (!strcmp(setAddress, remoteAddress))
3172 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3173 (*env)->DeleteGlobalRef(env, jarrayObj);
3175 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3176 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3177 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3179 OIC_LOG(ERROR, TAG, "List removal failed.");
3180 ca_mutex_unlock(g_gattObjectMutex);
3181 return CA_STATUS_FAILED;
3183 ca_mutex_unlock(g_gattObjectMutex);
3184 return CA_STATUS_OK;
3186 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3187 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3190 ca_mutex_unlock(g_gattObjectMutex);
3191 OIC_LOG(DEBUG, TAG, "there are no target object");
3192 return CA_STATUS_FAILED;
3195 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3197 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3199 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3200 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3202 // get Bluetooth Address
3203 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3204 if (!jni_btTargetAddress)
3206 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3210 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3213 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3217 // get method ID of getDevice()
3218 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3219 if (!jni_cid_gattdevice_list)
3221 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3222 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3226 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3227 METHODID_BT_DEVICE);
3228 if (!jni_mid_getDevice)
3230 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3231 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3235 size_t length = u_arraylist_length(g_gattObjectList);
3236 for (size_t index = 0; index < length; index++)
3238 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3241 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3242 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3246 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3247 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3248 if (!jni_obj_device)
3250 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3251 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3255 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3258 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3259 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3263 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3266 OIC_LOG(ERROR, TAG, "btAddress is not available");
3267 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3271 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3272 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3273 if (!strcmp(targetAddress, btAddress))
3275 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3278 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3281 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3283 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3284 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3285 (*env)->DeleteLocalRef(env, jni_btAddress);
3286 (*env)->DeleteLocalRef(env, jni_obj_device);
3287 return jni_LEAddress;
3289 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3290 (*env)->DeleteLocalRef(env, jni_btAddress);
3291 (*env)->DeleteLocalRef(env, jni_obj_device);
3294 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3302 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3303 uint16_t notificationState, uint16_t sendState)
3305 VERIFY_NON_NULL(address, TAG, "address is null");
3307 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3310 OIC_LOG(ERROR, TAG, "out of memory");
3311 return CA_MEMORY_ALLOC_FAILED;
3314 if (strlen(address) > CA_MACADDR_SIZE)
3316 OIC_LOG(ERROR, TAG, "address is not proper");
3318 return CA_STATUS_FAILED;
3321 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3322 newstate->connectedState = connectedState;
3323 newstate->notificationState = notificationState;
3324 newstate->sendState = sendState;
3325 return CALEClientAddDeviceStateToList(newstate);
3328 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3330 VERIFY_NON_NULL(state, TAG, "state is null");
3332 ca_mutex_lock(g_deviceStateListMutex);
3334 if (!g_deviceStateList)
3336 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3337 ca_mutex_unlock(g_deviceStateListMutex);
3338 return CA_STATUS_FAILED;
3341 if (CALEClientIsDeviceInList(state->address))
3343 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3346 OIC_LOG(ERROR, TAG, "curState is null");
3347 ca_mutex_unlock(g_deviceStateListMutex);
3348 return CA_STATUS_FAILED;
3351 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3353 state->notificationState = curState->notificationState;
3355 state->autoConnectFlag = curState->autoConnectFlag;
3357 // delete previous state for update new state
3358 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3359 if (CA_STATUS_OK != res)
3361 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3362 ca_mutex_unlock(g_deviceStateListMutex);
3366 u_arraylist_add(g_deviceStateList, state); // update new state
3367 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
3368 state->connectedState, state->notificationState,
3369 state->address, state->autoConnectFlag);
3371 ca_mutex_unlock(g_deviceStateListMutex);
3372 return CA_STATUS_OK;
3375 bool CALEClientIsDeviceInList(const char* remoteAddress)
3377 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3379 if (!g_deviceStateList)
3381 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3385 uint32_t length = u_arraylist_length(g_deviceStateList);
3386 for (uint32_t index = 0; index < length; index++)
3388 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3391 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3395 if (!strcmp(remoteAddress, state->address))
3397 OIC_LOG(DEBUG, TAG, "the device is already set");
3406 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3410 CAResult_t CALEClientRemoveAllDeviceState()
3412 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3414 ca_mutex_lock(g_deviceStateListMutex);
3415 if (!g_deviceStateList)
3417 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3418 ca_mutex_unlock(g_deviceStateListMutex);
3419 return CA_STATUS_FAILED;
3422 uint32_t length = u_arraylist_length(g_deviceStateList);
3423 for (uint32_t index = 0; index < length; index++)
3425 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3428 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3434 OICFree(g_deviceStateList);
3435 g_deviceStateList = NULL;
3436 ca_mutex_unlock(g_deviceStateListMutex);
3438 return CA_STATUS_OK;
3441 CAResult_t CALEClientResetDeviceStateForAll()
3443 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3445 ca_mutex_lock(g_deviceStateListMutex);
3446 if (!g_deviceStateList)
3448 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3449 ca_mutex_unlock(g_deviceStateListMutex);
3450 return CA_STATUS_FAILED;
3453 size_t length = u_arraylist_length(g_deviceStateList);
3454 for (size_t index = 0; index < length; index++)
3456 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3459 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3463 // autoConnectFlag value will be not changed,
3464 // since it has reset only termination case.
3465 state->connectedState = STATE_DISCONNECTED;
3466 state->notificationState = STATE_CHARACTER_UNSET;
3467 state->sendState = STATE_SEND_NONE;
3469 ca_mutex_unlock(g_deviceStateListMutex);
3471 return CA_STATUS_OK;
3474 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3476 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3477 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3479 if (!g_deviceStateList)
3481 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3482 return CA_STATUS_FAILED;
3485 uint32_t length = u_arraylist_length(g_deviceStateList);
3486 for (uint32_t index = 0; index < length; index++)
3488 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3491 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3495 if (!strcmp(state->address, remoteAddress))
3497 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3499 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3501 if (NULL == targetState)
3503 OIC_LOG(ERROR, TAG, "List removal failed.");
3504 return CA_STATUS_FAILED;
3507 OICFree(targetState);
3508 return CA_STATUS_OK;
3512 return CA_STATUS_OK;
3515 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3517 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3518 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3520 if (!g_deviceStateList)
3522 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3526 uint32_t length = u_arraylist_length(g_deviceStateList);
3527 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3529 for (uint32_t index = 0; index < length; index++)
3531 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3534 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3538 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3539 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3541 if (!strcmp(state->address, remoteAddress))
3543 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3550 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3552 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3553 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3555 ca_mutex_lock(g_deviceStateListMutex);
3556 if (!g_deviceStateList)
3558 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3559 ca_mutex_unlock(g_deviceStateListMutex);
3563 uint32_t length = u_arraylist_length(g_deviceStateList);
3564 for (uint32_t index = 0; index < length; index++)
3566 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3569 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3573 if (!strcmp(state->address, remoteAddress))
3575 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3577 if (STATE_CONNECTED == state->connectedState)
3579 ca_mutex_unlock(g_deviceStateListMutex);
3584 ca_mutex_unlock(g_deviceStateListMutex);
3589 ca_mutex_unlock(g_deviceStateListMutex);
3593 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3595 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3596 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3598 ca_mutex_lock(g_deviceStateListMutex);
3599 if (!g_deviceStateList)
3601 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3602 ca_mutex_unlock(g_deviceStateListMutex);
3606 uint32_t length = u_arraylist_length(g_deviceStateList);
3607 for (uint32_t index = 0; index < length; index++)
3609 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3612 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3616 if (!strcmp(state->address, remoteAddress))
3618 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3620 if (STATE_CHARACTER_SET == state->notificationState)
3622 ca_mutex_unlock(g_deviceStateListMutex);
3627 ca_mutex_unlock(g_deviceStateListMutex);
3633 ca_mutex_unlock(g_deviceStateListMutex);
3637 void CALEClientCreateDeviceList()
3639 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3641 // create new object array
3642 if (!g_gattObjectList)
3644 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3646 g_gattObjectList = u_arraylist_create();
3649 if (!g_deviceStateList)
3651 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3653 g_deviceStateList = u_arraylist_create();
3658 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3660 g_deviceList = u_arraylist_create();
3665 * Check Sent Count for remove g_sendBuffer
3667 void CALEClientUpdateSendCnt(JNIEnv *env)
3669 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3671 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3673 ca_mutex_lock(g_threadMutex);
3677 if (g_targetCnt <= g_currentSentCnt)
3680 g_currentSentCnt = 0;
3684 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3685 g_sendBuffer = NULL;
3687 // notity the thread
3688 ca_cond_signal(g_threadCond);
3690 CALEClientSetSendFinishFlag(true);
3691 OIC_LOG(DEBUG, TAG, "set signal for send data");
3694 ca_mutex_unlock(g_threadMutex);
3697 CAResult_t CALEClientInitGattMutexVaraibles()
3699 if (NULL == g_bleReqRespClientCbMutex)
3701 g_bleReqRespClientCbMutex = ca_mutex_new();
3702 if (NULL == g_bleReqRespClientCbMutex)
3704 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3705 return CA_STATUS_FAILED;
3709 if (NULL == g_bleServerBDAddressMutex)
3711 g_bleServerBDAddressMutex = ca_mutex_new();
3712 if (NULL == g_bleServerBDAddressMutex)
3714 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3715 return CA_STATUS_FAILED;
3719 if (NULL == g_threadMutex)
3721 g_threadMutex = ca_mutex_new();
3722 if (NULL == g_threadMutex)
3724 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3725 return CA_STATUS_FAILED;
3729 if (NULL == g_threadSendMutex)
3731 g_threadSendMutex = ca_mutex_new();
3732 if (NULL == g_threadSendMutex)
3734 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3735 return CA_STATUS_FAILED;
3739 if (NULL == g_deviceListMutex)
3741 g_deviceListMutex = ca_mutex_new();
3742 if (NULL == g_deviceListMutex)
3744 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3745 return CA_STATUS_FAILED;
3749 if (NULL == g_gattObjectMutex)
3751 g_gattObjectMutex = ca_mutex_new();
3752 if (NULL == g_gattObjectMutex)
3754 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3755 return CA_STATUS_FAILED;
3759 if (NULL == g_deviceStateListMutex)
3761 g_deviceStateListMutex = ca_mutex_new();
3762 if (NULL == g_deviceStateListMutex)
3764 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3765 return CA_STATUS_FAILED;
3769 if (NULL == g_SendFinishMutex)
3771 g_SendFinishMutex = ca_mutex_new();
3772 if (NULL == g_SendFinishMutex)
3774 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3775 return CA_STATUS_FAILED;
3779 if (NULL == g_scanMutex)
3781 g_scanMutex = ca_mutex_new();
3782 if (NULL == g_scanMutex)
3784 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3785 return CA_STATUS_FAILED;
3789 if (NULL == g_threadWriteCharacteristicMutex)
3791 g_threadWriteCharacteristicMutex = ca_mutex_new();
3792 if (NULL == g_threadWriteCharacteristicMutex)
3794 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3795 return CA_STATUS_FAILED;
3799 if (NULL == g_deviceScanRetryDelayMutex)
3801 g_deviceScanRetryDelayMutex = ca_mutex_new();
3802 if (NULL == g_deviceScanRetryDelayMutex)
3804 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3805 return CA_STATUS_FAILED;
3809 return CA_STATUS_OK;
3812 void CALEClientTerminateGattMutexVariables()
3814 ca_mutex_free(g_bleReqRespClientCbMutex);
3815 g_bleReqRespClientCbMutex = NULL;
3817 ca_mutex_free(g_bleServerBDAddressMutex);
3818 g_bleServerBDAddressMutex = NULL;
3820 ca_mutex_free(g_threadMutex);
3821 g_threadMutex = NULL;
3823 ca_mutex_free(g_threadSendMutex);
3824 g_threadSendMutex = NULL;
3826 ca_mutex_free(g_deviceListMutex);
3827 g_deviceListMutex = NULL;
3829 ca_mutex_free(g_SendFinishMutex);
3830 g_SendFinishMutex = NULL;
3832 ca_mutex_free(g_scanMutex);
3835 ca_mutex_free(g_threadWriteCharacteristicMutex);
3836 g_threadWriteCharacteristicMutex = NULL;
3838 ca_mutex_free(g_deviceScanRetryDelayMutex);
3839 g_deviceScanRetryDelayMutex = NULL;
3842 void CALEClientSetSendFinishFlag(bool flag)
3844 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3846 ca_mutex_lock(g_SendFinishMutex);
3847 g_isFinishedSendData = flag;
3848 ca_mutex_unlock(g_SendFinishMutex);
3855 CAResult_t CAStartLEGattClient()
3857 // init mutex for send logic
3858 if (!g_deviceDescCond)
3860 g_deviceDescCond = ca_cond_new();
3865 g_threadCond = ca_cond_new();
3868 if (!g_threadWriteCharacteristicCond)
3870 g_threadWriteCharacteristicCond = ca_cond_new();
3873 CAResult_t ret = CALEClientStartScan();
3874 if (CA_STATUS_OK != ret)
3876 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3880 g_isStartedLEClient = true;
3881 return CA_STATUS_OK;
3884 void CAStopLEGattClient()
3886 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3890 OIC_LOG(ERROR, TAG, "g_jvm is null");
3894 bool isAttached = false;
3896 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3899 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3900 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3904 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3910 CAResult_t ret = CALEClientDisconnectAll(env);
3911 if (CA_STATUS_OK != ret)
3913 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3916 ret = CALEClientStopScan();
3917 if(CA_STATUS_OK != ret)
3919 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3922 ca_mutex_lock(g_threadMutex);
3923 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3924 ca_cond_signal(g_threadCond);
3925 CALEClientSetSendFinishFlag(true);
3926 ca_mutex_unlock(g_threadMutex);
3928 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3929 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3930 ca_cond_signal(g_threadWriteCharacteristicCond);
3931 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3933 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3934 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3935 ca_cond_signal(g_deviceScanRetryDelayCond);
3936 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3938 ca_cond_free(g_deviceDescCond);
3939 ca_cond_free(g_threadCond);
3940 ca_cond_free(g_threadWriteCharacteristicCond);
3941 ca_cond_free(g_deviceScanRetryDelayCond);
3943 g_deviceDescCond = NULL;
3944 g_threadCond = NULL;
3945 g_threadWriteCharacteristicCond = NULL;
3946 g_deviceScanRetryDelayCond = NULL;
3950 (*g_jvm)->DetachCurrentThread(g_jvm);
3955 CAResult_t CAInitializeLEGattClient()
3957 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3958 CALEClientInitialize();
3959 return CA_STATUS_OK;
3962 void CATerminateLEGattClient()
3964 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3965 CAStopLEGattClient();
3966 CALEClientTerminate();
3969 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3970 uint32_t dataLen, CALETransferType_t type,
3973 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3974 VERIFY_NON_NULL(data, TAG, "data is null");
3975 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3977 if (LE_UNICAST != type || position < 0)
3979 OIC_LOG(ERROR, TAG, "this request is not unicast");
3980 return CA_STATUS_INVALID_PARAM;
3983 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3986 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3988 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3989 VERIFY_NON_NULL(data, TAG, "data is null");
3991 return CALEClientSendMulticastMessage(data, dataLen);
3994 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3996 ca_mutex_lock(g_bleReqRespClientCbMutex);
3997 g_CABLEClientDataReceivedCallback = callback;
3998 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4001 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4003 g_threadPoolHandle = handle;
4006 CAResult_t CAGetLEAddress(char **local_address)
4008 VERIFY_NON_NULL(local_address, TAG, "local_address");
4009 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4010 return CA_NOT_SUPPORTED;
4013 JNIEXPORT void JNICALL
4014 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4017 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4018 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4019 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4020 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4022 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4025 JNIEXPORT void JNICALL
4026 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4029 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4030 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4031 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4032 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4034 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4037 JNIEXPORT void JNICALL
4038 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4041 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4042 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4043 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4045 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4046 if (CA_STATUS_OK != res)
4048 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4052 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4054 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4056 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4057 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4059 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4060 if (!jni_cid_gattdevice_list)
4062 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4066 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4067 METHODID_BT_DEVICE);
4068 if (!jni_mid_getDevice)
4070 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4074 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4075 if (!jni_obj_device)
4077 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4081 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4084 OIC_LOG(ERROR, TAG, "jni_address is null");
4088 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4093 * Class: org_iotivity_ca_jar_caleinterface
4094 * Method: CALeGattConnectionStateChangeCallback
4095 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4097 JNIEXPORT void JNICALL
4098 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4104 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4106 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4107 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4108 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4110 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4111 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4112 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4114 if (gatt_success == status && state_connected == newstate) // le connected
4116 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4122 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4125 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4126 STATE_CHARACTER_NO_CHANGE,
4128 if (CA_STATUS_OK != res)
4130 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4131 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4134 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4136 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4139 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4140 if (CA_STATUS_OK != res)
4142 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4146 res = CALEClientDiscoverServices(env, gatt);
4147 if (CA_STATUS_OK != res)
4149 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4153 else if (state_disconnected == newstate) // le disconnected
4155 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4158 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4162 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4165 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4166 STATE_CHARACTER_UNSET,
4168 if (CA_STATUS_OK != res)
4170 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4171 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4174 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4176 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4179 CAResult_t res = CALEClientGattClose(env, gatt);
4180 if (CA_STATUS_OK != res)
4182 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4185 if (GATT_ERROR == status)
4187 // when we get GATT ERROR(0x85), gatt connection can be called again.
4188 OIC_LOG(INFO, TAG, "retry gatt connect");
4190 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4193 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4197 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4200 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4204 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4207 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4215 if (CALECheckConnectionStateValue(status))
4217 // this state is unexpected reason to disconnect
4218 // if the reason is suitable, connection logic of the device will be destroyed.
4219 OIC_LOG(INFO, TAG, "connection logic destroy");
4224 // other reason except for gatt_success is expected to running
4225 // background connection in BT platform.
4226 OIC_LOG(INFO, TAG, "unknown state or manual disconnected state");
4227 CALEClientUpdateSendCnt(env);
4234 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4235 g_sendBuffer = NULL;
4243 CALEClientSendFinish(env, gatt);
4248 * Class: org_iotivity_ca_jar_caleinterface
4249 * Method: CALeGattServicesDiscoveredCallback
4250 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4252 JNIEXPORT void JNICALL
4253 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4258 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4259 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4260 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4261 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4263 if (0 != status) // discovery error
4265 CALEClientSendFinish(env, gatt);
4269 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4272 CALEClientSendFinish(env, gatt);
4276 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4279 CALEClientSendFinish(env, gatt);
4283 if (!CALEClientIsSetCharacteristic(address))
4285 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4288 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4292 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4293 if (!jni_obj_GattCharacteristic)
4295 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4299 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4300 jni_obj_GattCharacteristic);
4301 if (CA_STATUS_OK != res)
4303 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4307 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4308 if (CA_STATUS_OK != res)
4310 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4313 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4314 if (CA_STATUS_OK != res)
4316 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4322 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4324 if (CA_STATUS_OK != res)
4326 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4334 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4335 if (CA_STATUS_OK != res)
4337 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4342 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4343 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4348 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4349 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4350 CALEClientSendFinish(env, gatt);
4355 * Class: org_iotivity_ca_jar_caleinterface
4356 * Method: CALeGattCharacteristicWritjclasseCallback
4357 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4359 JNIEXPORT void JNICALL
4360 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4361 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4364 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4365 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4366 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4367 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4369 // send success & signal
4370 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4376 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4382 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4383 if (gatt_success != status) // error case
4385 OIC_LOG(ERROR, TAG, "send failure");
4388 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4389 if (CA_STATUS_OK != res)
4391 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4392 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4393 g_isSignalSetFlag = true;
4394 ca_cond_signal(g_threadWriteCharacteristicCond);
4395 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4397 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4398 STATE_CHARACTER_SET,
4400 if (CA_STATUS_OK != res)
4402 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4405 if (g_clientErrorCallback)
4407 jint length = (*env)->GetArrayLength(env, data);
4408 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4411 CALEClientSendFinish(env, gatt);
4417 OIC_LOG(DEBUG, TAG, "send success");
4418 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4419 STATE_SEND_SUCCESS);
4420 if (CA_STATUS_OK != res)
4422 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4425 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4426 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4427 g_isSignalSetFlag = true;
4428 ca_cond_signal(g_threadWriteCharacteristicCond);
4429 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4431 CALEClientUpdateSendCnt(env);
4434 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4440 CALEClientSendFinish(env, gatt);
4445 * Class: org_iotivity_ca_jar_caleinterface
4446 * Method: CALeGattCharacteristicChangedCallback
4447 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4449 JNIEXPORT void JNICALL
4450 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4451 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4453 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4454 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4455 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4456 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4457 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4459 // get Byte Array and convert to uint8_t*
4460 jint length = (*env)->GetArrayLength(env, data);
4463 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4465 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4466 jni_byte_responseData);
4468 uint8_t* receivedData = OICMalloc(length);
4471 OIC_LOG(ERROR, TAG, "receivedData is null");
4475 memcpy(receivedData, jni_byte_responseData, length);
4476 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4478 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4481 OIC_LOG(ERROR, TAG, "jni_address is null");
4482 OICFree(receivedData);
4486 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4489 OIC_LOG(ERROR, TAG, "address is null");
4490 OICFree(receivedData);
4494 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4495 receivedData, length);
4497 ca_mutex_lock(g_bleServerBDAddressMutex);
4498 uint32_t sentLength = 0;
4499 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4501 ca_mutex_unlock(g_bleServerBDAddressMutex);
4503 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4507 * Class: org_iotivity_ca_jar_caleinterface
4508 * Method: CALeGattDescriptorWriteCallback
4509 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4511 JNIEXPORT void JNICALL
4512 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4516 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4517 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4518 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4519 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4521 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4522 if (gatt_success != status) // error
4529 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4530 if (CA_STATUS_OK != res)
4532 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4541 CALEClientSendFinish(env, gatt);