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