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,
1054 CALEClientGetAutoConnectFlag(env, jni_address));
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, JNI_TRUE);
1127 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1128 return CA_STATUS_FAILED;
1133 return CA_STATUS_OK;
1136 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1138 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1139 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1141 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1142 if (!jni_cid_gattdevice_list)
1144 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1148 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1149 "()Landroid/bluetooth/BluetoothDevice;");
1150 if (!jni_mid_getDevice)
1152 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1156 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1157 if (!jni_obj_device)
1159 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1163 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1166 OIC_LOG(ERROR, TAG, "jni_address is null");
1176 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1179 OIC_LOG(DEBUG, TAG, "Gatt Close");
1180 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1181 VERIFY_NON_NULL(env, TAG, "env is null");
1183 // get BluetoothGatt class
1184 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1185 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1186 if (!jni_cid_BluetoothGatt)
1188 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1189 return CA_STATUS_FAILED;
1192 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1193 if (!jni_mid_closeGatt)
1195 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1196 return CA_STATUS_OK;
1199 // call disconnect gatt method
1200 OIC_LOG(DEBUG, TAG, "request to close GATT");
1201 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1203 if ((*env)->ExceptionCheck(env))
1205 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1206 (*env)->ExceptionDescribe(env);
1207 (*env)->ExceptionClear(env);
1208 return CA_STATUS_FAILED;
1211 return CA_STATUS_OK;
1214 CAResult_t CALEClientStartScan()
1216 if (!g_isStartedMulticastServer)
1218 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1219 return CA_STATUS_FAILED;
1222 if (!g_isStartedLEClient)
1224 OIC_LOG(ERROR, TAG, "LE client is not started");
1225 return CA_STATUS_FAILED;
1230 OIC_LOG(ERROR, TAG, "g_jvm is null");
1231 return CA_STATUS_FAILED;
1234 if (g_isStartedScan)
1236 OIC_LOG(INFO, TAG, "scanning is already started");
1237 return CA_STATUS_OK;
1240 bool isAttached = false;
1242 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1245 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1247 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1250 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1251 return CA_STATUS_FAILED;
1256 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1258 CAResult_t ret = CA_STATUS_OK;
1259 // scan gatt server with UUID
1260 if (g_leScanCallback && g_uuidList)
1263 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1265 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1267 if (CA_STATUS_OK != ret)
1269 if (CA_ADAPTER_NOT_ENABLED == ret)
1271 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1275 OIC_LOG(ERROR, TAG, "start scan has failed");
1282 (*g_jvm)->DetachCurrentThread(g_jvm);
1288 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1290 VERIFY_NON_NULL(callback, TAG, "callback is null");
1291 VERIFY_NON_NULL(env, TAG, "env is null");
1293 if (!CALEIsEnableBTAdapter(env))
1295 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1296 return CA_ADAPTER_NOT_ENABLED;
1299 // get default bt adapter class
1300 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1301 if (!jni_cid_BTAdapter)
1303 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1304 return CA_STATUS_FAILED;
1307 // get remote bt adapter method
1308 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1309 "getDefaultAdapter",
1310 METHODID_OBJECTNONPARAM);
1311 if (!jni_mid_getDefaultAdapter)
1313 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1314 return CA_STATUS_FAILED;
1317 // get start le scan method
1318 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1319 "(Landroid/bluetooth/BluetoothAdapter$"
1320 "LeScanCallback;)Z");
1321 if (!jni_mid_startLeScan)
1323 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1324 return CA_STATUS_FAILED;
1327 // gat bt adapter object
1328 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1329 jni_mid_getDefaultAdapter);
1330 if (!jni_obj_BTAdapter)
1332 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1333 return CA_STATUS_FAILED;
1336 // call start le scan method
1337 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1338 jni_mid_startLeScan, callback);
1339 if (!jni_obj_startLeScan)
1341 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1342 return CA_STATUS_FAILED;
1346 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1347 CALEClientSetScanFlag(true);
1350 return CA_STATUS_OK;
1353 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1355 VERIFY_NON_NULL(callback, TAG, "callback is null");
1356 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1357 VERIFY_NON_NULL(env, TAG, "env is null");
1359 if (!CALEIsEnableBTAdapter(env))
1361 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1362 return CA_ADAPTER_NOT_ENABLED;
1365 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1366 if (!jni_cid_BTAdapter)
1368 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1369 return CA_STATUS_FAILED;
1372 // get remote bt adapter method
1373 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1374 "getDefaultAdapter",
1375 METHODID_OBJECTNONPARAM);
1376 if (!jni_mid_getDefaultAdapter)
1378 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1379 return CA_STATUS_FAILED;
1382 // get start le scan method
1383 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1384 "([Ljava/util/UUID;Landroid/bluetooth/"
1385 "BluetoothAdapter$LeScanCallback;)Z");
1386 if (!jni_mid_startLeScan)
1388 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1389 return CA_STATUS_FAILED;
1392 // get bt adapter object
1393 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1394 jni_mid_getDefaultAdapter);
1395 if (!jni_obj_BTAdapter)
1397 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1398 return CA_STATUS_FAILED;
1401 // call start le scan method
1402 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1403 jni_mid_startLeScan, uuids, callback);
1404 if (!jni_obj_startLeScan)
1406 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1407 return CA_STATUS_FAILED;
1411 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1412 CALEClientSetScanFlag(true);
1415 return CA_STATUS_OK;
1418 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1420 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1421 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1424 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1427 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1431 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1432 "(Ljava/lang/String;)"
1433 "Ljava/util/UUID;");
1434 if (!jni_mid_fromString)
1436 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1440 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1441 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1445 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1449 return jni_obj_uuid;
1452 CAResult_t CALEClientStopScan()
1456 OIC_LOG(ERROR, TAG, "g_jvm is null");
1457 return CA_STATUS_FAILED;
1460 if (!g_isStartedScan)
1462 OIC_LOG(INFO, TAG, "scanning is already stopped");
1463 return CA_STATUS_OK;
1466 bool isAttached = false;
1468 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1471 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1472 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1475 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1476 return CA_STATUS_FAILED;
1481 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1482 if (CA_STATUS_OK != ret)
1484 if (CA_ADAPTER_NOT_ENABLED == ret)
1486 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1490 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1495 CALEClientSetScanFlag(false);
1500 (*g_jvm)->DetachCurrentThread(g_jvm);
1506 void CALEClientSetScanFlag(bool flag)
1508 ca_mutex_lock(g_scanMutex);
1509 g_isStartedScan = flag;
1510 ca_mutex_unlock(g_scanMutex);
1513 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1515 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1516 VERIFY_NON_NULL(callback, TAG, "callback is null");
1517 VERIFY_NON_NULL(env, TAG, "env is null");
1519 if (!CALEIsEnableBTAdapter(env))
1521 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1522 return CA_ADAPTER_NOT_ENABLED;
1525 // get default bt adapter class
1526 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1527 if (!jni_cid_BTAdapter)
1529 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1530 return CA_STATUS_FAILED;
1533 // get remote bt adapter method
1534 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1535 "getDefaultAdapter",
1536 METHODID_OBJECTNONPARAM);
1537 if (!jni_mid_getDefaultAdapter)
1539 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1540 return CA_STATUS_FAILED;
1543 // get start le scan method
1544 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1545 "(Landroid/bluetooth/"
1546 "BluetoothAdapter$LeScanCallback;)V");
1547 if (!jni_mid_stopLeScan)
1549 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1550 return CA_STATUS_FAILED;
1553 // gat bt adapter object
1554 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1555 jni_mid_getDefaultAdapter);
1556 if (!jni_obj_BTAdapter)
1558 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1559 return CA_STATUS_FAILED;
1562 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1563 // call start le scan method
1564 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1565 if ((*env)->ExceptionCheck(env))
1567 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1568 (*env)->ExceptionDescribe(env);
1569 (*env)->ExceptionClear(env);
1570 return CA_STATUS_FAILED;
1573 return CA_STATUS_OK;
1576 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1578 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1579 VERIFY_NON_NULL(env, TAG, "env");
1580 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1582 ca_mutex_lock(g_deviceStateListMutex);
1584 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1587 OIC_LOG(ERROR, TAG, "address is not available");
1588 return CA_STATUS_FAILED;
1591 if (CALEClientIsDeviceInList(address))
1593 CALEState_t* curState = CALEClientGetStateInfo(address);
1596 OIC_LOG(ERROR, TAG, "curState is null");
1597 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1598 ca_mutex_unlock(g_deviceStateListMutex);
1599 return CA_STATUS_FAILED;
1601 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1603 curState->autoConnectFlag = flag;
1606 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1607 ca_mutex_unlock(g_deviceStateListMutex);
1608 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1609 return CA_STATUS_OK;
1612 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1614 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1615 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1616 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1618 ca_mutex_lock(g_deviceStateListMutex);
1620 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1623 OIC_LOG(ERROR, TAG, "address is not available");
1627 CALEState_t* curState = CALEClientGetStateInfo(address);
1630 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1631 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1632 ca_mutex_unlock(g_deviceStateListMutex);
1635 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1637 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1638 ca_mutex_unlock(g_deviceStateListMutex);
1640 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1641 return curState->autoConnectFlag;
1644 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1646 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1647 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1648 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1650 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1651 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1654 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1657 OIC_LOG(ERROR, TAG, "address is not available");
1661 // close the gatt service
1662 jobject gatt = CALEClientGetGattObjInList(env, address);
1665 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1666 if (CA_STATUS_OK != res)
1668 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1669 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1673 // clean previous gatt object after close profile service
1674 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1675 if (CA_STATUS_OK != res)
1677 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1678 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1682 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1685 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1688 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1692 // add new gatt object into g_gattObjectList
1693 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1694 if (CA_STATUS_OK != res)
1696 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1703 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1705 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1706 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1707 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1709 if (!CALEIsEnableBTAdapter(env))
1711 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1715 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1718 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1722 // get BluetoothDevice class
1723 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1724 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1725 if (!jni_cid_BluetoothDevice)
1727 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1731 // get connectGatt method
1732 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1733 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1734 "(Landroid/content/Context;ZLandroid/"
1735 "bluetooth/BluetoothGattCallback;)"
1736 "Landroid/bluetooth/BluetoothGatt;");
1737 if (!jni_mid_connectGatt)
1739 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1743 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1744 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1745 jni_mid_connectGatt,
1747 autoconnect, g_leGattCallback);
1748 if (!jni_obj_connectGatt)
1750 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1751 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1752 CALEClientUpdateSendCnt(env);
1757 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1759 return jni_obj_connectGatt;
1762 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1764 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1766 VERIFY_NON_NULL(env, TAG, "env is null");
1767 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1769 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1770 if (!jni_cid_BTAdapter)
1772 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1773 return CA_STATUS_FAILED;
1776 // get remote bt adapter method
1777 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1778 "getDefaultAdapter",
1779 METHODID_OBJECTNONPARAM);
1780 if (!jni_mid_getDefaultAdapter)
1782 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1783 return CA_STATUS_FAILED;
1786 // gat bt adapter object
1787 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1788 jni_mid_getDefaultAdapter);
1789 if (!jni_obj_BTAdapter)
1791 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1792 return CA_STATUS_FAILED;
1795 // get closeProfileProxy method
1796 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1797 "closeProfileProxy",
1798 "(ILandroid/bluetooth/"
1799 "BluetoothProfile;)V");
1800 if (!jni_mid_closeProfileProxy)
1802 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1803 return CA_STATUS_FAILED;
1806 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1807 if (!jni_cid_BTProfile)
1809 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1810 return CA_STATUS_FAILED;
1813 // GATT - Constant value : 7 (0x00000007)
1814 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1818 OIC_LOG(ERROR, TAG, "id_gatt is null");
1819 return CA_STATUS_FAILED;
1822 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1824 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1825 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1826 if ((*env)->ExceptionCheck(env))
1828 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1829 (*env)->ExceptionDescribe(env);
1830 (*env)->ExceptionClear(env);
1831 return CA_STATUS_FAILED;
1834 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1835 return CA_STATUS_OK;
1839 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1841 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1842 VERIFY_NON_NULL(env, TAG, "env is null");
1843 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1845 // get BluetoothGatt class
1846 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1847 if (!jni_cid_BluetoothGatt)
1849 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1850 return CA_STATUS_FAILED;
1853 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1854 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1855 "disconnect", "()V");
1856 if (!jni_mid_disconnectGatt)
1858 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1859 return CA_STATUS_FAILED;
1862 // call disconnect gatt method
1863 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1864 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1865 if ((*env)->ExceptionCheck(env))
1867 OIC_LOG(ERROR, TAG, "disconnect has failed");
1868 (*env)->ExceptionDescribe(env);
1869 (*env)->ExceptionClear(env);
1870 return CA_STATUS_FAILED;
1873 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1875 return CA_STATUS_OK;
1878 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1880 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1881 VERIFY_NON_NULL(env, TAG, "env is null");
1883 if (!g_gattObjectList)
1885 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1886 return CA_STATUS_OK;
1889 uint32_t length = u_arraylist_length(g_gattObjectList);
1890 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1891 for (uint32_t index = 0; index < length; index++)
1893 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1894 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1897 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1900 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1901 if (CA_STATUS_OK != res)
1903 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1908 return CA_STATUS_OK;
1911 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1913 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1914 VERIFY_NON_NULL(env, TAG, "env is null");
1916 if (!g_gattObjectList)
1918 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1919 return CA_STATUS_OK;
1922 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1925 OIC_LOG(ERROR, TAG, "address is null");
1926 return CA_STATUS_FAILED;
1929 uint32_t length = u_arraylist_length(g_gattObjectList);
1930 for (uint32_t index = 0; index < length; index++)
1932 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1935 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1939 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1940 if (!jni_setAddress)
1942 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1943 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1944 return CA_STATUS_FAILED;
1947 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1950 OIC_LOG(ERROR, TAG, "setAddress is null");
1951 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1952 return CA_STATUS_FAILED;
1955 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1956 if (!strcmp(address, setAddress))
1958 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1959 if (CA_STATUS_OK != res)
1961 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1962 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1963 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1964 return CA_STATUS_FAILED;
1966 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1967 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1968 return CA_STATUS_OK;
1970 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1972 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1974 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1975 return CA_STATUS_OK;
1978 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1980 VERIFY_NON_NULL(env, TAG, "env is null");
1981 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1983 if (!CALEIsEnableBTAdapter(env))
1985 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1986 return CA_ADAPTER_NOT_ENABLED;
1989 // get BluetoothGatt class
1990 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1991 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1992 if (!jni_cid_BluetoothGatt)
1994 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1995 return CA_STATUS_FAILED;
1998 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1999 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2000 "discoverServices", "()Z");
2001 if (!jni_mid_discoverServices)
2003 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2004 return CA_STATUS_FAILED;
2006 // call disconnect gatt method
2007 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
2008 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2011 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2012 return CA_STATUS_FAILED;
2015 return CA_STATUS_OK;
2018 static void CALEWriteCharacteristicThread(void* object)
2020 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2022 bool isAttached = false;
2024 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2027 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2028 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2032 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2038 jobject gatt = (jobject)object;
2039 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2040 if (CA_STATUS_OK != ret)
2042 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2047 (*g_jvm)->DetachCurrentThread(g_jvm);
2051 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2053 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2054 VERIFY_NON_NULL(env, TAG, "env is null");
2057 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2058 if (!jni_obj_character)
2060 CALEClientSendFinish(env, gatt);
2061 return CA_STATUS_FAILED;
2064 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2065 if (CA_STATUS_OK != ret)
2067 CALEClientSendFinish(env, gatt);
2068 return CA_STATUS_FAILED;
2071 // wait for callback for write Characteristic with success to sent data
2072 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2073 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2074 if (!g_isSignalSetFlag)
2076 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2077 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2078 g_threadWriteCharacteristicMutex,
2079 WAIT_TIME_WRITE_CHARACTERISTIC))
2081 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2082 g_isSignalSetFlag = false;
2083 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2084 return CA_STATUS_FAILED;
2087 // reset flag set by writeCharacteristic Callback
2088 g_isSignalSetFlag = false;
2089 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2091 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2092 return CA_STATUS_OK;
2095 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2097 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2098 VERIFY_NON_NULL(env, TAG, "env is null");
2099 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2101 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2102 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2103 CALEWriteCharacteristicThread, (void*)gattParam))
2105 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2106 return CA_STATUS_FAILED;
2109 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2110 return CA_STATUS_OK;
2113 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2114 jobject gattCharacteristic)
2116 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2117 VERIFY_NON_NULL(env, TAG, "env is null");
2118 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2119 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2121 if (!CALEIsEnableBTAdapter(env))
2123 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2124 return CA_STATUS_FAILED;
2127 // get BluetoothGatt class
2128 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2129 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2130 if (!jni_cid_BluetoothGatt)
2132 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2133 return CA_STATUS_FAILED;
2136 OIC_LOG(DEBUG, TAG, "write characteristic method");
2137 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2138 "writeCharacteristic",
2139 "(Landroid/bluetooth/"
2140 "BluetoothGattCharacteristic;)Z");
2141 if (!jni_mid_writeCharacteristic)
2143 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2144 return CA_STATUS_FAILED;
2147 // call disconnect gatt method
2148 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2149 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2150 jni_mid_writeCharacteristic,
2151 gattCharacteristic);
2154 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2158 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2159 return CA_STATUS_FAILED;
2162 return CA_STATUS_OK;
2165 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2167 VERIFY_NON_NULL(env, TAG, "env is null");
2168 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2170 if (!CALEIsEnableBTAdapter(env))
2172 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2173 return CA_STATUS_FAILED;
2176 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2177 if (!jni_cid_BluetoothGatt)
2179 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2180 return CA_STATUS_FAILED;
2183 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2186 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2187 return CA_STATUS_FAILED;
2190 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2191 if (!jni_obj_GattCharacteristic)
2193 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2194 return CA_STATUS_FAILED;
2197 OIC_LOG(DEBUG, TAG, "read characteristic method");
2198 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2199 "readCharacteristic",
2200 "(Landroid/bluetooth/"
2201 "BluetoothGattCharacteristic;)Z");
2202 if (!jni_mid_readCharacteristic)
2204 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2205 return CA_STATUS_FAILED;
2208 // call disconnect gatt method
2209 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2210 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2211 jni_obj_GattCharacteristic);
2214 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2218 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2219 return CA_STATUS_FAILED;
2222 return CA_STATUS_OK;
2225 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2226 jobject characteristic)
2228 VERIFY_NON_NULL(env, TAG, "env is null");
2229 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2230 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2232 if (!CALEIsEnableBTAdapter(env))
2234 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2235 return CA_ADAPTER_NOT_ENABLED;
2238 // get BluetoothGatt class
2239 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2240 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2241 if (!jni_cid_BluetoothGatt)
2243 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2244 return CA_STATUS_FAILED;
2247 // set Characteristic Notification
2248 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2249 "setCharacteristicNotification",
2250 "(Landroid/bluetooth/"
2251 "BluetoothGattCharacteristic;Z)Z");
2252 if (!jni_mid_setNotification)
2254 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2255 return CA_STATUS_FAILED;
2258 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2259 characteristic, JNI_TRUE);
2260 if (JNI_TRUE == ret)
2262 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2266 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2267 return CA_STATUS_FAILED;
2270 return CA_STATUS_OK;
2273 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2275 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2276 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2277 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2279 if (!CALEIsEnableBTAdapter(env))
2281 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2285 // get BluetoothGatt class
2286 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2287 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2288 if (!jni_cid_BluetoothGatt)
2290 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2294 jmethodID jni_mid_getService = (*env)->GetMethodID(
2295 env, jni_cid_BluetoothGatt, "getService",
2296 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2297 if (!jni_mid_getService)
2299 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2303 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2304 if (!jni_obj_service_uuid)
2306 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2310 // get bluetooth gatt service
2311 OIC_LOG(DEBUG, TAG, "request to get service");
2312 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2313 jni_obj_service_uuid);
2314 if (!jni_obj_gattService)
2316 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2320 // get bluetooth gatt service class
2321 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2322 env, "android/bluetooth/BluetoothGattService");
2323 if (!jni_cid_BluetoothGattService)
2325 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2329 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2330 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2331 "getCharacteristic",
2332 "(Ljava/util/UUID;)"
2333 "Landroid/bluetooth/"
2334 "BluetoothGattCharacteristic;");
2335 if (!jni_mid_getCharacteristic)
2337 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2341 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2344 OIC_LOG(ERROR, TAG, "uuid is null");
2348 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2349 if (!jni_obj_tx_uuid)
2351 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2352 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2356 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2357 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2358 jni_mid_getCharacteristic,
2361 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2362 return jni_obj_GattCharacteristic;
2365 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2367 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2368 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2369 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2370 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2372 if (!CALEIsEnableBTAdapter(env))
2374 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2378 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2381 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2385 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2386 if (!jni_obj_GattCharacteristic)
2388 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2392 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2393 "/BluetoothGattCharacteristic");
2394 if (!jni_cid_BTGattCharacteristic)
2396 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2400 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2401 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2403 if (!jni_mid_setValue)
2405 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2409 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2411 if (JNI_TRUE == ret)
2413 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2417 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2422 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2423 "setWriteType", "(I)V");
2424 if (!jni_mid_setWriteType)
2426 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2430 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2431 "WRITE_TYPE_NO_RESPONSE", "I");
2432 if (!jni_fid_no_response)
2434 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2438 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2439 jni_fid_no_response);
2441 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2443 return jni_obj_GattCharacteristic;
2446 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2448 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2449 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2451 if (!CALEIsEnableBTAdapter(env))
2453 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2457 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2458 "BluetoothGattCharacteristic");
2459 if (!jni_cid_BTGattCharacteristic)
2461 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2465 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2466 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2468 if (!jni_mid_getValue)
2470 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2474 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2476 return jni_obj_data_array;
2479 CAResult_t CALEClientCreateUUIDList()
2483 OIC_LOG(ERROR, TAG, "g_jvm is null");
2484 return CA_STATUS_FAILED;
2487 bool isAttached = false;
2489 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2492 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2493 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2497 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2498 return CA_STATUS_FAILED;
2503 // create new object array
2504 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2505 if (!jni_cid_uuid_list)
2507 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2511 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2512 jni_cid_uuid_list, NULL);
2513 if (!jni_obj_uuid_list)
2515 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2520 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2523 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2526 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2528 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2532 (*g_jvm)->DetachCurrentThread(g_jvm);
2535 return CA_STATUS_OK;
2542 (*g_jvm)->DetachCurrentThread(g_jvm);
2544 return CA_STATUS_FAILED;
2547 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2548 jobject characteristic)
2550 VERIFY_NON_NULL(env, TAG, "env is null");
2551 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2552 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2554 if (!CALEIsEnableBTAdapter(env))
2556 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2557 return CA_ADAPTER_NOT_ENABLED;
2560 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2561 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2562 "BluetoothGattCharacteristic");
2563 if (!jni_cid_BTGattCharacteristic)
2565 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2566 return CA_STATUS_FAILED;
2569 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2570 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2572 "(Ljava/util/UUID;)Landroid/bluetooth/"
2573 "BluetoothGattDescriptor;");
2574 if (!jni_mid_getDescriptor)
2576 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2577 return CA_STATUS_FAILED;
2580 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2581 if (!jni_obj_cc_uuid)
2583 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2584 return CA_STATUS_FAILED;
2587 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2588 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2589 jni_mid_getDescriptor, jni_obj_cc_uuid);
2590 if (!jni_obj_descriptor)
2592 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2593 return CA_NOT_SUPPORTED;
2596 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2597 jclass jni_cid_descriptor = (*env)->FindClass(env,
2598 "android/bluetooth/BluetoothGattDescriptor");
2599 if (!jni_cid_descriptor)
2601 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2602 return CA_STATUS_FAILED;
2605 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2606 if (!jni_mid_setValue)
2608 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2609 return CA_STATUS_FAILED;
2612 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2613 "ENABLE_NOTIFICATION_VALUE", "[B");
2614 if (!jni_fid_NotiValue)
2616 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2617 return CA_STATUS_FAILED;
2620 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2622 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2623 env, jni_obj_descriptor, jni_mid_setValue,
2624 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2627 OIC_LOG(DEBUG, TAG, "setValue success");
2631 OIC_LOG(ERROR, TAG, "setValue has failed");
2632 return CA_STATUS_FAILED;
2635 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2638 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2639 return CA_STATUS_FAILED;
2642 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2643 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2644 "(Landroid/bluetooth/"
2645 "BluetoothGattDescriptor;)Z");
2646 if (!jni_mid_writeDescriptor)
2648 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2649 return CA_STATUS_FAILED;
2652 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2653 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2654 jni_obj_descriptor);
2657 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2661 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2662 return CA_STATUS_FAILED;
2665 return CA_STATUS_OK;
2668 void CALEClientCreateScanDeviceList(JNIEnv *env)
2670 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2671 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2673 ca_mutex_lock(g_deviceListMutex);
2674 // create new object array
2675 if (g_deviceList == NULL)
2677 OIC_LOG(DEBUG, TAG, "Create device list");
2679 g_deviceList = u_arraylist_create();
2681 ca_mutex_unlock(g_deviceListMutex);
2684 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2686 VERIFY_NON_NULL(device, TAG, "device is null");
2687 VERIFY_NON_NULL(env, TAG, "env is null");
2689 ca_mutex_lock(g_deviceListMutex);
2693 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2694 ca_mutex_unlock(g_deviceListMutex);
2695 return CA_STATUS_FAILED;
2698 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2699 if (!jni_remoteAddress)
2701 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2702 ca_mutex_unlock(g_deviceListMutex);
2703 return CA_STATUS_FAILED;
2706 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2709 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2710 ca_mutex_unlock(g_deviceListMutex);
2711 return CA_STATUS_FAILED;
2714 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2716 jobject gdevice = (*env)->NewGlobalRef(env, device);
2717 u_arraylist_add(g_deviceList, gdevice);
2718 ca_cond_signal(g_deviceDescCond);
2719 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2721 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2723 ca_mutex_unlock(g_deviceListMutex);
2725 return CA_STATUS_OK;
2728 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2730 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2731 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2735 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2739 uint32_t length = u_arraylist_length(g_deviceList);
2740 for (uint32_t index = 0; index < length; index++)
2742 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2745 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2749 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2750 if (!jni_setAddress)
2752 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2756 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2759 OIC_LOG(ERROR, TAG, "setAddress is null");
2763 if (!strcmp(remoteAddress, setAddress))
2765 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2769 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2772 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2777 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2779 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2780 VERIFY_NON_NULL(env, TAG, "env is null");
2782 ca_mutex_lock(g_deviceListMutex);
2786 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2787 ca_mutex_unlock(g_deviceListMutex);
2788 return CA_STATUS_FAILED;
2791 uint32_t length = u_arraylist_length(g_deviceList);
2792 for (uint32_t index = 0; index < length; index++)
2794 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2797 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2800 (*env)->DeleteGlobalRef(env, jarrayObj);
2803 OICFree(g_deviceList);
2804 g_deviceList = NULL;
2806 ca_mutex_unlock(g_deviceListMutex);
2807 return CA_STATUS_OK;
2810 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2812 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2813 VERIFY_NON_NULL(address, TAG, "address is null");
2814 VERIFY_NON_NULL(env, TAG, "env is null");
2816 ca_mutex_lock(g_deviceListMutex);
2820 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2821 ca_mutex_unlock(g_deviceListMutex);
2822 return CA_STATUS_FAILED;
2825 uint32_t length = u_arraylist_length(g_deviceList);
2826 for (uint32_t index = 0; index < length; index++)
2828 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2831 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2832 ca_mutex_unlock(g_deviceListMutex);
2833 return CA_STATUS_FAILED;
2836 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2837 if (!jni_setAddress)
2839 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2840 ca_mutex_unlock(g_deviceListMutex);
2841 return CA_STATUS_FAILED;
2844 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2847 OIC_LOG(ERROR, TAG, "setAddress is null");
2848 ca_mutex_unlock(g_deviceListMutex);
2849 return CA_STATUS_FAILED;
2852 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2855 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2856 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2857 ca_mutex_unlock(g_deviceListMutex);
2858 return CA_STATUS_FAILED;
2861 if (!strcmp(setAddress, remoteAddress))
2863 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2864 (*env)->DeleteGlobalRef(env, jarrayObj);
2865 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2866 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2868 if (NULL == u_arraylist_remove(g_deviceList, index))
2870 OIC_LOG(ERROR, TAG, "List removal failed.");
2871 ca_mutex_unlock(g_deviceListMutex);
2872 return CA_STATUS_FAILED;
2874 ca_mutex_unlock(g_deviceListMutex);
2875 return CA_STATUS_OK;
2877 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2878 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2881 ca_mutex_unlock(g_deviceListMutex);
2882 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2884 return CA_STATUS_OK;
2891 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2893 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2894 VERIFY_NON_NULL(env, TAG, "env is null");
2895 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2897 ca_mutex_lock(g_gattObjectMutex);
2899 if (!g_gattObjectList)
2901 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2902 ca_mutex_unlock(g_gattObjectMutex);
2903 return CA_STATUS_FAILED;
2906 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2907 if (!jni_remoteAddress)
2909 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2910 ca_mutex_unlock(g_gattObjectMutex);
2911 return CA_STATUS_FAILED;
2914 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2917 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2918 ca_mutex_unlock(g_gattObjectMutex);
2919 return CA_STATUS_FAILED;
2922 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2923 if (!CALEClientIsGattObjInList(env, remoteAddress))
2925 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2926 u_arraylist_add(g_gattObjectList, newGatt);
2927 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2930 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2931 ca_mutex_unlock(g_gattObjectMutex);
2932 return CA_STATUS_OK;
2935 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2937 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2938 VERIFY_NON_NULL(env, TAG, "env is null");
2939 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2941 uint32_t length = u_arraylist_length(g_gattObjectList);
2942 for (uint32_t index = 0; index < length; index++)
2945 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2948 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2952 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2953 if (!jni_setAddress)
2955 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2959 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2962 OIC_LOG(ERROR, TAG, "setAddress is null");
2966 if (!strcmp(remoteAddress, setAddress))
2968 OIC_LOG(DEBUG, TAG, "the device is already set");
2969 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2974 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2979 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2983 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2985 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2986 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2987 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2989 ca_mutex_lock(g_gattObjectMutex);
2990 uint32_t length = u_arraylist_length(g_gattObjectList);
2991 for (uint32_t index = 0; index < length; index++)
2993 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2996 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2997 ca_mutex_unlock(g_gattObjectMutex);
3001 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3002 if (!jni_setAddress)
3004 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3005 ca_mutex_unlock(g_gattObjectMutex);
3009 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3012 OIC_LOG(ERROR, TAG, "setAddress is null");
3013 ca_mutex_unlock(g_gattObjectMutex);
3017 if (!strcmp(remoteAddress, setAddress))
3019 OIC_LOG(DEBUG, TAG, "the device is already set");
3020 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3021 ca_mutex_unlock(g_gattObjectMutex);
3024 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3027 ca_mutex_unlock(g_gattObjectMutex);
3028 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3032 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3034 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3035 VERIFY_NON_NULL(env, TAG, "env is null");
3037 ca_mutex_lock(g_gattObjectMutex);
3038 if (!g_gattObjectList)
3040 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3041 ca_mutex_unlock(g_gattObjectMutex);
3042 return CA_STATUS_OK;
3045 uint32_t length = u_arraylist_length(g_gattObjectList);
3046 for (uint32_t index = 0; index < length; index++)
3048 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3051 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3054 (*env)->DeleteGlobalRef(env, jarrayObj);
3057 OICFree(g_gattObjectList);
3058 g_gattObjectList = NULL;
3059 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3060 ca_mutex_unlock(g_gattObjectMutex);
3061 return CA_STATUS_OK;
3064 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3066 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3067 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3068 VERIFY_NON_NULL(env, TAG, "env is null");
3070 ca_mutex_lock(g_gattObjectMutex);
3071 if (!g_gattObjectList)
3073 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3074 ca_mutex_unlock(g_gattObjectMutex);
3075 return CA_STATUS_OK;
3078 uint32_t length = u_arraylist_length(g_gattObjectList);
3079 for (uint32_t index = 0; index < length; index++)
3081 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3084 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3085 ca_mutex_unlock(g_gattObjectMutex);
3086 return CA_STATUS_FAILED;
3089 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3090 if (!jni_setAddress)
3092 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3093 ca_mutex_unlock(g_gattObjectMutex);
3094 return CA_STATUS_FAILED;
3097 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3100 OIC_LOG(ERROR, TAG, "setAddress is null");
3101 ca_mutex_unlock(g_gattObjectMutex);
3102 return CA_STATUS_FAILED;
3105 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3106 if (!jni_remoteAddress)
3108 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3109 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3110 ca_mutex_unlock(g_gattObjectMutex);
3111 return CA_STATUS_FAILED;
3114 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3117 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3118 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3119 ca_mutex_unlock(g_gattObjectMutex);
3120 return CA_STATUS_FAILED;
3123 if (!strcmp(setAddress, remoteAddress))
3125 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3126 (*env)->DeleteGlobalRef(env, jarrayObj);
3127 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3128 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3130 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3132 OIC_LOG(ERROR, TAG, "List removal failed.");
3133 ca_mutex_unlock(g_gattObjectMutex);
3134 return CA_STATUS_FAILED;
3136 ca_mutex_unlock(g_gattObjectMutex);
3137 return CA_STATUS_OK;
3139 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3140 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3143 ca_mutex_unlock(g_gattObjectMutex);
3144 OIC_LOG(DEBUG, TAG, "there are no target object");
3145 return CA_STATUS_OK;
3148 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3150 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3151 VERIFY_NON_NULL(addr, TAG, "addr is null");
3152 VERIFY_NON_NULL(env, TAG, "env is null");
3154 ca_mutex_lock(g_gattObjectMutex);
3155 if (!g_gattObjectList)
3157 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3158 ca_mutex_unlock(g_gattObjectMutex);
3159 return CA_STATUS_OK;
3162 uint32_t length = u_arraylist_length(g_gattObjectList);
3163 for (uint32_t index = 0; index < length; index++)
3165 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3168 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3169 ca_mutex_unlock(g_gattObjectMutex);
3170 return CA_STATUS_FAILED;
3173 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3174 if (!jni_setAddress)
3176 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3177 ca_mutex_unlock(g_gattObjectMutex);
3178 return CA_STATUS_FAILED;
3181 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3184 OIC_LOG(ERROR, TAG, "setAddress is null");
3185 ca_mutex_unlock(g_gattObjectMutex);
3186 return CA_STATUS_FAILED;
3189 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3192 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3193 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3194 ca_mutex_unlock(g_gattObjectMutex);
3195 return CA_STATUS_FAILED;
3198 if (!strcmp(setAddress, remoteAddress))
3200 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3201 (*env)->DeleteGlobalRef(env, jarrayObj);
3203 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3204 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3205 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3207 OIC_LOG(ERROR, TAG, "List removal failed.");
3208 ca_mutex_unlock(g_gattObjectMutex);
3209 return CA_STATUS_FAILED;
3211 ca_mutex_unlock(g_gattObjectMutex);
3212 return CA_STATUS_OK;
3214 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3215 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3218 ca_mutex_unlock(g_gattObjectMutex);
3219 OIC_LOG(DEBUG, TAG, "there are no target object");
3220 return CA_STATUS_FAILED;
3223 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3225 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3227 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3228 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3230 // get Bluetooth Address
3231 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3232 if (!jni_btTargetAddress)
3234 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3238 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3241 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3245 // get method ID of getDevice()
3246 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3247 if (!jni_cid_gattdevice_list)
3249 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3250 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3254 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3255 METHODID_BT_DEVICE);
3256 if (!jni_mid_getDevice)
3258 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3259 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3263 size_t length = u_arraylist_length(g_gattObjectList);
3264 for (size_t index = 0; index < length; index++)
3266 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3269 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3270 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3274 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3275 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3276 if (!jni_obj_device)
3278 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3279 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3283 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3286 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3287 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3291 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3294 OIC_LOG(ERROR, TAG, "btAddress is not available");
3295 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3299 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3300 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3301 if (!strcmp(targetAddress, btAddress))
3303 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3306 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3309 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3311 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3312 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3313 (*env)->DeleteLocalRef(env, jni_btAddress);
3314 (*env)->DeleteLocalRef(env, jni_obj_device);
3315 return jni_LEAddress;
3317 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3318 (*env)->DeleteLocalRef(env, jni_btAddress);
3319 (*env)->DeleteLocalRef(env, jni_obj_device);
3322 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3330 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3331 uint16_t notificationState, uint16_t sendState)
3333 VERIFY_NON_NULL(address, TAG, "address is null");
3335 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3338 OIC_LOG(ERROR, TAG, "out of memory");
3339 return CA_MEMORY_ALLOC_FAILED;
3342 if (strlen(address) > CA_MACADDR_SIZE)
3344 OIC_LOG(ERROR, TAG, "address is not proper");
3346 return CA_STATUS_FAILED;
3349 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3350 newstate->connectedState = connectedState;
3351 newstate->notificationState = notificationState;
3352 newstate->sendState = sendState;
3353 return CALEClientAddDeviceStateToList(newstate);
3356 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3358 VERIFY_NON_NULL(state, TAG, "state is null");
3360 ca_mutex_lock(g_deviceStateListMutex);
3362 if (!g_deviceStateList)
3364 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3365 ca_mutex_unlock(g_deviceStateListMutex);
3366 return CA_STATUS_FAILED;
3369 if (CALEClientIsDeviceInList(state->address))
3371 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3374 OIC_LOG(ERROR, TAG, "curState is null");
3375 ca_mutex_unlock(g_deviceStateListMutex);
3376 return CA_STATUS_FAILED;
3379 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3381 state->notificationState = curState->notificationState;
3383 state->autoConnectFlag = curState->autoConnectFlag;
3385 // delete previous state for update new state
3386 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3387 if (CA_STATUS_OK != res)
3389 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3390 ca_mutex_unlock(g_deviceStateListMutex);
3394 u_arraylist_add(g_deviceStateList, state); // update new state
3395 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3396 state->connectedState, state->notificationState, state->address);
3398 ca_mutex_unlock(g_deviceStateListMutex);
3399 return CA_STATUS_OK;
3402 bool CALEClientIsDeviceInList(const char* remoteAddress)
3404 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3406 if (!g_deviceStateList)
3408 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3412 uint32_t length = u_arraylist_length(g_deviceStateList);
3413 for (uint32_t index = 0; index < length; index++)
3415 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3418 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3422 if (!strcmp(remoteAddress, state->address))
3424 OIC_LOG(DEBUG, TAG, "the device is already set");
3433 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3437 CAResult_t CALEClientRemoveAllDeviceState()
3439 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3441 ca_mutex_lock(g_deviceStateListMutex);
3442 if (!g_deviceStateList)
3444 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3445 ca_mutex_unlock(g_deviceStateListMutex);
3446 return CA_STATUS_FAILED;
3449 uint32_t length = u_arraylist_length(g_deviceStateList);
3450 for (uint32_t index = 0; index < length; index++)
3452 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3455 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3461 OICFree(g_deviceStateList);
3462 g_deviceStateList = NULL;
3463 ca_mutex_unlock(g_deviceStateListMutex);
3465 return CA_STATUS_OK;
3468 CAResult_t CALEClientResetDeviceStateForAll()
3470 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3472 ca_mutex_lock(g_deviceStateListMutex);
3473 if (!g_deviceStateList)
3475 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3476 ca_mutex_unlock(g_deviceStateListMutex);
3477 return CA_STATUS_FAILED;
3480 size_t length = u_arraylist_length(g_deviceStateList);
3481 for (size_t index = 0; index < length; index++)
3483 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3486 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3490 // autoConnectFlag value will be not changed,
3491 // since it has reset only termination case.
3492 state->connectedState = STATE_DISCONNECTED;
3493 state->notificationState = STATE_CHARACTER_UNSET;
3494 state->sendState = STATE_SEND_NONE;
3496 ca_mutex_unlock(g_deviceStateListMutex);
3498 return CA_STATUS_OK;
3501 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3503 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3504 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3506 if (!g_deviceStateList)
3508 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3509 return CA_STATUS_FAILED;
3512 uint32_t length = u_arraylist_length(g_deviceStateList);
3513 for (uint32_t index = 0; index < length; index++)
3515 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3518 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3522 if (!strcmp(state->address, remoteAddress))
3524 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3526 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3528 if (NULL == targetState)
3530 OIC_LOG(ERROR, TAG, "List removal failed.");
3531 return CA_STATUS_FAILED;
3534 OICFree(targetState);
3535 return CA_STATUS_OK;
3539 return CA_STATUS_OK;
3542 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3544 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3545 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3547 if (!g_deviceStateList)
3549 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3553 uint32_t length = u_arraylist_length(g_deviceStateList);
3554 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3556 for (uint32_t index = 0; index < length; index++)
3558 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3561 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3565 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3566 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3568 if (!strcmp(state->address, remoteAddress))
3570 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3577 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3579 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3580 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3582 ca_mutex_lock(g_deviceStateListMutex);
3583 if (!g_deviceStateList)
3585 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3586 ca_mutex_unlock(g_deviceStateListMutex);
3590 uint32_t length = u_arraylist_length(g_deviceStateList);
3591 for (uint32_t index = 0; index < length; index++)
3593 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3596 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3600 if (!strcmp(state->address, remoteAddress))
3602 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3604 if (STATE_CONNECTED == state->connectedState)
3606 ca_mutex_unlock(g_deviceStateListMutex);
3611 ca_mutex_unlock(g_deviceStateListMutex);
3616 ca_mutex_unlock(g_deviceStateListMutex);
3620 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3622 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3623 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3625 ca_mutex_lock(g_deviceStateListMutex);
3626 if (!g_deviceStateList)
3628 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3629 ca_mutex_unlock(g_deviceStateListMutex);
3633 uint32_t length = u_arraylist_length(g_deviceStateList);
3634 for (uint32_t index = 0; index < length; index++)
3636 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3639 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3643 if (!strcmp(state->address, remoteAddress))
3645 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3647 if (STATE_CHARACTER_SET == state->notificationState)
3649 ca_mutex_unlock(g_deviceStateListMutex);
3654 ca_mutex_unlock(g_deviceStateListMutex);
3660 ca_mutex_unlock(g_deviceStateListMutex);
3664 void CALEClientCreateDeviceList()
3666 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3668 // create new object array
3669 if (!g_gattObjectList)
3671 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3673 g_gattObjectList = u_arraylist_create();
3676 if (!g_deviceStateList)
3678 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3680 g_deviceStateList = u_arraylist_create();
3685 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3687 g_deviceList = u_arraylist_create();
3692 * Check Sent Count for remove g_sendBuffer
3694 void CALEClientUpdateSendCnt(JNIEnv *env)
3696 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3698 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3700 ca_mutex_lock(g_threadMutex);
3704 if (g_targetCnt <= g_currentSentCnt)
3707 g_currentSentCnt = 0;
3711 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3712 g_sendBuffer = NULL;
3714 // notity the thread
3715 ca_cond_signal(g_threadCond);
3717 CALEClientSetSendFinishFlag(true);
3718 OIC_LOG(DEBUG, TAG, "set signal for send data");
3721 ca_mutex_unlock(g_threadMutex);
3724 CAResult_t CALEClientInitGattMutexVaraibles()
3726 if (NULL == g_bleReqRespClientCbMutex)
3728 g_bleReqRespClientCbMutex = ca_mutex_new();
3729 if (NULL == g_bleReqRespClientCbMutex)
3731 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3732 return CA_STATUS_FAILED;
3736 if (NULL == g_bleServerBDAddressMutex)
3738 g_bleServerBDAddressMutex = ca_mutex_new();
3739 if (NULL == g_bleServerBDAddressMutex)
3741 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3742 return CA_STATUS_FAILED;
3746 if (NULL == g_threadMutex)
3748 g_threadMutex = ca_mutex_new();
3749 if (NULL == g_threadMutex)
3751 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3752 return CA_STATUS_FAILED;
3756 if (NULL == g_threadSendMutex)
3758 g_threadSendMutex = ca_mutex_new();
3759 if (NULL == g_threadSendMutex)
3761 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3762 return CA_STATUS_FAILED;
3766 if (NULL == g_deviceListMutex)
3768 g_deviceListMutex = ca_mutex_new();
3769 if (NULL == g_deviceListMutex)
3771 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3772 return CA_STATUS_FAILED;
3776 if (NULL == g_gattObjectMutex)
3778 g_gattObjectMutex = ca_mutex_new();
3779 if (NULL == g_gattObjectMutex)
3781 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3782 return CA_STATUS_FAILED;
3786 if (NULL == g_deviceStateListMutex)
3788 g_deviceStateListMutex = ca_mutex_new();
3789 if (NULL == g_deviceStateListMutex)
3791 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3792 return CA_STATUS_FAILED;
3796 if (NULL == g_SendFinishMutex)
3798 g_SendFinishMutex = ca_mutex_new();
3799 if (NULL == g_SendFinishMutex)
3801 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3802 return CA_STATUS_FAILED;
3806 if (NULL == g_scanMutex)
3808 g_scanMutex = ca_mutex_new();
3809 if (NULL == g_scanMutex)
3811 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3812 return CA_STATUS_FAILED;
3816 if (NULL == g_threadWriteCharacteristicMutex)
3818 g_threadWriteCharacteristicMutex = ca_mutex_new();
3819 if (NULL == g_threadWriteCharacteristicMutex)
3821 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3822 return CA_STATUS_FAILED;
3826 if (NULL == g_deviceScanRetryDelayMutex)
3828 g_deviceScanRetryDelayMutex = ca_mutex_new();
3829 if (NULL == g_deviceScanRetryDelayMutex)
3831 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3832 return CA_STATUS_FAILED;
3836 return CA_STATUS_OK;
3839 void CALEClientTerminateGattMutexVariables()
3841 ca_mutex_free(g_bleReqRespClientCbMutex);
3842 g_bleReqRespClientCbMutex = NULL;
3844 ca_mutex_free(g_bleServerBDAddressMutex);
3845 g_bleServerBDAddressMutex = NULL;
3847 ca_mutex_free(g_threadMutex);
3848 g_threadMutex = NULL;
3850 ca_mutex_free(g_threadSendMutex);
3851 g_threadSendMutex = NULL;
3853 ca_mutex_free(g_deviceListMutex);
3854 g_deviceListMutex = NULL;
3856 ca_mutex_free(g_SendFinishMutex);
3857 g_SendFinishMutex = NULL;
3859 ca_mutex_free(g_scanMutex);
3862 ca_mutex_free(g_threadWriteCharacteristicMutex);
3863 g_threadWriteCharacteristicMutex = NULL;
3865 ca_mutex_free(g_deviceScanRetryDelayMutex);
3866 g_deviceScanRetryDelayMutex = NULL;
3869 void CALEClientSetSendFinishFlag(bool flag)
3871 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3873 ca_mutex_lock(g_SendFinishMutex);
3874 g_isFinishedSendData = flag;
3875 ca_mutex_unlock(g_SendFinishMutex);
3882 CAResult_t CAStartLEGattClient()
3884 // init mutex for send logic
3885 if (!g_deviceDescCond)
3887 g_deviceDescCond = ca_cond_new();
3892 g_threadCond = ca_cond_new();
3895 if (!g_threadWriteCharacteristicCond)
3897 g_threadWriteCharacteristicCond = ca_cond_new();
3900 CAResult_t res = CALEClientStartMulticastServer();
3901 if (CA_STATUS_OK != res)
3903 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3907 g_isStartedLEClient = true;
3913 void CAStopLEGattClient()
3915 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3919 OIC_LOG(ERROR, TAG, "g_jvm is null");
3923 bool isAttached = false;
3925 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3928 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3929 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3933 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3939 CAResult_t ret = CALEClientDisconnectAll(env);
3940 if (CA_STATUS_OK != ret)
3942 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3945 ret = CALEClientStopScan();
3946 if(CA_STATUS_OK != ret)
3948 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3951 ca_mutex_lock(g_threadMutex);
3952 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3953 ca_cond_signal(g_threadCond);
3954 ca_mutex_unlock(g_threadMutex);
3956 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3957 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3958 ca_cond_signal(g_threadWriteCharacteristicCond);
3959 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3961 ca_mutex_lock(g_threadSendMutex);
3962 OIC_LOG(DEBUG, TAG, "signal - send cond");
3963 ca_cond_signal(g_deviceDescCond);
3964 ca_mutex_unlock(g_threadSendMutex);
3966 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3967 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3968 ca_cond_signal(g_deviceScanRetryDelayCond);
3969 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3972 ca_cond_free(g_deviceDescCond);
3973 ca_cond_free(g_threadCond);
3974 ca_cond_free(g_threadWriteCharacteristicCond);
3975 ca_cond_free(g_deviceScanRetryDelayCond);
3977 g_deviceDescCond = NULL;
3978 g_threadCond = NULL;
3979 g_threadWriteCharacteristicCond = NULL;
3980 g_deviceScanRetryDelayCond = NULL;
3984 (*g_jvm)->DetachCurrentThread(g_jvm);
3989 CAResult_t CAInitializeLEGattClient()
3991 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3992 CALEClientInitialize();
3993 return CA_STATUS_OK;
3996 void CATerminateLEGattClient()
3998 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3999 CAStopLEGattClient();
4000 CALEClientTerminate();
4003 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4004 uint32_t dataLen, CALETransferType_t type,
4007 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4008 VERIFY_NON_NULL(data, TAG, "data is null");
4009 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4011 if (LE_UNICAST != type || position < 0)
4013 OIC_LOG(ERROR, TAG, "this request is not unicast");
4014 return CA_STATUS_INVALID_PARAM;
4017 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4020 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4022 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4023 VERIFY_NON_NULL(data, TAG, "data is null");
4025 return CALEClientSendMulticastMessage(data, dataLen);
4028 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4030 ca_mutex_lock(g_bleReqRespClientCbMutex);
4031 g_CABLEClientDataReceivedCallback = callback;
4032 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4035 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4037 g_threadPoolHandle = handle;
4040 CAResult_t CAGetLEAddress(char **local_address)
4042 VERIFY_NON_NULL(local_address, TAG, "local_address");
4043 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4044 return CA_NOT_SUPPORTED;
4047 JNIEXPORT void JNICALL
4048 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4051 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4052 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4053 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4054 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4056 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4059 JNIEXPORT void JNICALL
4060 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4063 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4064 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4065 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4066 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4068 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4071 JNIEXPORT void JNICALL
4072 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4075 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4076 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4077 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4079 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4080 if (CA_STATUS_OK != res)
4082 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4086 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4088 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4090 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4091 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4093 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4094 if (!jni_cid_gattdevice_list)
4096 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4100 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4101 METHODID_BT_DEVICE);
4102 if (!jni_mid_getDevice)
4104 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4108 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4109 if (!jni_obj_device)
4111 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4115 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4118 OIC_LOG(ERROR, TAG, "jni_address is null");
4122 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4127 * Class: org_iotivity_ca_jar_caleinterface
4128 * Method: CALeGattConnectionStateChangeCallback
4129 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4131 JNIEXPORT void JNICALL
4132 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4138 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4140 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4141 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4142 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4144 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4145 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4146 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4148 if (gatt_success == status && state_connected == newstate) // le connected
4150 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4156 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4159 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4160 STATE_CHARACTER_NO_CHANGE,
4162 if (CA_STATUS_OK != res)
4164 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4165 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4168 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4170 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4173 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4174 if (CA_STATUS_OK != res)
4176 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4180 res = CALEClientDiscoverServices(env, gatt);
4181 if (CA_STATUS_OK != res)
4183 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4187 else if (state_disconnected == newstate) // le disconnected
4189 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4192 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4196 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4199 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4200 STATE_CHARACTER_UNSET,
4202 if (CA_STATUS_OK != res)
4204 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4205 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4208 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4210 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4213 CAResult_t res = CALEClientGattClose(env, gatt);
4214 if (CA_STATUS_OK != res)
4216 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4219 if (gatt_success == status)
4221 // that state is a general reason to disconnect BLE.
4222 // its means manual disconnected message from BT platform.
4223 // in this case Scanning has to start again and clean previous data.
4224 CAResult_t res = CALEClientStartScan();
4225 if (CA_STATUS_OK != res)
4227 if (CA_ADAPTER_NOT_ENABLED == res)
4229 // scan will be started with start server when adapter is enabled
4230 OIC_LOG(INFO, TAG, "Adapter was disabled");
4234 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4239 else if (GATT_ERROR == status)
4241 // when we get GATT ERROR(0x85), gatt connection can be called again.
4242 OIC_LOG(INFO, TAG, "retry gatt connect");
4244 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4247 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4251 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4254 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4258 jobject newGatt = CALEClientConnect(env, btObject,
4259 CALEClientGetAutoConnectFlag(env, leAddress));
4262 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4269 if (CALECheckConnectionStateValue(status))
4271 // this state is unexpected reason to disconnect
4272 // if the reason is suitable, connection logic of the device will be destroyed.
4273 OIC_LOG(INFO, TAG, "connection logic destroy");
4278 // other reason is expected to running background connection in BT platform.
4279 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4280 CALEClientUpdateSendCnt(env);
4287 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4288 g_sendBuffer = NULL;
4296 CALEClientSendFinish(env, gatt);
4301 * Class: org_iotivity_ca_jar_caleinterface
4302 * Method: CALeGattServicesDiscoveredCallback
4303 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4305 JNIEXPORT void JNICALL
4306 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4311 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4312 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4313 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4314 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4316 if (0 != status) // discovery error
4318 CALEClientSendFinish(env, gatt);
4322 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4325 CALEClientSendFinish(env, gatt);
4329 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4332 CALEClientSendFinish(env, gatt);
4336 if (!CALEClientIsSetCharacteristic(address))
4338 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4341 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4345 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4346 if (!jni_obj_GattCharacteristic)
4348 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4352 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4353 jni_obj_GattCharacteristic);
4354 if (CA_STATUS_OK != res)
4356 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4360 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4361 if (CA_STATUS_OK != res)
4363 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4366 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4367 if (CA_STATUS_OK != res)
4369 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4375 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4377 if (CA_STATUS_OK != res)
4379 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4387 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4388 if (CA_STATUS_OK != res)
4390 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4395 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4396 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4401 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4402 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4403 CALEClientSendFinish(env, gatt);
4408 * Class: org_iotivity_ca_jar_caleinterface
4409 * Method: CALeGattCharacteristicWritjclasseCallback
4410 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4412 JNIEXPORT void JNICALL
4413 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4414 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4417 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4418 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4419 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4420 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4422 // send success & signal
4423 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4429 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4435 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4436 if (gatt_success != status) // error case
4438 OIC_LOG(ERROR, TAG, "send failure");
4441 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4442 if (CA_STATUS_OK != res)
4444 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4445 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4446 g_isSignalSetFlag = true;
4447 ca_cond_signal(g_threadWriteCharacteristicCond);
4448 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4450 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4451 STATE_CHARACTER_SET,
4453 if (CA_STATUS_OK != res)
4455 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4458 if (g_clientErrorCallback)
4460 jint length = (*env)->GetArrayLength(env, data);
4461 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4464 CALEClientSendFinish(env, gatt);
4470 OIC_LOG(DEBUG, TAG, "send success");
4471 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4472 STATE_SEND_SUCCESS);
4473 if (CA_STATUS_OK != res)
4475 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4478 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4479 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4480 g_isSignalSetFlag = true;
4481 ca_cond_signal(g_threadWriteCharacteristicCond);
4482 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4484 CALEClientUpdateSendCnt(env);
4487 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4493 CALEClientSendFinish(env, gatt);
4498 * Class: org_iotivity_ca_jar_caleinterface
4499 * Method: CALeGattCharacteristicChangedCallback
4500 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4502 JNIEXPORT void JNICALL
4503 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4504 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4506 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4507 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4508 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4509 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4510 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4512 // get Byte Array and convert to uint8_t*
4513 jint length = (*env)->GetArrayLength(env, data);
4516 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4518 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4519 jni_byte_responseData);
4521 uint8_t* receivedData = OICMalloc(length);
4524 OIC_LOG(ERROR, TAG, "receivedData is null");
4528 memcpy(receivedData, jni_byte_responseData, length);
4529 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4531 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4534 OIC_LOG(ERROR, TAG, "jni_address is null");
4535 OICFree(receivedData);
4539 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4542 OIC_LOG(ERROR, TAG, "address is null");
4543 OICFree(receivedData);
4547 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4548 receivedData, length);
4550 ca_mutex_lock(g_bleServerBDAddressMutex);
4551 uint32_t sentLength = 0;
4552 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4554 ca_mutex_unlock(g_bleServerBDAddressMutex);
4556 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4560 * Class: org_iotivity_ca_jar_caleinterface
4561 * Method: CALeGattDescriptorWriteCallback
4562 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4564 JNIEXPORT void JNICALL
4565 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4569 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4570 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4571 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4572 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4574 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4575 if (gatt_success != status) // error
4582 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4583 if (CA_STATUS_OK != res)
4585 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4594 CALEClientSendFinish(env, gatt);