1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define GATT_CONNECTION_PRIORITY_BALANCED 0
46 #define GATT_FAILURE 257
47 #define GATT_INSUFFICIENT_AUTHENTICATION 5
48 #define GATT_INSUFFICIENT_ENCRYPTION 15
49 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
50 #define GATT_INVALID_OFFSET 7
51 #define GATT_READ_NOT_PERMITTED 2
52 #define GATT_REQUEST_NOT_SUPPORTED 6
53 #define GATT_WRITE_NOT_PERMITTED 3
55 static ca_thread_pool_t g_threadPoolHandle = NULL;
58 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
59 static u_arraylist_t *g_gattObjectList = NULL;
60 static u_arraylist_t *g_deviceStateList = NULL;
62 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
63 static CABLEErrorHandleCallback g_clientErrorCallback;
64 static jobject g_leScanCallback = NULL;
65 static jobject g_leGattCallback = NULL;
66 static jobject g_context = NULL;
67 static jobjectArray g_uuidList = NULL;
69 // it will be prevent to start send logic when adapter has stopped.
70 static bool g_isStartedLEClient = false;
71 static bool g_isStartedMulticastServer = false;
72 static bool g_isStartedScan = false;
74 static jbyteArray g_sendBuffer = NULL;
75 static uint32_t g_targetCnt = 0;
76 static uint32_t g_currentSentCnt = 0;
77 static bool g_isFinishedSendData = false;
78 static ca_mutex g_SendFinishMutex = NULL;
79 static ca_mutex g_threadMutex = NULL;
80 static ca_cond g_threadCond = NULL;
81 static ca_cond g_deviceDescCond = NULL;
83 static ca_mutex g_threadSendMutex = NULL;
84 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
85 static ca_cond g_threadWriteCharacteristicCond = NULL;
86 static bool g_isSignalSetFlag = false;
88 static ca_mutex g_bleReqRespClientCbMutex = NULL;
89 static ca_mutex g_bleServerBDAddressMutex = NULL;
91 static ca_mutex g_deviceListMutex = NULL;
92 static ca_mutex g_gattObjectMutex = NULL;
93 static ca_mutex g_deviceStateListMutex = NULL;
95 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
96 static ca_cond g_deviceScanRetryDelayCond = NULL;
98 static ca_mutex g_scanMutex = NULL;
100 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
103 * check if retry logic for connection routine has to be stopped or not.
104 * in case of error value including this method, connection routine has to be stopped.
105 * since there is no retry logic for this error reason in this client.
106 * @param state constant value of bluetoothgatt.
107 * @return true - waiting for background connection in BT platform.
108 * false - connection routine has to be stopped.
110 static bool CALECheckConnectionStateValue(jint state)
114 case GATT_CONNECTION_PRIORITY_BALANCED:
116 case GATT_INSUFFICIENT_AUTHENTICATION:
117 case GATT_INSUFFICIENT_ENCRYPTION:
118 case GATT_INVALID_ATTRIBUTE_LENGTH:
119 case GATT_INVALID_OFFSET:
120 case GATT_READ_NOT_PERMITTED:
121 case GATT_REQUEST_NOT_SUPPORTED:
122 case GATT_WRITE_NOT_PERMITTED:
129 void CALEClientJniInit()
131 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
132 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
135 void CALEClientJNISetContext()
137 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
138 g_context = (jobject) CANativeJNIGetContext();
141 CAResult_t CALECreateJniInterfaceObject()
143 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
147 OIC_LOG(ERROR, TAG, "g_context is null");
148 return CA_STATUS_FAILED;
153 OIC_LOG(ERROR, TAG, "g_jvm is null");
154 return CA_STATUS_FAILED;
157 bool isAttached = false;
159 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
162 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
163 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
167 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
168 return CA_STATUS_FAILED;
173 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
174 if (!jni_LEInterface)
176 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
180 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
181 "(Landroid/content/Context;)V");
182 if (!LeInterfaceConstructorMethod)
184 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
188 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
189 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
193 (*g_jvm)->DetachCurrentThread(g_jvm);
202 (*g_jvm)->DetachCurrentThread(g_jvm);
205 return CA_STATUS_FAILED;
208 CAResult_t CALEClientInitialize()
210 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
216 OIC_LOG(ERROR, TAG, "g_jvm is null");
217 return CA_STATUS_FAILED;
220 bool isAttached = false;
222 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
225 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
226 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
230 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
231 return CA_STATUS_FAILED;
236 CAResult_t ret = CALECheckPlatformVersion(env, 18);
237 if (CA_STATUS_OK != ret)
239 OIC_LOG(ERROR, TAG, "it is not supported");
243 (*g_jvm)->DetachCurrentThread(g_jvm);
249 ret = CALEClientInitGattMutexVaraibles();
250 if (CA_STATUS_OK != ret)
252 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
253 CALEClientTerminateGattMutexVariables();
257 (*g_jvm)->DetachCurrentThread(g_jvm);
263 g_deviceDescCond = ca_cond_new();
265 // init mutex for send logic
266 g_threadCond = ca_cond_new();
267 g_threadWriteCharacteristicCond = ca_cond_new();
268 g_deviceScanRetryDelayCond = ca_cond_new();
270 CALEClientCreateDeviceList();
271 CALEClientJNISetContext();
273 ret = CALEClientCreateUUIDList();
274 if (CA_STATUS_OK != ret)
276 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
280 (*g_jvm)->DetachCurrentThread(g_jvm);
286 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
287 if (CA_STATUS_OK != ret)
289 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
293 (*g_jvm)->DetachCurrentThread(g_jvm);
298 g_isStartedLEClient = true;
302 (*g_jvm)->DetachCurrentThread(g_jvm);
308 void CALEClientTerminate()
310 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
314 OIC_LOG(ERROR, TAG, "g_jvm is null");
318 bool isAttached = false;
320 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
323 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
324 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
328 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
334 if (g_leScanCallback)
336 (*env)->DeleteGlobalRef(env, g_leScanCallback);
339 if (g_leGattCallback)
341 (*env)->DeleteGlobalRef(env, g_leGattCallback);
346 (*env)->DeleteGlobalRef(env, g_sendBuffer);
351 (*env)->DeleteGlobalRef(env, g_uuidList);
354 CAResult_t ret = CALEClientRemoveAllDeviceState();
355 if (CA_STATUS_OK != ret)
357 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
360 ret = CALEClientRemoveAllScanDevices(env);
361 if (CA_STATUS_OK != ret)
363 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
366 ret = CALEClientRemoveAllGattObjs(env);
367 if (CA_STATUS_OK != ret)
369 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
372 g_isStartedMulticastServer = false;
373 CALEClientSetScanFlag(false);
374 CALEClientSetSendFinishFlag(false);
376 CALEClientTerminateGattMutexVariables();
377 CALEClientDestroyJniInterface();
379 ca_cond_free(g_deviceDescCond);
380 ca_cond_free(g_threadCond);
381 ca_cond_free(g_threadWriteCharacteristicCond);
382 ca_cond_free(g_deviceScanRetryDelayCond);
384 g_deviceDescCond = NULL;
386 g_threadWriteCharacteristicCond = NULL;
387 g_deviceScanRetryDelayCond = NULL;
389 g_isSignalSetFlag = false;
393 (*g_jvm)->DetachCurrentThread(g_jvm);
397 CAResult_t CALEClientDestroyJniInterface()
399 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
403 OIC_LOG(ERROR, TAG, "g_jvm is null");
404 return CA_STATUS_FAILED;
407 bool isAttached = false;
409 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
412 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
413 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
417 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
418 return CA_STATUS_FAILED;
423 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
424 if (!jni_LeInterface)
426 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
430 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
431 "destroyLeInterface",
433 if (!jni_InterfaceDestroyMethod)
435 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
439 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
441 if ((*env)->ExceptionCheck(env))
443 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
444 (*env)->ExceptionDescribe(env);
445 (*env)->ExceptionClear(env);
449 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
453 (*g_jvm)->DetachCurrentThread(g_jvm);
462 (*g_jvm)->DetachCurrentThread(g_jvm);
465 return CA_STATUS_FAILED;
468 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
470 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
471 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
475 CAResult_t res = CALEClientDisconnect(env, gatt);
476 if (CA_STATUS_OK != res)
478 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
481 CALEClientUpdateSendCnt(env);
484 CAResult_t CALEClientSendUnicastMessage(const char* address,
486 const uint32_t dataLen)
488 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
489 VERIFY_NON_NULL(address, TAG, "address is null");
490 VERIFY_NON_NULL(data, TAG, "data is null");
492 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
495 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
496 const uint32_t dataLen)
498 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
499 VERIFY_NON_NULL(data, TAG, "data is null");
503 OIC_LOG(ERROR, TAG, "g_jvm is null");
504 return CA_STATUS_FAILED;
507 bool isAttached = false;
509 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
512 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
513 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
517 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
518 return CA_STATUS_FAILED;
523 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
524 if (CA_STATUS_OK != ret)
526 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
531 (*g_jvm)->DetachCurrentThread(g_jvm);
537 CAResult_t CALEClientStartUnicastServer(const char* address)
539 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
541 return CA_NOT_SUPPORTED;
544 CAResult_t CALEClientStartMulticastServer()
546 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
548 if (g_isStartedMulticastServer)
550 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
551 return CA_STATUS_FAILED;
556 OIC_LOG(ERROR, TAG, "g_jvm is null");
557 return CA_STATUS_FAILED;
560 bool isAttached = false;
562 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
565 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
566 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
570 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
571 return CA_STATUS_FAILED;
576 g_isStartedMulticastServer = true;
577 CAResult_t ret = CALEClientStartScan();
578 if (CA_STATUS_OK != ret)
580 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
585 (*g_jvm)->DetachCurrentThread(g_jvm);
591 void CALEClientStopUnicastServer()
593 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
596 void CALEClientStopMulticastServer()
598 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
599 g_isStartedMulticastServer = false;
600 CAResult_t res = CALEClientStopScan();
601 if (CA_STATUS_OK != res)
603 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
608 void CALEClientSetCallback(CAPacketReceiveCallback callback)
610 g_packetReceiveCallback = callback;
613 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
615 g_clientErrorCallback = callback;
618 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
620 VERIFY_NON_NULL(env, TAG, "env");
624 return CA_STATUS_FAILED;
627 if (0 == u_arraylist_length(g_deviceList) // multicast
628 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
630 // Wait for LE peripherals to be discovered.
632 // Number of times to wait for discovery to complete.
633 static size_t const RETRIES = 5;
635 static uint64_t const TIMEOUT =
636 2 * MICROSECS_PER_SEC; // Microseconds
638 bool devicesDiscovered = false;
639 for (size_t i = 0; i < RETRIES; ++i)
641 OIC_LOG(DEBUG, TAG, "waiting for target device");
642 if (ca_cond_wait_for(g_deviceDescCond,
644 TIMEOUT) == CA_WAIT_SUCCESS)
646 ca_mutex_lock(g_deviceListMutex);
647 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
648 ca_mutex_unlock(g_deviceListMutex);
650 if (0 < scannedDeviceLen)
652 if (!address // multicast
653 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
655 devicesDiscovered = true;
662 OIC_LOG(INFO, TAG, "waiting..");
664 ca_mutex_lock(g_deviceScanRetryDelayMutex);
665 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
666 g_deviceScanRetryDelayMutex,
667 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
669 OIC_LOG(INFO, TAG, "finish to waiting for target device");
670 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
673 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
681 // time out for scanning devices
682 if (!devicesDiscovered)
684 return CA_STATUS_FAILED;
692 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
693 const uint32_t dataLen)
695 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
697 VERIFY_NON_NULL(address, TAG, "address is null");
698 VERIFY_NON_NULL(data, TAG, "data is null");
702 OIC_LOG(ERROR, TAG, "g_jvm is null");
703 return CA_STATUS_FAILED;
706 bool isAttached = false;
708 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
711 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
712 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
715 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
716 return CA_STATUS_FAILED;
721 ca_mutex_lock(g_threadSendMutex);
723 CALEClientSetSendFinishFlag(false);
725 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
726 if (CA_STATUS_OK != ret)
728 OIC_LOG(INFO, TAG, "there is no scanned device");
732 if (g_context && g_deviceList)
734 uint32_t length = u_arraylist_length(g_deviceList);
735 for (uint32_t index = 0; index < length; index++)
737 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
740 OIC_LOG(ERROR, TAG, "jarrayObj is null");
744 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
747 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
751 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
754 OIC_LOG(ERROR, TAG, "setAddress is null");
758 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
760 if (!strcmp(setAddress, address))
762 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
764 // connect to gatt server
765 ret = CALEClientStopScan();
766 if (CA_STATUS_OK != ret)
768 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
774 (*env)->DeleteGlobalRef(env, g_sendBuffer);
777 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
778 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
779 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
781 // Target device to send message is just one.
784 ret = CALEClientSendData(env, jarrayObj);
785 if (CA_STATUS_OK != ret)
787 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
791 OIC_LOG(INFO, TAG, "wake up");
794 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
798 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
800 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
801 // if there is no connection state.
802 ca_mutex_lock(g_threadMutex);
803 if (!g_isFinishedSendData)
805 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
806 ca_cond_wait(g_threadCond, g_threadMutex);
807 OIC_LOG(DEBUG, TAG, "the data was sent");
809 ca_mutex_unlock(g_threadMutex);
813 (*g_jvm)->DetachCurrentThread(g_jvm);
816 // start LE Scan again
817 ret = CALEClientStartScan();
818 if (CA_STATUS_OK != ret)
820 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
821 ca_mutex_unlock(g_threadSendMutex);
825 ca_mutex_unlock(g_threadSendMutex);
826 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
827 return CALECheckSendState(address);
832 // start LE Scan again
833 ret = CALEClientStartScan();
834 if (CA_STATUS_OK != ret)
836 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
837 ca_mutex_unlock(g_threadSendMutex);
840 (*g_jvm)->DetachCurrentThread(g_jvm);
847 (*g_jvm)->DetachCurrentThread(g_jvm);
850 if (g_clientErrorCallback)
852 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
854 ca_mutex_unlock(g_threadSendMutex);
855 return CA_SEND_FAILED;
858 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
859 const uint32_t dataLen)
861 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
862 VERIFY_NON_NULL(data, TAG, "data is null");
863 VERIFY_NON_NULL(env, TAG, "env is null");
867 OIC_LOG(ERROR, TAG, "g_deviceList is null");
868 return CA_STATUS_FAILED;
871 ca_mutex_lock(g_threadSendMutex);
873 CALEClientSetSendFinishFlag(false);
875 OIC_LOG(DEBUG, TAG, "set byteArray for data");
878 (*env)->DeleteGlobalRef(env, g_sendBuffer);
882 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
883 if (CA_STATUS_OK != res)
885 OIC_LOG(INFO, TAG, "there is no scanned device");
889 // connect to gatt server
890 res = CALEClientStopScan();
891 if (CA_STATUS_OK != res)
893 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
894 ca_mutex_unlock(g_threadSendMutex);
897 uint32_t length = u_arraylist_length(g_deviceList);
898 g_targetCnt = length;
900 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
901 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
902 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
904 for (uint32_t index = 0; index < length; index++)
906 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
909 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
913 res = CALEClientSendData(env, jarrayObj);
914 if (res != CA_STATUS_OK)
916 OIC_LOG(ERROR, TAG, "BT device - send has failed");
919 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
922 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
926 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
929 OIC_LOG(ERROR, TAG, "address is not available");
933 (*env)->ReleaseStringUTFChars(env, jni_address, address);
936 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
938 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
939 ca_mutex_lock(g_threadMutex);
940 if (!g_isFinishedSendData)
942 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
943 ca_cond_wait(g_threadCond, g_threadMutex);
944 OIC_LOG(DEBUG, TAG, "the data was sent");
946 ca_mutex_unlock(g_threadMutex);
948 // start LE Scan again
949 res = CALEClientStartScan();
950 if (CA_STATUS_OK != res)
952 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
953 ca_mutex_unlock(g_threadSendMutex);
957 ca_mutex_unlock(g_threadSendMutex);
958 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
962 res = CALEClientStartScan();
963 if (CA_STATUS_OK != res)
965 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
966 ca_mutex_unlock(g_threadSendMutex);
970 ca_mutex_unlock(g_threadSendMutex);
971 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
972 return CA_SEND_FAILED;
975 CAResult_t CALECheckSendState(const char* address)
977 VERIFY_NON_NULL(address, TAG, "address is null");
979 ca_mutex_lock(g_deviceStateListMutex);
980 CALEState_t* state = CALEClientGetStateInfo(address);
983 OIC_LOG(ERROR, TAG, "state is null");
984 ca_mutex_unlock(g_deviceStateListMutex);
985 return CA_SEND_FAILED;
988 if (STATE_SEND_SUCCESS != state->sendState)
990 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
991 ca_mutex_unlock(g_deviceStateListMutex);
992 return CA_SEND_FAILED;
995 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
996 ca_mutex_unlock(g_deviceStateListMutex);
1000 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1002 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1003 VERIFY_NON_NULL(device, TAG, "device is null");
1004 VERIFY_NON_NULL(env, TAG, "env is null");
1006 // get BLE address from bluetooth device object.
1007 char* address = NULL;
1008 CALEState_t* state = NULL;
1009 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1012 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1013 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1016 OIC_LOG(ERROR, TAG, "address is not available");
1017 return CA_STATUS_FAILED;
1019 ca_mutex_lock(g_deviceStateListMutex);
1020 state = CALEClientGetStateInfo(address);
1021 ca_mutex_unlock(g_deviceStateListMutex);
1022 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1027 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1029 // cancel previous connection request before connection
1030 // if there is gatt object in g_gattObjectList.
1033 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1036 OIC_LOG(ERROR, TAG, "address is not available");
1037 return CA_STATUS_FAILED;
1040 jobject gatt = CALEClientGetGattObjInList(env, address);
1043 CAResult_t res = CALEClientDisconnect(env, gatt);
1044 if (CA_STATUS_OK != res)
1046 OIC_LOG(INFO, TAG, "there is no gatt object");
1049 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1052 // connection request
1053 jobject newGatt = CALEClientConnect(env, device,
1055 if (NULL == newGatt)
1057 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1058 return CA_STATUS_FAILED;
1063 if (STATE_CONNECTED == state->connectedState)
1065 OIC_LOG(INFO, TAG, "GATT has already connected");
1068 OIC_LOG(ERROR, TAG, "jni_address is not available");
1069 return CA_STATUS_FAILED;
1072 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1075 OIC_LOG(ERROR, TAG, "address is not available");
1076 return CA_STATUS_FAILED;
1079 jobject gatt = CALEClientGetGattObjInList(env, address);
1082 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1083 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1084 return CA_STATUS_FAILED;
1087 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1088 if (CA_STATUS_OK != ret)
1090 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1091 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1094 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1098 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1100 // cancel previous connection request before connection
1101 // if there is gatt object in g_gattObjectList.
1104 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1107 OIC_LOG(ERROR, TAG, "address is not available");
1108 return CA_STATUS_FAILED;
1111 jobject gatt = CALEClientGetGattObjInList(env, address);
1114 CAResult_t res = CALEClientDisconnect(env, gatt);
1115 if (CA_STATUS_OK != res)
1117 OIC_LOG(INFO, TAG, "there is no gatt object");
1120 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1123 OIC_LOG(DEBUG, TAG, "start to connect LE");
1124 jobject gatt = CALEClientConnect(env, device,
1125 CALEClientGetAutoConnectFlag(env, jni_address));
1128 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1129 return CA_STATUS_FAILED;
1134 return CA_STATUS_OK;
1137 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1139 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1140 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1142 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1143 if (!jni_cid_gattdevice_list)
1145 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1149 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1150 "()Landroid/bluetooth/BluetoothDevice;");
1151 if (!jni_mid_getDevice)
1153 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1157 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1158 if (!jni_obj_device)
1160 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1164 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1167 OIC_LOG(ERROR, TAG, "jni_address is null");
1177 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1180 OIC_LOG(DEBUG, TAG, "Gatt Close");
1181 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1182 VERIFY_NON_NULL(env, TAG, "env is null");
1184 // get BluetoothGatt class
1185 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1186 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1187 if (!jni_cid_BluetoothGatt)
1189 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1190 return CA_STATUS_FAILED;
1193 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1194 if (!jni_mid_closeGatt)
1196 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1197 return CA_STATUS_OK;
1200 // call disconnect gatt method
1201 OIC_LOG(DEBUG, TAG, "request to close GATT");
1202 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1204 if ((*env)->ExceptionCheck(env))
1206 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1207 (*env)->ExceptionDescribe(env);
1208 (*env)->ExceptionClear(env);
1209 return CA_STATUS_FAILED;
1212 return CA_STATUS_OK;
1215 CAResult_t CALEClientStartScan()
1217 if (!g_isStartedMulticastServer)
1219 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1220 return CA_STATUS_FAILED;
1223 if (!g_isStartedLEClient)
1225 OIC_LOG(ERROR, TAG, "LE client is not started");
1226 return CA_STATUS_FAILED;
1231 OIC_LOG(ERROR, TAG, "g_jvm is null");
1232 return CA_STATUS_FAILED;
1235 if (g_isStartedScan)
1237 OIC_LOG(INFO, TAG, "scanning is already started");
1238 return CA_STATUS_OK;
1241 bool isAttached = false;
1243 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1246 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1248 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1251 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1252 return CA_STATUS_FAILED;
1257 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1259 CAResult_t ret = CA_STATUS_OK;
1260 // scan gatt server with UUID
1261 if (g_leScanCallback && g_uuidList)
1264 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1266 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1268 if (CA_STATUS_OK != ret)
1270 if (CA_ADAPTER_NOT_ENABLED == ret)
1272 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1276 OIC_LOG(ERROR, TAG, "start scan has failed");
1283 (*g_jvm)->DetachCurrentThread(g_jvm);
1289 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1291 VERIFY_NON_NULL(callback, TAG, "callback is null");
1292 VERIFY_NON_NULL(env, TAG, "env is null");
1294 if (!CALEIsEnableBTAdapter(env))
1296 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1297 return CA_ADAPTER_NOT_ENABLED;
1300 // get default bt adapter class
1301 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1302 if (!jni_cid_BTAdapter)
1304 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1305 return CA_STATUS_FAILED;
1308 // get remote bt adapter method
1309 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1310 "getDefaultAdapter",
1311 METHODID_OBJECTNONPARAM);
1312 if (!jni_mid_getDefaultAdapter)
1314 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1315 return CA_STATUS_FAILED;
1318 // get start le scan method
1319 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1320 "(Landroid/bluetooth/BluetoothAdapter$"
1321 "LeScanCallback;)Z");
1322 if (!jni_mid_startLeScan)
1324 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1325 return CA_STATUS_FAILED;
1328 // gat bt adapter object
1329 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1330 jni_mid_getDefaultAdapter);
1331 if (!jni_obj_BTAdapter)
1333 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1334 return CA_STATUS_FAILED;
1337 // call start le scan method
1338 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1339 jni_mid_startLeScan, callback);
1340 if (!jni_obj_startLeScan)
1342 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1343 return CA_STATUS_FAILED;
1347 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1348 CALEClientSetScanFlag(true);
1351 return CA_STATUS_OK;
1354 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1356 VERIFY_NON_NULL(callback, TAG, "callback is null");
1357 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1358 VERIFY_NON_NULL(env, TAG, "env is null");
1360 if (!CALEIsEnableBTAdapter(env))
1362 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1363 return CA_ADAPTER_NOT_ENABLED;
1366 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1367 if (!jni_cid_BTAdapter)
1369 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1370 return CA_STATUS_FAILED;
1373 // get remote bt adapter method
1374 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1375 "getDefaultAdapter",
1376 METHODID_OBJECTNONPARAM);
1377 if (!jni_mid_getDefaultAdapter)
1379 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1380 return CA_STATUS_FAILED;
1383 // get start le scan method
1384 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1385 "([Ljava/util/UUID;Landroid/bluetooth/"
1386 "BluetoothAdapter$LeScanCallback;)Z");
1387 if (!jni_mid_startLeScan)
1389 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1390 return CA_STATUS_FAILED;
1393 // get bt adapter object
1394 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1395 jni_mid_getDefaultAdapter);
1396 if (!jni_obj_BTAdapter)
1398 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1399 return CA_STATUS_FAILED;
1402 // call start le scan method
1403 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1404 jni_mid_startLeScan, uuids, callback);
1405 if (!jni_obj_startLeScan)
1407 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1408 return CA_STATUS_FAILED;
1412 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1413 CALEClientSetScanFlag(true);
1416 return CA_STATUS_OK;
1419 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1421 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1422 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1425 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1428 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1432 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1433 "(Ljava/lang/String;)"
1434 "Ljava/util/UUID;");
1435 if (!jni_mid_fromString)
1437 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1441 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1442 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1446 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1450 return jni_obj_uuid;
1453 CAResult_t CALEClientStopScan()
1457 OIC_LOG(ERROR, TAG, "g_jvm is null");
1458 return CA_STATUS_FAILED;
1461 if (!g_isStartedScan)
1463 OIC_LOG(INFO, TAG, "scanning is already stopped");
1464 return CA_STATUS_OK;
1467 bool isAttached = false;
1469 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1472 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1473 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1476 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1477 return CA_STATUS_FAILED;
1482 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1483 if (CA_STATUS_OK != ret)
1485 if (CA_ADAPTER_NOT_ENABLED == ret)
1487 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1491 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1496 CALEClientSetScanFlag(false);
1501 (*g_jvm)->DetachCurrentThread(g_jvm);
1507 void CALEClientSetScanFlag(bool flag)
1509 ca_mutex_lock(g_scanMutex);
1510 g_isStartedScan = flag;
1511 ca_mutex_unlock(g_scanMutex);
1514 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1516 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1517 VERIFY_NON_NULL(callback, TAG, "callback is null");
1518 VERIFY_NON_NULL(env, TAG, "env is null");
1520 if (!CALEIsEnableBTAdapter(env))
1522 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1523 return CA_ADAPTER_NOT_ENABLED;
1526 // get default bt adapter class
1527 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1528 if (!jni_cid_BTAdapter)
1530 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1531 return CA_STATUS_FAILED;
1534 // get remote bt adapter method
1535 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1536 "getDefaultAdapter",
1537 METHODID_OBJECTNONPARAM);
1538 if (!jni_mid_getDefaultAdapter)
1540 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1541 return CA_STATUS_FAILED;
1544 // get start le scan method
1545 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1546 "(Landroid/bluetooth/"
1547 "BluetoothAdapter$LeScanCallback;)V");
1548 if (!jni_mid_stopLeScan)
1550 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1551 return CA_STATUS_FAILED;
1554 // gat bt adapter object
1555 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1556 jni_mid_getDefaultAdapter);
1557 if (!jni_obj_BTAdapter)
1559 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1560 return CA_STATUS_FAILED;
1563 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1564 // call start le scan method
1565 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1566 if ((*env)->ExceptionCheck(env))
1568 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1569 (*env)->ExceptionDescribe(env);
1570 (*env)->ExceptionClear(env);
1571 return CA_STATUS_FAILED;
1574 return CA_STATUS_OK;
1577 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1579 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1580 VERIFY_NON_NULL(env, TAG, "env");
1581 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1583 ca_mutex_lock(g_deviceStateListMutex);
1585 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1588 OIC_LOG(ERROR, TAG, "address is not available");
1589 return CA_STATUS_FAILED;
1592 if (CALEClientIsDeviceInList(address))
1594 CALEState_t* curState = CALEClientGetStateInfo(address);
1597 OIC_LOG(ERROR, TAG, "curState is null");
1598 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1599 ca_mutex_unlock(g_deviceStateListMutex);
1600 return CA_STATUS_FAILED;
1602 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1604 curState->autoConnectFlag = flag;
1607 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1608 ca_mutex_unlock(g_deviceStateListMutex);
1609 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1610 return CA_STATUS_OK;
1613 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1615 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1616 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1617 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1619 ca_mutex_lock(g_deviceStateListMutex);
1621 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1624 OIC_LOG(ERROR, TAG, "address is not available");
1628 CALEState_t* curState = CALEClientGetStateInfo(address);
1631 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1632 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1633 ca_mutex_unlock(g_deviceStateListMutex);
1636 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1638 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1639 ca_mutex_unlock(g_deviceStateListMutex);
1641 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1642 return curState->autoConnectFlag;
1645 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1647 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1648 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1649 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1651 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1652 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1655 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1658 OIC_LOG(ERROR, TAG, "address is not available");
1662 // close the gatt service
1663 jobject gatt = CALEClientGetGattObjInList(env, address);
1666 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1667 if (CA_STATUS_OK != res)
1669 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1670 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1674 // clean previous gatt object after close profile service
1675 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1676 if (CA_STATUS_OK != res)
1678 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1679 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1683 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1686 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1689 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1693 // add new gatt object into g_gattObjectList
1694 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1695 if (CA_STATUS_OK != res)
1697 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1704 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1706 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1707 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1708 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1710 if (!CALEIsEnableBTAdapter(env))
1712 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1716 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1719 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1723 // get BluetoothDevice class
1724 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1725 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1726 if (!jni_cid_BluetoothDevice)
1728 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1732 // get connectGatt method
1733 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1734 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1735 "(Landroid/content/Context;ZLandroid/"
1736 "bluetooth/BluetoothGattCallback;)"
1737 "Landroid/bluetooth/BluetoothGatt;");
1738 if (!jni_mid_connectGatt)
1740 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1744 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1745 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1746 jni_mid_connectGatt,
1748 autoconnect, g_leGattCallback);
1749 if (!jni_obj_connectGatt)
1751 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1752 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1753 CALEClientUpdateSendCnt(env);
1758 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1760 return jni_obj_connectGatt;
1763 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1765 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1767 VERIFY_NON_NULL(env, TAG, "env is null");
1768 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1770 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1771 if (!jni_cid_BTAdapter)
1773 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1774 return CA_STATUS_FAILED;
1777 // get remote bt adapter method
1778 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1779 "getDefaultAdapter",
1780 METHODID_OBJECTNONPARAM);
1781 if (!jni_mid_getDefaultAdapter)
1783 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1784 return CA_STATUS_FAILED;
1787 // gat bt adapter object
1788 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1789 jni_mid_getDefaultAdapter);
1790 if (!jni_obj_BTAdapter)
1792 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1793 return CA_STATUS_FAILED;
1796 // get closeProfileProxy method
1797 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1798 "closeProfileProxy",
1799 "(ILandroid/bluetooth/"
1800 "BluetoothProfile;)V");
1801 if (!jni_mid_closeProfileProxy)
1803 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1804 return CA_STATUS_FAILED;
1807 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1808 if (!jni_cid_BTProfile)
1810 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1811 return CA_STATUS_FAILED;
1814 // GATT - Constant value : 7 (0x00000007)
1815 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1819 OIC_LOG(ERROR, TAG, "id_gatt is null");
1820 return CA_STATUS_FAILED;
1823 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1825 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1826 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1827 if ((*env)->ExceptionCheck(env))
1829 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1830 (*env)->ExceptionDescribe(env);
1831 (*env)->ExceptionClear(env);
1832 return CA_STATUS_FAILED;
1835 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1836 return CA_STATUS_OK;
1840 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1842 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1843 VERIFY_NON_NULL(env, TAG, "env is null");
1844 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1846 // get BluetoothGatt class
1847 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1848 if (!jni_cid_BluetoothGatt)
1850 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1851 return CA_STATUS_FAILED;
1854 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1855 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1856 "disconnect", "()V");
1857 if (!jni_mid_disconnectGatt)
1859 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1860 return CA_STATUS_FAILED;
1863 // call disconnect gatt method
1864 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1865 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1866 if ((*env)->ExceptionCheck(env))
1868 OIC_LOG(ERROR, TAG, "disconnect has failed");
1869 (*env)->ExceptionDescribe(env);
1870 (*env)->ExceptionClear(env);
1871 return CA_STATUS_FAILED;
1874 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1876 return CA_STATUS_OK;
1879 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1881 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1882 VERIFY_NON_NULL(env, TAG, "env is null");
1884 if (!g_gattObjectList)
1886 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1887 return CA_STATUS_OK;
1890 uint32_t length = u_arraylist_length(g_gattObjectList);
1891 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1892 for (uint32_t index = 0; index < length; index++)
1894 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1895 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1898 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1901 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1902 if (CA_STATUS_OK != res)
1904 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1909 return CA_STATUS_OK;
1912 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1914 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1915 VERIFY_NON_NULL(env, TAG, "env is null");
1917 if (!g_gattObjectList)
1919 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1920 return CA_STATUS_OK;
1923 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1926 OIC_LOG(ERROR, TAG, "address is null");
1927 return CA_STATUS_FAILED;
1930 uint32_t length = u_arraylist_length(g_gattObjectList);
1931 for (uint32_t index = 0; index < length; index++)
1933 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1936 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1940 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1941 if (!jni_setAddress)
1943 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1944 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1945 return CA_STATUS_FAILED;
1948 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1951 OIC_LOG(ERROR, TAG, "setAddress is null");
1952 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1953 return CA_STATUS_FAILED;
1956 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1957 if (!strcmp(address, setAddress))
1959 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1960 if (CA_STATUS_OK != res)
1962 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1963 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1964 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1965 return CA_STATUS_FAILED;
1967 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1968 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1969 return CA_STATUS_OK;
1971 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1973 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1975 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1976 return CA_STATUS_OK;
1979 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1981 VERIFY_NON_NULL(env, TAG, "env is null");
1982 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1984 if (!CALEIsEnableBTAdapter(env))
1986 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1987 return CA_ADAPTER_NOT_ENABLED;
1990 // get BluetoothGatt class
1991 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1992 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1993 if (!jni_cid_BluetoothGatt)
1995 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1996 return CA_STATUS_FAILED;
1999 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
2000 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2001 "discoverServices", "()Z");
2002 if (!jni_mid_discoverServices)
2004 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2005 return CA_STATUS_FAILED;
2007 // call disconnect gatt method
2008 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
2009 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2012 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2013 return CA_STATUS_FAILED;
2016 return CA_STATUS_OK;
2019 static void CALEWriteCharacteristicThread(void* object)
2021 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2023 bool isAttached = false;
2025 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2028 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2029 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2033 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2039 jobject gatt = (jobject)object;
2040 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2041 if (CA_STATUS_OK != ret)
2043 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2048 (*g_jvm)->DetachCurrentThread(g_jvm);
2052 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2054 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2055 VERIFY_NON_NULL(env, TAG, "env is null");
2058 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2059 if (!jni_obj_character)
2061 CALEClientSendFinish(env, gatt);
2062 return CA_STATUS_FAILED;
2065 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2066 if (CA_STATUS_OK != ret)
2068 CALEClientSendFinish(env, gatt);
2069 return CA_STATUS_FAILED;
2072 // wait for callback for write Characteristic with success to sent data
2073 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2074 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2075 if (!g_isSignalSetFlag)
2077 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2078 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2079 g_threadWriteCharacteristicMutex,
2080 WAIT_TIME_WRITE_CHARACTERISTIC))
2082 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2083 g_isSignalSetFlag = false;
2084 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2085 return CA_STATUS_FAILED;
2088 // reset flag set by writeCharacteristic Callback
2089 g_isSignalSetFlag = false;
2090 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2092 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2093 return CA_STATUS_OK;
2096 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2098 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2099 VERIFY_NON_NULL(env, TAG, "env is null");
2100 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2102 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2103 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2104 CALEWriteCharacteristicThread, (void*)gattParam))
2106 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2107 return CA_STATUS_FAILED;
2110 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2111 return CA_STATUS_OK;
2114 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2115 jobject gattCharacteristic)
2117 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2118 VERIFY_NON_NULL(env, TAG, "env is null");
2119 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2120 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2122 if (!CALEIsEnableBTAdapter(env))
2124 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2125 return CA_STATUS_FAILED;
2128 // get BluetoothGatt class
2129 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2130 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2131 if (!jni_cid_BluetoothGatt)
2133 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2134 return CA_STATUS_FAILED;
2137 OIC_LOG(DEBUG, TAG, "write characteristic method");
2138 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2139 "writeCharacteristic",
2140 "(Landroid/bluetooth/"
2141 "BluetoothGattCharacteristic;)Z");
2142 if (!jni_mid_writeCharacteristic)
2144 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2145 return CA_STATUS_FAILED;
2148 // call disconnect gatt method
2149 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2150 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2151 jni_mid_writeCharacteristic,
2152 gattCharacteristic);
2155 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2159 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2160 return CA_STATUS_FAILED;
2163 return CA_STATUS_OK;
2166 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2168 VERIFY_NON_NULL(env, TAG, "env is null");
2169 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2171 if (!CALEIsEnableBTAdapter(env))
2173 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2174 return CA_STATUS_FAILED;
2177 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2178 if (!jni_cid_BluetoothGatt)
2180 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2181 return CA_STATUS_FAILED;
2184 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2187 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2188 return CA_STATUS_FAILED;
2191 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2192 if (!jni_obj_GattCharacteristic)
2194 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2195 return CA_STATUS_FAILED;
2198 OIC_LOG(DEBUG, TAG, "read characteristic method");
2199 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2200 "readCharacteristic",
2201 "(Landroid/bluetooth/"
2202 "BluetoothGattCharacteristic;)Z");
2203 if (!jni_mid_readCharacteristic)
2205 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2206 return CA_STATUS_FAILED;
2209 // call disconnect gatt method
2210 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2211 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2212 jni_obj_GattCharacteristic);
2215 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2219 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2220 return CA_STATUS_FAILED;
2223 return CA_STATUS_OK;
2226 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2227 jobject characteristic)
2229 VERIFY_NON_NULL(env, TAG, "env is null");
2230 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2231 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2233 if (!CALEIsEnableBTAdapter(env))
2235 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2236 return CA_ADAPTER_NOT_ENABLED;
2239 // get BluetoothGatt class
2240 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2241 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2242 if (!jni_cid_BluetoothGatt)
2244 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2245 return CA_STATUS_FAILED;
2248 // set Characteristic Notification
2249 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2250 "setCharacteristicNotification",
2251 "(Landroid/bluetooth/"
2252 "BluetoothGattCharacteristic;Z)Z");
2253 if (!jni_mid_setNotification)
2255 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2256 return CA_STATUS_FAILED;
2259 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2260 characteristic, JNI_TRUE);
2261 if (JNI_TRUE == ret)
2263 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2267 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2268 return CA_STATUS_FAILED;
2271 return CA_STATUS_OK;
2274 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2276 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2277 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2278 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2280 if (!CALEIsEnableBTAdapter(env))
2282 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2286 // get BluetoothGatt class
2287 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2288 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2289 if (!jni_cid_BluetoothGatt)
2291 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2295 jmethodID jni_mid_getService = (*env)->GetMethodID(
2296 env, jni_cid_BluetoothGatt, "getService",
2297 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2298 if (!jni_mid_getService)
2300 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2304 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2305 if (!jni_obj_service_uuid)
2307 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2311 // get bluetooth gatt service
2312 OIC_LOG(DEBUG, TAG, "request to get service");
2313 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2314 jni_obj_service_uuid);
2315 if (!jni_obj_gattService)
2317 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2321 // get bluetooth gatt service class
2322 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2323 env, "android/bluetooth/BluetoothGattService");
2324 if (!jni_cid_BluetoothGattService)
2326 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2330 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2331 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2332 "getCharacteristic",
2333 "(Ljava/util/UUID;)"
2334 "Landroid/bluetooth/"
2335 "BluetoothGattCharacteristic;");
2336 if (!jni_mid_getCharacteristic)
2338 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2342 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2345 OIC_LOG(ERROR, TAG, "uuid is null");
2349 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2350 if (!jni_obj_tx_uuid)
2352 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2353 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2357 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2358 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2359 jni_mid_getCharacteristic,
2362 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2363 return jni_obj_GattCharacteristic;
2366 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2368 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2369 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2370 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2371 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2373 if (!CALEIsEnableBTAdapter(env))
2375 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2379 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2382 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2386 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2387 if (!jni_obj_GattCharacteristic)
2389 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2393 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2394 "/BluetoothGattCharacteristic");
2395 if (!jni_cid_BTGattCharacteristic)
2397 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2401 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2402 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2404 if (!jni_mid_setValue)
2406 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2410 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2412 if (JNI_TRUE == ret)
2414 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2418 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2423 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2424 "setWriteType", "(I)V");
2425 if (!jni_mid_setWriteType)
2427 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2431 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2432 "WRITE_TYPE_NO_RESPONSE", "I");
2433 if (!jni_fid_no_response)
2435 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2439 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2440 jni_fid_no_response);
2442 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2444 return jni_obj_GattCharacteristic;
2447 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2449 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2450 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2452 if (!CALEIsEnableBTAdapter(env))
2454 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2458 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2459 "BluetoothGattCharacteristic");
2460 if (!jni_cid_BTGattCharacteristic)
2462 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2466 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2467 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2469 if (!jni_mid_getValue)
2471 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2475 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2477 return jni_obj_data_array;
2480 CAResult_t CALEClientCreateUUIDList()
2484 OIC_LOG(ERROR, TAG, "g_jvm is null");
2485 return CA_STATUS_FAILED;
2488 bool isAttached = false;
2490 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2493 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2494 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2498 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2499 return CA_STATUS_FAILED;
2504 // create new object array
2505 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2506 if (!jni_cid_uuid_list)
2508 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2512 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2513 jni_cid_uuid_list, NULL);
2514 if (!jni_obj_uuid_list)
2516 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2521 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2524 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2527 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2529 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2533 (*g_jvm)->DetachCurrentThread(g_jvm);
2536 return CA_STATUS_OK;
2543 (*g_jvm)->DetachCurrentThread(g_jvm);
2545 return CA_STATUS_FAILED;
2548 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2549 jobject characteristic)
2551 VERIFY_NON_NULL(env, TAG, "env is null");
2552 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2553 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2555 if (!CALEIsEnableBTAdapter(env))
2557 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2558 return CA_ADAPTER_NOT_ENABLED;
2561 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2562 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2563 "BluetoothGattCharacteristic");
2564 if (!jni_cid_BTGattCharacteristic)
2566 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2567 return CA_STATUS_FAILED;
2570 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2571 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2573 "(Ljava/util/UUID;)Landroid/bluetooth/"
2574 "BluetoothGattDescriptor;");
2575 if (!jni_mid_getDescriptor)
2577 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2578 return CA_STATUS_FAILED;
2581 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2582 if (!jni_obj_cc_uuid)
2584 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2585 return CA_STATUS_FAILED;
2588 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2589 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2590 jni_mid_getDescriptor, jni_obj_cc_uuid);
2591 if (!jni_obj_descriptor)
2593 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2594 return CA_NOT_SUPPORTED;
2597 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2598 jclass jni_cid_descriptor = (*env)->FindClass(env,
2599 "android/bluetooth/BluetoothGattDescriptor");
2600 if (!jni_cid_descriptor)
2602 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2603 return CA_STATUS_FAILED;
2606 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2607 if (!jni_mid_setValue)
2609 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2610 return CA_STATUS_FAILED;
2613 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2614 "ENABLE_NOTIFICATION_VALUE", "[B");
2615 if (!jni_fid_NotiValue)
2617 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2618 return CA_STATUS_FAILED;
2621 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2623 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2624 env, jni_obj_descriptor, jni_mid_setValue,
2625 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2628 OIC_LOG(DEBUG, TAG, "setValue success");
2632 OIC_LOG(ERROR, TAG, "setValue has failed");
2633 return CA_STATUS_FAILED;
2636 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2639 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2640 return CA_STATUS_FAILED;
2643 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2644 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2645 "(Landroid/bluetooth/"
2646 "BluetoothGattDescriptor;)Z");
2647 if (!jni_mid_writeDescriptor)
2649 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2650 return CA_STATUS_FAILED;
2653 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2654 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2655 jni_obj_descriptor);
2658 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2662 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2663 return CA_STATUS_FAILED;
2666 return CA_STATUS_OK;
2669 void CALEClientCreateScanDeviceList(JNIEnv *env)
2671 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2672 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2674 ca_mutex_lock(g_deviceListMutex);
2675 // create new object array
2676 if (g_deviceList == NULL)
2678 OIC_LOG(DEBUG, TAG, "Create device list");
2680 g_deviceList = u_arraylist_create();
2682 ca_mutex_unlock(g_deviceListMutex);
2685 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2687 VERIFY_NON_NULL(device, TAG, "device is null");
2688 VERIFY_NON_NULL(env, TAG, "env is null");
2690 ca_mutex_lock(g_deviceListMutex);
2694 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2695 ca_mutex_unlock(g_deviceListMutex);
2696 return CA_STATUS_FAILED;
2699 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2700 if (!jni_remoteAddress)
2702 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2703 ca_mutex_unlock(g_deviceListMutex);
2704 return CA_STATUS_FAILED;
2707 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2710 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2711 ca_mutex_unlock(g_deviceListMutex);
2712 return CA_STATUS_FAILED;
2715 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2717 jobject gdevice = (*env)->NewGlobalRef(env, device);
2718 u_arraylist_add(g_deviceList, gdevice);
2719 ca_cond_signal(g_deviceDescCond);
2720 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2722 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2724 ca_mutex_unlock(g_deviceListMutex);
2726 return CA_STATUS_OK;
2729 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2731 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2732 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2736 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2740 uint32_t length = u_arraylist_length(g_deviceList);
2741 for (uint32_t index = 0; index < length; index++)
2743 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2746 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2750 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2751 if (!jni_setAddress)
2753 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2757 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2760 OIC_LOG(ERROR, TAG, "setAddress is null");
2764 if (!strcmp(remoteAddress, setAddress))
2766 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2770 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2773 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2778 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2780 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2781 VERIFY_NON_NULL(env, TAG, "env is null");
2783 ca_mutex_lock(g_deviceListMutex);
2787 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2788 ca_mutex_unlock(g_deviceListMutex);
2789 return CA_STATUS_FAILED;
2792 uint32_t length = u_arraylist_length(g_deviceList);
2793 for (uint32_t index = 0; index < length; index++)
2795 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2798 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2801 (*env)->DeleteGlobalRef(env, jarrayObj);
2805 OICFree(g_deviceList);
2806 g_deviceList = NULL;
2808 ca_mutex_unlock(g_deviceListMutex);
2809 return CA_STATUS_OK;
2812 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2814 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2815 VERIFY_NON_NULL(address, TAG, "address is null");
2816 VERIFY_NON_NULL(env, TAG, "env is null");
2818 ca_mutex_lock(g_deviceListMutex);
2822 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2823 ca_mutex_unlock(g_deviceListMutex);
2824 return CA_STATUS_FAILED;
2827 uint32_t length = u_arraylist_length(g_deviceList);
2828 for (uint32_t index = 0; index < length; index++)
2830 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2833 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2834 ca_mutex_unlock(g_deviceListMutex);
2835 return CA_STATUS_FAILED;
2838 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2839 if (!jni_setAddress)
2841 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2842 ca_mutex_unlock(g_deviceListMutex);
2843 return CA_STATUS_FAILED;
2846 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2849 OIC_LOG(ERROR, TAG, "setAddress is null");
2850 ca_mutex_unlock(g_deviceListMutex);
2851 return CA_STATUS_FAILED;
2854 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2857 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2858 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2859 ca_mutex_unlock(g_deviceListMutex);
2860 return CA_STATUS_FAILED;
2863 if (!strcmp(setAddress, remoteAddress))
2865 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2866 (*env)->DeleteGlobalRef(env, jarrayObj);
2868 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2869 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2871 if (NULL == u_arraylist_remove(g_deviceList, index))
2873 OIC_LOG(ERROR, TAG, "List removal failed.");
2874 ca_mutex_unlock(g_deviceListMutex);
2875 return CA_STATUS_FAILED;
2877 ca_mutex_unlock(g_deviceListMutex);
2878 return CA_STATUS_OK;
2880 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2881 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2884 ca_mutex_unlock(g_deviceListMutex);
2885 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2887 return CA_STATUS_OK;
2894 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2896 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2897 VERIFY_NON_NULL(env, TAG, "env is null");
2898 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2900 ca_mutex_lock(g_gattObjectMutex);
2902 if (!g_gattObjectList)
2904 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2905 ca_mutex_unlock(g_gattObjectMutex);
2906 return CA_STATUS_FAILED;
2909 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2910 if (!jni_remoteAddress)
2912 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2913 ca_mutex_unlock(g_gattObjectMutex);
2914 return CA_STATUS_FAILED;
2917 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2920 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2921 ca_mutex_unlock(g_gattObjectMutex);
2922 return CA_STATUS_FAILED;
2925 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2926 if (!CALEClientIsGattObjInList(env, remoteAddress))
2928 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2929 u_arraylist_add(g_gattObjectList, newGatt);
2930 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2933 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2934 ca_mutex_unlock(g_gattObjectMutex);
2935 return CA_STATUS_OK;
2938 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2940 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2941 VERIFY_NON_NULL(env, TAG, "env is null");
2942 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2944 uint32_t length = u_arraylist_length(g_gattObjectList);
2945 for (uint32_t index = 0; index < length; index++)
2948 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2951 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2955 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2956 if (!jni_setAddress)
2958 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2962 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2965 OIC_LOG(ERROR, TAG, "setAddress is null");
2969 if (!strcmp(remoteAddress, setAddress))
2971 OIC_LOG(DEBUG, TAG, "the device is already set");
2972 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2977 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2982 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2986 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2988 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2989 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2990 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2992 ca_mutex_lock(g_gattObjectMutex);
2993 uint32_t length = u_arraylist_length(g_gattObjectList);
2994 for (uint32_t index = 0; index < length; index++)
2996 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2999 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3000 ca_mutex_unlock(g_gattObjectMutex);
3004 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3005 if (!jni_setAddress)
3007 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3008 ca_mutex_unlock(g_gattObjectMutex);
3012 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3015 OIC_LOG(ERROR, TAG, "setAddress is null");
3016 ca_mutex_unlock(g_gattObjectMutex);
3020 if (!strcmp(remoteAddress, setAddress))
3022 OIC_LOG(DEBUG, TAG, "the device is already set");
3023 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3024 ca_mutex_unlock(g_gattObjectMutex);
3027 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3030 ca_mutex_unlock(g_gattObjectMutex);
3031 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3035 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3037 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3038 VERIFY_NON_NULL(env, TAG, "env is null");
3040 ca_mutex_lock(g_gattObjectMutex);
3041 if (!g_gattObjectList)
3043 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3044 ca_mutex_unlock(g_gattObjectMutex);
3045 return CA_STATUS_OK;
3048 uint32_t length = u_arraylist_length(g_gattObjectList);
3049 for (uint32_t index = 0; index < length; index++)
3051 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3054 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3057 (*env)->DeleteGlobalRef(env, jarrayObj);
3061 OICFree(g_gattObjectList);
3062 g_gattObjectList = NULL;
3063 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3064 ca_mutex_unlock(g_gattObjectMutex);
3065 return CA_STATUS_OK;
3068 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3070 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3071 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3072 VERIFY_NON_NULL(env, TAG, "env is null");
3074 ca_mutex_lock(g_gattObjectMutex);
3075 if (!g_gattObjectList)
3077 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3078 ca_mutex_unlock(g_gattObjectMutex);
3079 return CA_STATUS_OK;
3082 uint32_t length = u_arraylist_length(g_gattObjectList);
3083 for (uint32_t index = 0; index < length; index++)
3085 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3088 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3089 ca_mutex_unlock(g_gattObjectMutex);
3090 return CA_STATUS_FAILED;
3093 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3094 if (!jni_setAddress)
3096 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3097 ca_mutex_unlock(g_gattObjectMutex);
3098 return CA_STATUS_FAILED;
3101 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3104 OIC_LOG(ERROR, TAG, "setAddress is null");
3105 ca_mutex_unlock(g_gattObjectMutex);
3106 return CA_STATUS_FAILED;
3109 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3110 if (!jni_remoteAddress)
3112 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3113 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3114 ca_mutex_unlock(g_gattObjectMutex);
3115 return CA_STATUS_FAILED;
3118 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3121 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3122 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3123 ca_mutex_unlock(g_gattObjectMutex);
3124 return CA_STATUS_FAILED;
3127 if (!strcmp(setAddress, remoteAddress))
3129 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3130 (*env)->DeleteGlobalRef(env, jarrayObj);
3132 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3133 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3135 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3137 OIC_LOG(ERROR, TAG, "List removal failed.");
3138 ca_mutex_unlock(g_gattObjectMutex);
3139 return CA_STATUS_FAILED;
3141 ca_mutex_unlock(g_gattObjectMutex);
3142 return CA_STATUS_OK;
3144 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3145 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3148 ca_mutex_unlock(g_gattObjectMutex);
3149 OIC_LOG(DEBUG, TAG, "there are no target object");
3150 return CA_STATUS_OK;
3153 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3155 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3156 VERIFY_NON_NULL(addr, TAG, "addr is null");
3157 VERIFY_NON_NULL(env, TAG, "env is null");
3159 ca_mutex_lock(g_gattObjectMutex);
3160 if (!g_gattObjectList)
3162 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3163 ca_mutex_unlock(g_gattObjectMutex);
3164 return CA_STATUS_OK;
3167 uint32_t length = u_arraylist_length(g_gattObjectList);
3168 for (uint32_t index = 0; index < length; index++)
3170 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3173 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3174 ca_mutex_unlock(g_gattObjectMutex);
3175 return CA_STATUS_FAILED;
3178 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3179 if (!jni_setAddress)
3181 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3182 ca_mutex_unlock(g_gattObjectMutex);
3183 return CA_STATUS_FAILED;
3186 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3189 OIC_LOG(ERROR, TAG, "setAddress is null");
3190 ca_mutex_unlock(g_gattObjectMutex);
3191 return CA_STATUS_FAILED;
3194 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3197 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3198 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3199 ca_mutex_unlock(g_gattObjectMutex);
3200 return CA_STATUS_FAILED;
3203 if (!strcmp(setAddress, remoteAddress))
3205 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3206 (*env)->DeleteGlobalRef(env, jarrayObj);
3208 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3209 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3210 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3212 OIC_LOG(ERROR, TAG, "List removal failed.");
3213 ca_mutex_unlock(g_gattObjectMutex);
3214 return CA_STATUS_FAILED;
3216 ca_mutex_unlock(g_gattObjectMutex);
3217 return CA_STATUS_OK;
3219 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3220 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3223 ca_mutex_unlock(g_gattObjectMutex);
3224 OIC_LOG(DEBUG, TAG, "there are no target object");
3225 return CA_STATUS_FAILED;
3228 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3230 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3232 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3233 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3235 // get Bluetooth Address
3236 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3237 if (!jni_btTargetAddress)
3239 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3243 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3246 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3250 // get method ID of getDevice()
3251 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3252 if (!jni_cid_gattdevice_list)
3254 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3255 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3259 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3260 METHODID_BT_DEVICE);
3261 if (!jni_mid_getDevice)
3263 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3264 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3268 size_t length = u_arraylist_length(g_gattObjectList);
3269 for (size_t index = 0; index < length; index++)
3271 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3274 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3275 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3279 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3280 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3281 if (!jni_obj_device)
3283 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3284 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3288 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3291 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3292 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3296 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3299 OIC_LOG(ERROR, TAG, "btAddress is not available");
3300 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3304 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3305 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3306 if (!strcmp(targetAddress, btAddress))
3308 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3311 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3314 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3316 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3317 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3318 (*env)->DeleteLocalRef(env, jni_btAddress);
3319 (*env)->DeleteLocalRef(env, jni_obj_device);
3320 return jni_LEAddress;
3322 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3323 (*env)->DeleteLocalRef(env, jni_btAddress);
3324 (*env)->DeleteLocalRef(env, jni_obj_device);
3327 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3335 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3336 uint16_t notificationState, uint16_t sendState)
3338 VERIFY_NON_NULL(address, TAG, "address is null");
3340 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3343 OIC_LOG(ERROR, TAG, "out of memory");
3344 return CA_MEMORY_ALLOC_FAILED;
3347 if (strlen(address) > CA_MACADDR_SIZE)
3349 OIC_LOG(ERROR, TAG, "address is not proper");
3351 return CA_STATUS_FAILED;
3354 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3355 newstate->connectedState = connectedState;
3356 newstate->notificationState = notificationState;
3357 newstate->sendState = sendState;
3358 return CALEClientAddDeviceStateToList(newstate);
3361 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3363 VERIFY_NON_NULL(state, TAG, "state is null");
3365 ca_mutex_lock(g_deviceStateListMutex);
3367 if (!g_deviceStateList)
3369 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3370 ca_mutex_unlock(g_deviceStateListMutex);
3371 return CA_STATUS_FAILED;
3374 if (CALEClientIsDeviceInList(state->address))
3376 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3379 OIC_LOG(ERROR, TAG, "curState is null");
3380 ca_mutex_unlock(g_deviceStateListMutex);
3381 return CA_STATUS_FAILED;
3384 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3386 state->notificationState = curState->notificationState;
3388 state->autoConnectFlag = curState->autoConnectFlag;
3390 // delete previous state for update new state
3391 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3392 if (CA_STATUS_OK != res)
3394 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3395 ca_mutex_unlock(g_deviceStateListMutex);
3399 u_arraylist_add(g_deviceStateList, state); // update new state
3400 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3401 state->connectedState, state->notificationState, state->address);
3403 ca_mutex_unlock(g_deviceStateListMutex);
3404 return CA_STATUS_OK;
3407 bool CALEClientIsDeviceInList(const char* remoteAddress)
3409 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3411 if (!g_deviceStateList)
3413 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3417 uint32_t length = u_arraylist_length(g_deviceStateList);
3418 for (uint32_t index = 0; index < length; index++)
3420 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3423 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3427 if (!strcmp(remoteAddress, state->address))
3429 OIC_LOG(DEBUG, TAG, "the device is already set");
3438 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3442 CAResult_t CALEClientRemoveAllDeviceState()
3444 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3446 ca_mutex_lock(g_deviceStateListMutex);
3447 if (!g_deviceStateList)
3449 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3450 ca_mutex_unlock(g_deviceStateListMutex);
3451 return CA_STATUS_FAILED;
3454 uint32_t length = u_arraylist_length(g_deviceStateList);
3455 for (uint32_t index = 0; index < length; index++)
3457 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3460 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3466 OICFree(g_deviceStateList);
3467 g_deviceStateList = NULL;
3468 ca_mutex_unlock(g_deviceStateListMutex);
3470 return CA_STATUS_OK;
3473 CAResult_t CALEClientResetDeviceStateForAll()
3475 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3477 ca_mutex_lock(g_deviceStateListMutex);
3478 if (!g_deviceStateList)
3480 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3481 ca_mutex_unlock(g_deviceStateListMutex);
3482 return CA_STATUS_FAILED;
3485 size_t length = u_arraylist_length(g_deviceStateList);
3486 for (size_t index = 0; index < length; index++)
3488 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3491 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3495 // autoConnectFlag value will be not changed,
3496 // since it has reset only termination case.
3497 state->connectedState = STATE_DISCONNECTED;
3498 state->notificationState = STATE_CHARACTER_UNSET;
3499 state->sendState = STATE_SEND_NONE;
3501 ca_mutex_unlock(g_deviceStateListMutex);
3503 return CA_STATUS_OK;
3506 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3508 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3509 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3511 if (!g_deviceStateList)
3513 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3514 return CA_STATUS_FAILED;
3517 uint32_t length = u_arraylist_length(g_deviceStateList);
3518 for (uint32_t index = 0; index < length; index++)
3520 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3523 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3527 if (!strcmp(state->address, remoteAddress))
3529 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3531 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3533 if (NULL == targetState)
3535 OIC_LOG(ERROR, TAG, "List removal failed.");
3536 return CA_STATUS_FAILED;
3539 OICFree(targetState);
3540 return CA_STATUS_OK;
3544 return CA_STATUS_OK;
3547 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3549 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3550 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3552 if (!g_deviceStateList)
3554 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3558 uint32_t length = u_arraylist_length(g_deviceStateList);
3559 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3561 for (uint32_t index = 0; index < length; index++)
3563 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3566 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3570 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3571 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3573 if (!strcmp(state->address, remoteAddress))
3575 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3582 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3584 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3585 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3587 ca_mutex_lock(g_deviceStateListMutex);
3588 if (!g_deviceStateList)
3590 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3591 ca_mutex_unlock(g_deviceStateListMutex);
3595 uint32_t length = u_arraylist_length(g_deviceStateList);
3596 for (uint32_t index = 0; index < length; index++)
3598 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3601 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3605 if (!strcmp(state->address, remoteAddress))
3607 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3609 if (STATE_CONNECTED == state->connectedState)
3611 ca_mutex_unlock(g_deviceStateListMutex);
3616 ca_mutex_unlock(g_deviceStateListMutex);
3621 ca_mutex_unlock(g_deviceStateListMutex);
3625 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3627 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3628 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3630 ca_mutex_lock(g_deviceStateListMutex);
3631 if (!g_deviceStateList)
3633 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3634 ca_mutex_unlock(g_deviceStateListMutex);
3638 uint32_t length = u_arraylist_length(g_deviceStateList);
3639 for (uint32_t index = 0; index < length; index++)
3641 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3644 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3648 if (!strcmp(state->address, remoteAddress))
3650 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3652 if (STATE_CHARACTER_SET == state->notificationState)
3654 ca_mutex_unlock(g_deviceStateListMutex);
3659 ca_mutex_unlock(g_deviceStateListMutex);
3665 ca_mutex_unlock(g_deviceStateListMutex);
3669 void CALEClientCreateDeviceList()
3671 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3673 // create new object array
3674 if (!g_gattObjectList)
3676 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3678 g_gattObjectList = u_arraylist_create();
3681 if (!g_deviceStateList)
3683 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3685 g_deviceStateList = u_arraylist_create();
3690 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3692 g_deviceList = u_arraylist_create();
3697 * Check Sent Count for remove g_sendBuffer
3699 void CALEClientUpdateSendCnt(JNIEnv *env)
3701 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3703 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3705 ca_mutex_lock(g_threadMutex);
3709 if (g_targetCnt <= g_currentSentCnt)
3712 g_currentSentCnt = 0;
3716 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3717 g_sendBuffer = NULL;
3719 // notity the thread
3720 ca_cond_signal(g_threadCond);
3722 CALEClientSetSendFinishFlag(true);
3723 OIC_LOG(DEBUG, TAG, "set signal for send data");
3726 ca_mutex_unlock(g_threadMutex);
3729 CAResult_t CALEClientInitGattMutexVaraibles()
3731 if (NULL == g_bleReqRespClientCbMutex)
3733 g_bleReqRespClientCbMutex = ca_mutex_new();
3734 if (NULL == g_bleReqRespClientCbMutex)
3736 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3737 return CA_STATUS_FAILED;
3741 if (NULL == g_bleServerBDAddressMutex)
3743 g_bleServerBDAddressMutex = ca_mutex_new();
3744 if (NULL == g_bleServerBDAddressMutex)
3746 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3747 return CA_STATUS_FAILED;
3751 if (NULL == g_threadMutex)
3753 g_threadMutex = ca_mutex_new();
3754 if (NULL == g_threadMutex)
3756 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3757 return CA_STATUS_FAILED;
3761 if (NULL == g_threadSendMutex)
3763 g_threadSendMutex = ca_mutex_new();
3764 if (NULL == g_threadSendMutex)
3766 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3767 return CA_STATUS_FAILED;
3771 if (NULL == g_deviceListMutex)
3773 g_deviceListMutex = ca_mutex_new();
3774 if (NULL == g_deviceListMutex)
3776 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3777 return CA_STATUS_FAILED;
3781 if (NULL == g_gattObjectMutex)
3783 g_gattObjectMutex = ca_mutex_new();
3784 if (NULL == g_gattObjectMutex)
3786 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3787 return CA_STATUS_FAILED;
3791 if (NULL == g_deviceStateListMutex)
3793 g_deviceStateListMutex = ca_mutex_new();
3794 if (NULL == g_deviceStateListMutex)
3796 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3797 return CA_STATUS_FAILED;
3801 if (NULL == g_SendFinishMutex)
3803 g_SendFinishMutex = ca_mutex_new();
3804 if (NULL == g_SendFinishMutex)
3806 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3807 return CA_STATUS_FAILED;
3811 if (NULL == g_scanMutex)
3813 g_scanMutex = ca_mutex_new();
3814 if (NULL == g_scanMutex)
3816 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3817 return CA_STATUS_FAILED;
3821 if (NULL == g_threadWriteCharacteristicMutex)
3823 g_threadWriteCharacteristicMutex = ca_mutex_new();
3824 if (NULL == g_threadWriteCharacteristicMutex)
3826 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3827 return CA_STATUS_FAILED;
3831 if (NULL == g_deviceScanRetryDelayMutex)
3833 g_deviceScanRetryDelayMutex = ca_mutex_new();
3834 if (NULL == g_deviceScanRetryDelayMutex)
3836 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3837 return CA_STATUS_FAILED;
3841 return CA_STATUS_OK;
3844 void CALEClientTerminateGattMutexVariables()
3846 ca_mutex_free(g_bleReqRespClientCbMutex);
3847 g_bleReqRespClientCbMutex = NULL;
3849 ca_mutex_free(g_bleServerBDAddressMutex);
3850 g_bleServerBDAddressMutex = NULL;
3852 ca_mutex_free(g_threadMutex);
3853 g_threadMutex = NULL;
3855 ca_mutex_free(g_threadSendMutex);
3856 g_threadSendMutex = NULL;
3858 ca_mutex_free(g_deviceListMutex);
3859 g_deviceListMutex = NULL;
3861 ca_mutex_free(g_SendFinishMutex);
3862 g_SendFinishMutex = NULL;
3864 ca_mutex_free(g_scanMutex);
3867 ca_mutex_free(g_threadWriteCharacteristicMutex);
3868 g_threadWriteCharacteristicMutex = NULL;
3870 ca_mutex_free(g_deviceScanRetryDelayMutex);
3871 g_deviceScanRetryDelayMutex = NULL;
3874 void CALEClientSetSendFinishFlag(bool flag)
3876 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3878 ca_mutex_lock(g_SendFinishMutex);
3879 g_isFinishedSendData = flag;
3880 ca_mutex_unlock(g_SendFinishMutex);
3887 CAResult_t CAStartLEGattClient()
3889 // init mutex for send logic
3890 if (!g_deviceDescCond)
3892 g_deviceDescCond = ca_cond_new();
3897 g_threadCond = ca_cond_new();
3900 if (!g_threadWriteCharacteristicCond)
3902 g_threadWriteCharacteristicCond = ca_cond_new();
3905 CAResult_t res = CALEClientStartMulticastServer();
3906 if (CA_STATUS_OK != res)
3908 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3912 g_isStartedLEClient = true;
3918 void CAStopLEGattClient()
3920 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3924 OIC_LOG(ERROR, TAG, "g_jvm is null");
3928 bool isAttached = false;
3930 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3933 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3934 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3938 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3944 CAResult_t ret = CALEClientDisconnectAll(env);
3945 if (CA_STATUS_OK != ret)
3947 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3950 ret = CALEClientStopScan();
3951 if(CA_STATUS_OK != ret)
3953 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3956 ca_mutex_lock(g_threadMutex);
3957 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3958 ca_cond_signal(g_threadCond);
3959 ca_mutex_unlock(g_threadMutex);
3961 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3962 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3963 ca_cond_signal(g_threadWriteCharacteristicCond);
3964 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3966 ca_mutex_lock(g_threadSendMutex);
3967 OIC_LOG(DEBUG, TAG, "signal - send cond");
3968 ca_cond_signal(g_deviceDescCond);
3969 ca_mutex_unlock(g_threadSendMutex);
3971 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3972 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3973 ca_cond_signal(g_deviceScanRetryDelayCond);
3974 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3977 ca_cond_free(g_deviceDescCond);
3978 ca_cond_free(g_threadCond);
3979 ca_cond_free(g_threadWriteCharacteristicCond);
3980 ca_cond_free(g_deviceScanRetryDelayCond);
3982 g_deviceDescCond = NULL;
3983 g_threadCond = NULL;
3984 g_threadWriteCharacteristicCond = NULL;
3985 g_deviceScanRetryDelayCond = NULL;
3989 (*g_jvm)->DetachCurrentThread(g_jvm);
3994 CAResult_t CAInitializeLEGattClient()
3996 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3997 CALEClientInitialize();
3998 return CA_STATUS_OK;
4001 void CATerminateLEGattClient()
4003 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4004 CAStopLEGattClient();
4005 CALEClientTerminate();
4008 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4009 uint32_t dataLen, CALETransferType_t type,
4012 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4013 VERIFY_NON_NULL(data, TAG, "data is null");
4014 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4016 if (LE_UNICAST != type || position < 0)
4018 OIC_LOG(ERROR, TAG, "this request is not unicast");
4019 return CA_STATUS_INVALID_PARAM;
4022 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4025 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4027 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4028 VERIFY_NON_NULL(data, TAG, "data is null");
4030 return CALEClientSendMulticastMessage(data, dataLen);
4033 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4035 ca_mutex_lock(g_bleReqRespClientCbMutex);
4036 g_CABLEClientDataReceivedCallback = callback;
4037 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4040 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4042 g_threadPoolHandle = handle;
4045 CAResult_t CAGetLEAddress(char **local_address)
4047 VERIFY_NON_NULL(local_address, TAG, "local_address");
4048 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4049 return CA_NOT_SUPPORTED;
4052 JNIEXPORT void JNICALL
4053 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4056 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4057 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4058 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4059 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4061 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4064 JNIEXPORT void JNICALL
4065 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4068 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4069 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4070 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4071 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4073 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4076 JNIEXPORT void JNICALL
4077 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4080 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4081 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4082 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4084 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4085 if (CA_STATUS_OK != res)
4087 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4091 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4093 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4095 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4096 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4098 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4099 if (!jni_cid_gattdevice_list)
4101 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4105 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4106 METHODID_BT_DEVICE);
4107 if (!jni_mid_getDevice)
4109 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4113 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4114 if (!jni_obj_device)
4116 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4120 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4123 OIC_LOG(ERROR, TAG, "jni_address is null");
4127 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4132 * Class: org_iotivity_ca_jar_caleinterface
4133 * Method: CALeGattConnectionStateChangeCallback
4134 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4136 JNIEXPORT void JNICALL
4137 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4143 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4145 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4146 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4147 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4149 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4150 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4151 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4153 if (gatt_success == status && state_connected == newstate) // le connected
4155 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4161 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4164 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4165 STATE_CHARACTER_NO_CHANGE,
4167 if (CA_STATUS_OK != res)
4169 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4170 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4173 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4175 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4178 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4179 if (CA_STATUS_OK != res)
4181 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4185 res = CALEClientDiscoverServices(env, gatt);
4186 if (CA_STATUS_OK != res)
4188 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4192 else if (state_disconnected == newstate) // le disconnected
4194 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4197 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4201 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4204 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4205 STATE_CHARACTER_UNSET,
4207 if (CA_STATUS_OK != res)
4209 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4210 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4213 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4215 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4218 CAResult_t res = CALEClientGattClose(env, gatt);
4219 if (CA_STATUS_OK != res)
4221 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4224 if (gatt_success == status)
4226 // that state is a general reason to disconnect BLE.
4227 // its means manual disconnected message from BT platform.
4228 // in this case Scanning has to start again and clean previous data.
4229 CAResult_t res = CALEClientStartScan();
4230 if (CA_STATUS_OK != res)
4232 if (CA_ADAPTER_NOT_ENABLED == res)
4234 // scan will be started with start server when adapter is enabled
4235 OIC_LOG(INFO, TAG, "Adapter was disabled");
4239 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4244 else if (GATT_ERROR == status)
4246 // when we get GATT ERROR(0x85), gatt connection can be called again.
4247 OIC_LOG(INFO, TAG, "retry gatt connect");
4249 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4252 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4256 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4259 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4263 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4266 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4274 if (CALECheckConnectionStateValue(status))
4276 // this state is unexpected reason to disconnect
4277 // if the reason is suitable, connection logic of the device will be destroyed.
4278 OIC_LOG(INFO, TAG, "connection logic destroy");
4283 // other reason is expected to running background connection in BT platform.
4284 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4285 CALEClientUpdateSendCnt(env);
4292 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4293 g_sendBuffer = NULL;
4301 CALEClientSendFinish(env, gatt);
4306 * Class: org_iotivity_ca_jar_caleinterface
4307 * Method: CALeGattServicesDiscoveredCallback
4308 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4310 JNIEXPORT void JNICALL
4311 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4316 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4317 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4318 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4319 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4321 if (0 != status) // discovery error
4323 CALEClientSendFinish(env, gatt);
4327 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4330 CALEClientSendFinish(env, gatt);
4334 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4337 CALEClientSendFinish(env, gatt);
4341 if (!CALEClientIsSetCharacteristic(address))
4343 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4346 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4350 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4351 if (!jni_obj_GattCharacteristic)
4353 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4357 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4358 jni_obj_GattCharacteristic);
4359 if (CA_STATUS_OK != res)
4361 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4365 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4366 if (CA_STATUS_OK != res)
4368 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4371 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4372 if (CA_STATUS_OK != res)
4374 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4380 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4382 if (CA_STATUS_OK != res)
4384 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4392 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4393 if (CA_STATUS_OK != res)
4395 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4400 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4401 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4406 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4407 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4408 CALEClientSendFinish(env, gatt);
4413 * Class: org_iotivity_ca_jar_caleinterface
4414 * Method: CALeGattCharacteristicWritjclasseCallback
4415 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4417 JNIEXPORT void JNICALL
4418 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4419 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4422 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4423 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4424 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4425 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4427 // send success & signal
4428 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4434 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4440 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4441 if (gatt_success != status) // error case
4443 OIC_LOG(ERROR, TAG, "send failure");
4446 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4447 if (CA_STATUS_OK != res)
4449 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4450 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4451 g_isSignalSetFlag = true;
4452 ca_cond_signal(g_threadWriteCharacteristicCond);
4453 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4455 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4456 STATE_CHARACTER_SET,
4458 if (CA_STATUS_OK != res)
4460 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4463 if (g_clientErrorCallback)
4465 jint length = (*env)->GetArrayLength(env, data);
4466 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4469 CALEClientSendFinish(env, gatt);
4475 OIC_LOG(DEBUG, TAG, "send success");
4476 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4477 STATE_SEND_SUCCESS);
4478 if (CA_STATUS_OK != res)
4480 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4483 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4484 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4485 g_isSignalSetFlag = true;
4486 ca_cond_signal(g_threadWriteCharacteristicCond);
4487 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4489 CALEClientUpdateSendCnt(env);
4492 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4498 CALEClientSendFinish(env, gatt);
4503 * Class: org_iotivity_ca_jar_caleinterface
4504 * Method: CALeGattCharacteristicChangedCallback
4505 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4507 JNIEXPORT void JNICALL
4508 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4509 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4511 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4512 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4513 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4514 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4515 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4517 // get Byte Array and convert to uint8_t*
4518 jint length = (*env)->GetArrayLength(env, data);
4521 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4523 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4524 jni_byte_responseData);
4526 uint8_t* receivedData = OICMalloc(length);
4529 OIC_LOG(ERROR, TAG, "receivedData is null");
4533 memcpy(receivedData, jni_byte_responseData, length);
4534 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4536 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4539 OIC_LOG(ERROR, TAG, "jni_address is null");
4540 OICFree(receivedData);
4544 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4547 OIC_LOG(ERROR, TAG, "address is null");
4548 OICFree(receivedData);
4552 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4553 receivedData, length);
4555 ca_mutex_lock(g_bleServerBDAddressMutex);
4556 uint32_t sentLength = 0;
4557 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4559 ca_mutex_unlock(g_bleServerBDAddressMutex);
4561 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4565 * Class: org_iotivity_ca_jar_caleinterface
4566 * Method: CALeGattDescriptorWriteCallback
4567 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4569 JNIEXPORT void JNICALL
4570 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4574 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4575 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4576 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4577 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4579 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4580 if (gatt_success != status) // error
4587 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4588 if (CA_STATUS_OK != res)
4590 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4599 CALEClientSendFinish(env, gatt);