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);
676 // checking whether a target device is found while waiting for time-out.
677 if (CALEClientIsDeviceInScanDeviceList(env, address))
679 devicesDiscovered = true;
688 // time out for scanning devices
689 if (!devicesDiscovered)
691 return CA_STATUS_FAILED;
699 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
700 const uint32_t dataLen)
702 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
704 VERIFY_NON_NULL(address, TAG, "address is null");
705 VERIFY_NON_NULL(data, TAG, "data is null");
709 OIC_LOG(ERROR, TAG, "g_jvm is null");
710 return CA_STATUS_FAILED;
713 bool isAttached = false;
715 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
718 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
719 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
722 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
723 return CA_STATUS_FAILED;
728 ca_mutex_lock(g_threadSendMutex);
730 CALEClientSetSendFinishFlag(false);
732 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
733 if (CA_STATUS_OK != ret)
735 OIC_LOG(INFO, TAG, "there is no scanned device");
739 if (g_context && g_deviceList)
741 uint32_t length = u_arraylist_length(g_deviceList);
742 for (uint32_t index = 0; index < length; index++)
744 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
747 OIC_LOG(ERROR, TAG, "jarrayObj is null");
751 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
754 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
758 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
761 OIC_LOG(ERROR, TAG, "setAddress is null");
765 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
767 if (!strcmp(setAddress, address))
769 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
771 // connect to gatt server
772 ret = CALEClientStopScan();
773 if (CA_STATUS_OK != ret)
775 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
781 (*env)->DeleteGlobalRef(env, g_sendBuffer);
784 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
785 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
786 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
788 // Target device to send message is just one.
791 ret = CALEClientSendData(env, jarrayObj);
792 if (CA_STATUS_OK != ret)
794 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
798 OIC_LOG(INFO, TAG, "wake up");
801 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
805 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
807 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
808 // if there is no connection state.
809 ca_mutex_lock(g_threadMutex);
810 if (!g_isFinishedSendData)
812 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
813 ca_cond_wait(g_threadCond, g_threadMutex);
814 OIC_LOG(DEBUG, TAG, "the data was sent");
816 ca_mutex_unlock(g_threadMutex);
820 (*g_jvm)->DetachCurrentThread(g_jvm);
823 // start LE Scan again
824 ret = CALEClientStartScan();
825 if (CA_STATUS_OK != ret)
827 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
828 ca_mutex_unlock(g_threadSendMutex);
832 ca_mutex_unlock(g_threadSendMutex);
833 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
834 return CALECheckSendState(address);
839 // start LE Scan again
840 ret = CALEClientStartScan();
841 if (CA_STATUS_OK != ret)
843 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
844 ca_mutex_unlock(g_threadSendMutex);
847 (*g_jvm)->DetachCurrentThread(g_jvm);
854 (*g_jvm)->DetachCurrentThread(g_jvm);
857 if (g_clientErrorCallback)
859 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
861 ca_mutex_unlock(g_threadSendMutex);
862 return CA_SEND_FAILED;
865 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
866 const uint32_t dataLen)
868 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
869 VERIFY_NON_NULL(data, TAG, "data is null");
870 VERIFY_NON_NULL(env, TAG, "env is null");
874 OIC_LOG(ERROR, TAG, "g_deviceList is null");
875 return CA_STATUS_FAILED;
878 ca_mutex_lock(g_threadSendMutex);
880 CALEClientSetSendFinishFlag(false);
882 OIC_LOG(DEBUG, TAG, "set byteArray for data");
885 (*env)->DeleteGlobalRef(env, g_sendBuffer);
889 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
890 if (CA_STATUS_OK != res)
892 OIC_LOG(INFO, TAG, "there is no scanned device");
896 // connect to gatt server
897 res = CALEClientStopScan();
898 if (CA_STATUS_OK != res)
900 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
901 ca_mutex_unlock(g_threadSendMutex);
904 uint32_t length = u_arraylist_length(g_deviceList);
905 g_targetCnt = length;
907 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
908 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
909 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
911 for (uint32_t index = 0; index < length; index++)
913 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
916 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
920 res = CALEClientSendData(env, jarrayObj);
921 if (res != CA_STATUS_OK)
923 OIC_LOG(ERROR, TAG, "BT device - send has failed");
926 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
929 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
933 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
936 OIC_LOG(ERROR, TAG, "address is not available");
940 (*env)->ReleaseStringUTFChars(env, jni_address, address);
943 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
945 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
946 ca_mutex_lock(g_threadMutex);
947 if (!g_isFinishedSendData)
949 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
950 ca_cond_wait(g_threadCond, g_threadMutex);
951 OIC_LOG(DEBUG, TAG, "the data was sent");
953 ca_mutex_unlock(g_threadMutex);
955 // start LE Scan again
956 res = CALEClientStartScan();
957 if (CA_STATUS_OK != res)
959 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
960 ca_mutex_unlock(g_threadSendMutex);
964 ca_mutex_unlock(g_threadSendMutex);
965 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
969 res = CALEClientStartScan();
970 if (CA_STATUS_OK != res)
972 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
973 ca_mutex_unlock(g_threadSendMutex);
977 ca_mutex_unlock(g_threadSendMutex);
978 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
979 return CA_SEND_FAILED;
982 CAResult_t CALECheckSendState(const char* address)
984 VERIFY_NON_NULL(address, TAG, "address is null");
986 ca_mutex_lock(g_deviceStateListMutex);
987 CALEState_t* state = CALEClientGetStateInfo(address);
990 OIC_LOG(ERROR, TAG, "state is null");
991 ca_mutex_unlock(g_deviceStateListMutex);
992 return CA_SEND_FAILED;
995 if (STATE_SEND_SUCCESS != state->sendState)
997 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
998 ca_mutex_unlock(g_deviceStateListMutex);
999 return CA_SEND_FAILED;
1002 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
1003 ca_mutex_unlock(g_deviceStateListMutex);
1004 return CA_STATUS_OK;
1007 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1009 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1010 VERIFY_NON_NULL(device, TAG, "device is null");
1011 VERIFY_NON_NULL(env, TAG, "env is null");
1013 // get BLE address from bluetooth device object.
1014 char* address = NULL;
1015 CALEState_t* state = NULL;
1016 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1019 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1020 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1023 OIC_LOG(ERROR, TAG, "address is not available");
1024 return CA_STATUS_FAILED;
1026 ca_mutex_lock(g_deviceStateListMutex);
1027 state = CALEClientGetStateInfo(address);
1028 ca_mutex_unlock(g_deviceStateListMutex);
1029 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1034 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1036 // cancel previous connection request before connection
1037 // if there is gatt object in g_gattObjectList.
1040 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1043 OIC_LOG(ERROR, TAG, "address is not available");
1044 return CA_STATUS_FAILED;
1047 jobject gatt = CALEClientGetGattObjInList(env, address);
1050 CAResult_t res = CALEClientDisconnect(env, gatt);
1051 if (CA_STATUS_OK != res)
1053 OIC_LOG(INFO, TAG, "there is no gatt object");
1056 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1059 // connection request
1060 jobject newGatt = CALEClientConnect(env, device,
1062 if (NULL == newGatt)
1064 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1065 return CA_STATUS_FAILED;
1070 if (STATE_CONNECTED == state->connectedState)
1072 OIC_LOG(INFO, TAG, "GATT has already connected");
1075 OIC_LOG(ERROR, TAG, "jni_address is not available");
1076 return CA_STATUS_FAILED;
1079 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1082 OIC_LOG(ERROR, TAG, "address is not available");
1083 return CA_STATUS_FAILED;
1086 jobject gatt = CALEClientGetGattObjInList(env, address);
1089 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1090 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1091 return CA_STATUS_FAILED;
1094 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1095 if (CA_STATUS_OK != ret)
1097 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1098 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1101 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1105 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1107 // cancel previous connection request before connection
1108 // if there is gatt object in g_gattObjectList.
1111 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1114 OIC_LOG(ERROR, TAG, "address is not available");
1115 return CA_STATUS_FAILED;
1118 jobject gatt = CALEClientGetGattObjInList(env, address);
1121 CAResult_t res = CALEClientDisconnect(env, gatt);
1122 if (CA_STATUS_OK != res)
1124 OIC_LOG(INFO, TAG, "there is no gatt object");
1127 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1130 OIC_LOG(DEBUG, TAG, "start to connect LE");
1131 jobject gatt = CALEClientConnect(env, device,
1132 CALEClientGetAutoConnectFlag(env, jni_address));
1135 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1136 return CA_STATUS_FAILED;
1141 return CA_STATUS_OK;
1144 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1146 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1147 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1149 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1150 if (!jni_cid_gattdevice_list)
1152 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1156 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1157 "()Landroid/bluetooth/BluetoothDevice;");
1158 if (!jni_mid_getDevice)
1160 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1164 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1165 if (!jni_obj_device)
1167 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1171 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1174 OIC_LOG(ERROR, TAG, "jni_address is null");
1184 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1187 OIC_LOG(DEBUG, TAG, "Gatt Close");
1188 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1189 VERIFY_NON_NULL(env, TAG, "env is null");
1191 // get BluetoothGatt class
1192 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1193 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1194 if (!jni_cid_BluetoothGatt)
1196 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1197 return CA_STATUS_FAILED;
1200 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1201 if (!jni_mid_closeGatt)
1203 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1204 return CA_STATUS_OK;
1207 // call disconnect gatt method
1208 OIC_LOG(DEBUG, TAG, "request to close GATT");
1209 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1211 if ((*env)->ExceptionCheck(env))
1213 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1214 (*env)->ExceptionDescribe(env);
1215 (*env)->ExceptionClear(env);
1216 return CA_STATUS_FAILED;
1219 return CA_STATUS_OK;
1222 CAResult_t CALEClientStartScan()
1224 if (!g_isStartedMulticastServer)
1226 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1227 return CA_STATUS_FAILED;
1230 if (!g_isStartedLEClient)
1232 OIC_LOG(ERROR, TAG, "LE client is not started");
1233 return CA_STATUS_FAILED;
1238 OIC_LOG(ERROR, TAG, "g_jvm is null");
1239 return CA_STATUS_FAILED;
1242 if (g_isStartedScan)
1244 OIC_LOG(INFO, TAG, "scanning is already started");
1245 return CA_STATUS_OK;
1248 bool isAttached = false;
1250 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1253 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1255 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1258 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1259 return CA_STATUS_FAILED;
1264 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1266 CAResult_t ret = CA_STATUS_OK;
1267 // scan gatt server with UUID
1268 if (g_leScanCallback && g_uuidList)
1271 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1273 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1275 if (CA_STATUS_OK != ret)
1277 if (CA_ADAPTER_NOT_ENABLED == ret)
1279 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1283 OIC_LOG(ERROR, TAG, "start scan has failed");
1290 (*g_jvm)->DetachCurrentThread(g_jvm);
1296 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1298 VERIFY_NON_NULL(callback, TAG, "callback is null");
1299 VERIFY_NON_NULL(env, TAG, "env is null");
1301 if (!CALEIsEnableBTAdapter(env))
1303 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1304 return CA_ADAPTER_NOT_ENABLED;
1307 // get default bt adapter class
1308 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1309 if (!jni_cid_BTAdapter)
1311 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1312 return CA_STATUS_FAILED;
1315 // get remote bt adapter method
1316 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1317 "getDefaultAdapter",
1318 METHODID_OBJECTNONPARAM);
1319 if (!jni_mid_getDefaultAdapter)
1321 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1322 return CA_STATUS_FAILED;
1325 // get start le scan method
1326 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1327 "(Landroid/bluetooth/BluetoothAdapter$"
1328 "LeScanCallback;)Z");
1329 if (!jni_mid_startLeScan)
1331 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1332 return CA_STATUS_FAILED;
1335 // gat bt adapter object
1336 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1337 jni_mid_getDefaultAdapter);
1338 if (!jni_obj_BTAdapter)
1340 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1341 return CA_STATUS_FAILED;
1344 // call start le scan method
1345 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1346 jni_mid_startLeScan, callback);
1347 if (!jni_obj_startLeScan)
1349 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1350 return CA_STATUS_FAILED;
1354 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1355 CALEClientSetScanFlag(true);
1358 return CA_STATUS_OK;
1361 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1363 VERIFY_NON_NULL(callback, TAG, "callback is null");
1364 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1365 VERIFY_NON_NULL(env, TAG, "env is null");
1367 if (!CALEIsEnableBTAdapter(env))
1369 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1370 return CA_ADAPTER_NOT_ENABLED;
1373 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1374 if (!jni_cid_BTAdapter)
1376 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1377 return CA_STATUS_FAILED;
1380 // get remote bt adapter method
1381 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1382 "getDefaultAdapter",
1383 METHODID_OBJECTNONPARAM);
1384 if (!jni_mid_getDefaultAdapter)
1386 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1387 return CA_STATUS_FAILED;
1390 // get start le scan method
1391 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1392 "([Ljava/util/UUID;Landroid/bluetooth/"
1393 "BluetoothAdapter$LeScanCallback;)Z");
1394 if (!jni_mid_startLeScan)
1396 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1397 return CA_STATUS_FAILED;
1400 // get bt adapter object
1401 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1402 jni_mid_getDefaultAdapter);
1403 if (!jni_obj_BTAdapter)
1405 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1406 return CA_STATUS_FAILED;
1409 // call start le scan method
1410 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1411 jni_mid_startLeScan, uuids, callback);
1412 if (!jni_obj_startLeScan)
1414 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1415 return CA_STATUS_FAILED;
1419 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1420 CALEClientSetScanFlag(true);
1423 return CA_STATUS_OK;
1426 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1428 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1429 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1432 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1435 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1439 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1440 "(Ljava/lang/String;)"
1441 "Ljava/util/UUID;");
1442 if (!jni_mid_fromString)
1444 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1448 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1449 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1453 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1457 return jni_obj_uuid;
1460 CAResult_t CALEClientStopScan()
1464 OIC_LOG(ERROR, TAG, "g_jvm is null");
1465 return CA_STATUS_FAILED;
1468 if (!g_isStartedScan)
1470 OIC_LOG(INFO, TAG, "scanning is already stopped");
1471 return CA_STATUS_OK;
1474 bool isAttached = false;
1476 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1479 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1480 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1483 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1484 return CA_STATUS_FAILED;
1489 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1490 if (CA_STATUS_OK != ret)
1492 if (CA_ADAPTER_NOT_ENABLED == ret)
1494 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1498 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1503 CALEClientSetScanFlag(false);
1508 (*g_jvm)->DetachCurrentThread(g_jvm);
1514 void CALEClientSetScanFlag(bool flag)
1516 ca_mutex_lock(g_scanMutex);
1517 g_isStartedScan = flag;
1518 ca_mutex_unlock(g_scanMutex);
1521 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1523 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1524 VERIFY_NON_NULL(callback, TAG, "callback is null");
1525 VERIFY_NON_NULL(env, TAG, "env is null");
1527 if (!CALEIsEnableBTAdapter(env))
1529 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1530 return CA_ADAPTER_NOT_ENABLED;
1533 // get default bt adapter class
1534 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1535 if (!jni_cid_BTAdapter)
1537 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1538 return CA_STATUS_FAILED;
1541 // get remote bt adapter method
1542 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1543 "getDefaultAdapter",
1544 METHODID_OBJECTNONPARAM);
1545 if (!jni_mid_getDefaultAdapter)
1547 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1548 return CA_STATUS_FAILED;
1551 // get start le scan method
1552 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1553 "(Landroid/bluetooth/"
1554 "BluetoothAdapter$LeScanCallback;)V");
1555 if (!jni_mid_stopLeScan)
1557 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1558 return CA_STATUS_FAILED;
1561 // gat bt adapter object
1562 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1563 jni_mid_getDefaultAdapter);
1564 if (!jni_obj_BTAdapter)
1566 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1567 return CA_STATUS_FAILED;
1570 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1571 // call start le scan method
1572 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1573 if ((*env)->ExceptionCheck(env))
1575 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1576 (*env)->ExceptionDescribe(env);
1577 (*env)->ExceptionClear(env);
1578 return CA_STATUS_FAILED;
1581 return CA_STATUS_OK;
1584 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1586 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1587 VERIFY_NON_NULL(env, TAG, "env");
1588 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1590 ca_mutex_lock(g_deviceStateListMutex);
1592 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1595 OIC_LOG(ERROR, TAG, "address is not available");
1596 return CA_STATUS_FAILED;
1599 if (CALEClientIsDeviceInList(address))
1601 CALEState_t* curState = CALEClientGetStateInfo(address);
1604 OIC_LOG(ERROR, TAG, "curState is null");
1605 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1606 ca_mutex_unlock(g_deviceStateListMutex);
1607 return CA_STATUS_FAILED;
1609 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1611 curState->autoConnectFlag = flag;
1614 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1615 ca_mutex_unlock(g_deviceStateListMutex);
1616 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1617 return CA_STATUS_OK;
1620 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1622 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1623 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1624 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1626 ca_mutex_lock(g_deviceStateListMutex);
1628 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1631 OIC_LOG(ERROR, TAG, "address is not available");
1635 CALEState_t* curState = CALEClientGetStateInfo(address);
1638 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1639 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1640 ca_mutex_unlock(g_deviceStateListMutex);
1643 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1645 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1646 ca_mutex_unlock(g_deviceStateListMutex);
1648 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1649 return curState->autoConnectFlag;
1652 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1654 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1655 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1656 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1658 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1659 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1662 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1665 OIC_LOG(ERROR, TAG, "address is not available");
1669 // close the gatt service
1670 jobject gatt = CALEClientGetGattObjInList(env, address);
1673 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1674 if (CA_STATUS_OK != res)
1676 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1677 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1681 // clean previous gatt object after close profile service
1682 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1683 if (CA_STATUS_OK != res)
1685 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1686 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1690 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1693 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1696 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1700 // add new gatt object into g_gattObjectList
1701 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1702 if (CA_STATUS_OK != res)
1704 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1711 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1713 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1714 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1715 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1717 if (!CALEIsEnableBTAdapter(env))
1719 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1723 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1726 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1730 // get BluetoothDevice class
1731 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1732 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1733 if (!jni_cid_BluetoothDevice)
1735 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1739 // get connectGatt method
1740 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1741 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1742 "(Landroid/content/Context;ZLandroid/"
1743 "bluetooth/BluetoothGattCallback;)"
1744 "Landroid/bluetooth/BluetoothGatt;");
1745 if (!jni_mid_connectGatt)
1747 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1751 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1752 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1753 jni_mid_connectGatt,
1755 autoconnect, g_leGattCallback);
1756 if (!jni_obj_connectGatt)
1758 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1759 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1760 CALEClientUpdateSendCnt(env);
1765 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1767 return jni_obj_connectGatt;
1770 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1772 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1774 VERIFY_NON_NULL(env, TAG, "env is null");
1775 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1777 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1778 if (!jni_cid_BTAdapter)
1780 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1781 return CA_STATUS_FAILED;
1784 // get remote bt adapter method
1785 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1786 "getDefaultAdapter",
1787 METHODID_OBJECTNONPARAM);
1788 if (!jni_mid_getDefaultAdapter)
1790 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1791 return CA_STATUS_FAILED;
1794 // gat bt adapter object
1795 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1796 jni_mid_getDefaultAdapter);
1797 if (!jni_obj_BTAdapter)
1799 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1800 return CA_STATUS_FAILED;
1803 // get closeProfileProxy method
1804 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1805 "closeProfileProxy",
1806 "(ILandroid/bluetooth/"
1807 "BluetoothProfile;)V");
1808 if (!jni_mid_closeProfileProxy)
1810 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1811 return CA_STATUS_FAILED;
1814 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1815 if (!jni_cid_BTProfile)
1817 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1818 return CA_STATUS_FAILED;
1821 // GATT - Constant value : 7 (0x00000007)
1822 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1826 OIC_LOG(ERROR, TAG, "id_gatt is null");
1827 return CA_STATUS_FAILED;
1830 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1832 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1833 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1834 if ((*env)->ExceptionCheck(env))
1836 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1837 (*env)->ExceptionDescribe(env);
1838 (*env)->ExceptionClear(env);
1839 return CA_STATUS_FAILED;
1842 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1843 return CA_STATUS_OK;
1847 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1849 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1850 VERIFY_NON_NULL(env, TAG, "env is null");
1851 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1853 // get BluetoothGatt class
1854 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1855 if (!jni_cid_BluetoothGatt)
1857 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1858 return CA_STATUS_FAILED;
1861 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1862 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1863 "disconnect", "()V");
1864 if (!jni_mid_disconnectGatt)
1866 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1867 return CA_STATUS_FAILED;
1870 // call disconnect gatt method
1871 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1872 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1873 if ((*env)->ExceptionCheck(env))
1875 OIC_LOG(ERROR, TAG, "disconnect has failed");
1876 (*env)->ExceptionDescribe(env);
1877 (*env)->ExceptionClear(env);
1878 return CA_STATUS_FAILED;
1881 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1883 return CA_STATUS_OK;
1886 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1888 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1889 VERIFY_NON_NULL(env, TAG, "env is null");
1891 if (!g_gattObjectList)
1893 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1894 return CA_STATUS_OK;
1897 uint32_t length = u_arraylist_length(g_gattObjectList);
1898 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1899 for (uint32_t index = 0; index < length; index++)
1901 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1902 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1905 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1908 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1909 if (CA_STATUS_OK != res)
1911 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1916 return CA_STATUS_OK;
1919 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1921 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1922 VERIFY_NON_NULL(env, TAG, "env is null");
1924 if (!g_gattObjectList)
1926 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1927 return CA_STATUS_OK;
1930 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1933 OIC_LOG(ERROR, TAG, "address is null");
1934 return CA_STATUS_FAILED;
1937 uint32_t length = u_arraylist_length(g_gattObjectList);
1938 for (uint32_t index = 0; index < length; index++)
1940 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1943 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1947 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1948 if (!jni_setAddress)
1950 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1951 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1952 return CA_STATUS_FAILED;
1955 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1958 OIC_LOG(ERROR, TAG, "setAddress is null");
1959 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1960 return CA_STATUS_FAILED;
1963 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1964 if (!strcmp(address, setAddress))
1966 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1967 if (CA_STATUS_OK != res)
1969 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1970 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1971 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1972 return CA_STATUS_FAILED;
1974 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1975 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1976 return CA_STATUS_OK;
1978 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1980 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1982 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1983 return CA_STATUS_OK;
1986 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1988 VERIFY_NON_NULL(env, TAG, "env is null");
1989 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1991 if (!CALEIsEnableBTAdapter(env))
1993 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1994 return CA_ADAPTER_NOT_ENABLED;
1997 // get BluetoothGatt class
1998 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1999 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2000 if (!jni_cid_BluetoothGatt)
2002 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2003 return CA_STATUS_FAILED;
2006 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
2007 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2008 "discoverServices", "()Z");
2009 if (!jni_mid_discoverServices)
2011 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
2012 return CA_STATUS_FAILED;
2014 // call disconnect gatt method
2015 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
2016 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
2019 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
2020 return CA_STATUS_FAILED;
2023 return CA_STATUS_OK;
2026 static void CALEWriteCharacteristicThread(void* object)
2028 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
2030 bool isAttached = false;
2032 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2035 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2036 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2040 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2046 jobject gatt = (jobject)object;
2047 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2048 if (CA_STATUS_OK != ret)
2050 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2055 (*g_jvm)->DetachCurrentThread(g_jvm);
2059 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2061 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2062 VERIFY_NON_NULL(env, TAG, "env is null");
2065 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2066 if (!jni_obj_character)
2068 CALEClientSendFinish(env, gatt);
2069 return CA_STATUS_FAILED;
2072 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2073 if (CA_STATUS_OK != ret)
2075 CALEClientSendFinish(env, gatt);
2076 return CA_STATUS_FAILED;
2079 // wait for callback for write Characteristic with success to sent data
2080 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2081 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2082 if (!g_isSignalSetFlag)
2084 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2085 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2086 g_threadWriteCharacteristicMutex,
2087 WAIT_TIME_WRITE_CHARACTERISTIC))
2089 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2090 g_isSignalSetFlag = false;
2091 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2092 return CA_STATUS_FAILED;
2095 // reset flag set by writeCharacteristic Callback
2096 g_isSignalSetFlag = false;
2097 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2099 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2100 return CA_STATUS_OK;
2103 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2105 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2106 VERIFY_NON_NULL(env, TAG, "env is null");
2107 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2109 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2110 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2111 CALEWriteCharacteristicThread, (void*)gattParam))
2113 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2114 return CA_STATUS_FAILED;
2117 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2118 return CA_STATUS_OK;
2121 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2122 jobject gattCharacteristic)
2124 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2125 VERIFY_NON_NULL(env, TAG, "env is null");
2126 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2127 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2129 if (!CALEIsEnableBTAdapter(env))
2131 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2132 return CA_STATUS_FAILED;
2135 // get BluetoothGatt class
2136 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2137 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2138 if (!jni_cid_BluetoothGatt)
2140 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2141 return CA_STATUS_FAILED;
2144 OIC_LOG(DEBUG, TAG, "write characteristic method");
2145 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2146 "writeCharacteristic",
2147 "(Landroid/bluetooth/"
2148 "BluetoothGattCharacteristic;)Z");
2149 if (!jni_mid_writeCharacteristic)
2151 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2152 return CA_STATUS_FAILED;
2155 // call disconnect gatt method
2156 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2157 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2158 jni_mid_writeCharacteristic,
2159 gattCharacteristic);
2162 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2166 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2167 return CA_STATUS_FAILED;
2170 return CA_STATUS_OK;
2173 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2175 VERIFY_NON_NULL(env, TAG, "env is null");
2176 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2178 if (!CALEIsEnableBTAdapter(env))
2180 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2181 return CA_STATUS_FAILED;
2184 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2185 if (!jni_cid_BluetoothGatt)
2187 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2188 return CA_STATUS_FAILED;
2191 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2194 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2195 return CA_STATUS_FAILED;
2198 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2199 if (!jni_obj_GattCharacteristic)
2201 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2202 return CA_STATUS_FAILED;
2205 OIC_LOG(DEBUG, TAG, "read characteristic method");
2206 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2207 "readCharacteristic",
2208 "(Landroid/bluetooth/"
2209 "BluetoothGattCharacteristic;)Z");
2210 if (!jni_mid_readCharacteristic)
2212 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2213 return CA_STATUS_FAILED;
2216 // call disconnect gatt method
2217 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2218 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2219 jni_obj_GattCharacteristic);
2222 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2226 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2227 return CA_STATUS_FAILED;
2230 return CA_STATUS_OK;
2233 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2234 jobject characteristic)
2236 VERIFY_NON_NULL(env, TAG, "env is null");
2237 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2238 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2240 if (!CALEIsEnableBTAdapter(env))
2242 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2243 return CA_ADAPTER_NOT_ENABLED;
2246 // get BluetoothGatt class
2247 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2248 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2249 if (!jni_cid_BluetoothGatt)
2251 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2252 return CA_STATUS_FAILED;
2255 // set Characteristic Notification
2256 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2257 "setCharacteristicNotification",
2258 "(Landroid/bluetooth/"
2259 "BluetoothGattCharacteristic;Z)Z");
2260 if (!jni_mid_setNotification)
2262 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2263 return CA_STATUS_FAILED;
2266 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2267 characteristic, JNI_TRUE);
2268 if (JNI_TRUE == ret)
2270 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2274 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2275 return CA_STATUS_FAILED;
2278 return CA_STATUS_OK;
2281 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2283 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2284 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2285 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2287 if (!CALEIsEnableBTAdapter(env))
2289 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2293 // get BluetoothGatt class
2294 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2295 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2296 if (!jni_cid_BluetoothGatt)
2298 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2302 jmethodID jni_mid_getService = (*env)->GetMethodID(
2303 env, jni_cid_BluetoothGatt, "getService",
2304 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2305 if (!jni_mid_getService)
2307 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2311 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2312 if (!jni_obj_service_uuid)
2314 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2318 // get bluetooth gatt service
2319 OIC_LOG(DEBUG, TAG, "request to get service");
2320 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2321 jni_obj_service_uuid);
2322 if (!jni_obj_gattService)
2324 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2328 // get bluetooth gatt service class
2329 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2330 env, "android/bluetooth/BluetoothGattService");
2331 if (!jni_cid_BluetoothGattService)
2333 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2337 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2338 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2339 "getCharacteristic",
2340 "(Ljava/util/UUID;)"
2341 "Landroid/bluetooth/"
2342 "BluetoothGattCharacteristic;");
2343 if (!jni_mid_getCharacteristic)
2345 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2349 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2352 OIC_LOG(ERROR, TAG, "uuid is null");
2356 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2357 if (!jni_obj_tx_uuid)
2359 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2360 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2364 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2365 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2366 jni_mid_getCharacteristic,
2369 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2370 return jni_obj_GattCharacteristic;
2373 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2375 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2376 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2377 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2378 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2380 if (!CALEIsEnableBTAdapter(env))
2382 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2386 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2389 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2393 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2394 if (!jni_obj_GattCharacteristic)
2396 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2400 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2401 "/BluetoothGattCharacteristic");
2402 if (!jni_cid_BTGattCharacteristic)
2404 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2408 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2409 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2411 if (!jni_mid_setValue)
2413 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2417 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2419 if (JNI_TRUE == ret)
2421 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2425 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2430 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2431 "setWriteType", "(I)V");
2432 if (!jni_mid_setWriteType)
2434 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2438 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2439 "WRITE_TYPE_NO_RESPONSE", "I");
2440 if (!jni_fid_no_response)
2442 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2446 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2447 jni_fid_no_response);
2449 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2451 return jni_obj_GattCharacteristic;
2454 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2456 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2457 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2459 if (!CALEIsEnableBTAdapter(env))
2461 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2465 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2466 "BluetoothGattCharacteristic");
2467 if (!jni_cid_BTGattCharacteristic)
2469 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2473 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2474 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2476 if (!jni_mid_getValue)
2478 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2482 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2484 return jni_obj_data_array;
2487 CAResult_t CALEClientCreateUUIDList()
2491 OIC_LOG(ERROR, TAG, "g_jvm is null");
2492 return CA_STATUS_FAILED;
2495 bool isAttached = false;
2497 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2500 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2501 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2505 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2506 return CA_STATUS_FAILED;
2511 // create new object array
2512 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2513 if (!jni_cid_uuid_list)
2515 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2519 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2520 jni_cid_uuid_list, NULL);
2521 if (!jni_obj_uuid_list)
2523 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2528 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2531 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2534 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2536 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2540 (*g_jvm)->DetachCurrentThread(g_jvm);
2543 return CA_STATUS_OK;
2550 (*g_jvm)->DetachCurrentThread(g_jvm);
2552 return CA_STATUS_FAILED;
2555 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2556 jobject characteristic)
2558 VERIFY_NON_NULL(env, TAG, "env is null");
2559 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2560 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2562 if (!CALEIsEnableBTAdapter(env))
2564 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2565 return CA_ADAPTER_NOT_ENABLED;
2568 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2569 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2570 "BluetoothGattCharacteristic");
2571 if (!jni_cid_BTGattCharacteristic)
2573 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2574 return CA_STATUS_FAILED;
2577 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2578 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2580 "(Ljava/util/UUID;)Landroid/bluetooth/"
2581 "BluetoothGattDescriptor;");
2582 if (!jni_mid_getDescriptor)
2584 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2585 return CA_STATUS_FAILED;
2588 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2589 if (!jni_obj_cc_uuid)
2591 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2592 return CA_STATUS_FAILED;
2595 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2596 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2597 jni_mid_getDescriptor, jni_obj_cc_uuid);
2598 if (!jni_obj_descriptor)
2600 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2601 return CA_NOT_SUPPORTED;
2604 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2605 jclass jni_cid_descriptor = (*env)->FindClass(env,
2606 "android/bluetooth/BluetoothGattDescriptor");
2607 if (!jni_cid_descriptor)
2609 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2610 return CA_STATUS_FAILED;
2613 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2614 if (!jni_mid_setValue)
2616 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2617 return CA_STATUS_FAILED;
2620 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2621 "ENABLE_NOTIFICATION_VALUE", "[B");
2622 if (!jni_fid_NotiValue)
2624 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2625 return CA_STATUS_FAILED;
2628 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2630 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2631 env, jni_obj_descriptor, jni_mid_setValue,
2632 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2635 OIC_LOG(DEBUG, TAG, "setValue success");
2639 OIC_LOG(ERROR, TAG, "setValue has failed");
2640 return CA_STATUS_FAILED;
2643 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2646 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2647 return CA_STATUS_FAILED;
2650 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2651 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2652 "(Landroid/bluetooth/"
2653 "BluetoothGattDescriptor;)Z");
2654 if (!jni_mid_writeDescriptor)
2656 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2657 return CA_STATUS_FAILED;
2660 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2661 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2662 jni_obj_descriptor);
2665 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2669 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2670 return CA_STATUS_FAILED;
2673 return CA_STATUS_OK;
2676 void CALEClientCreateScanDeviceList(JNIEnv *env)
2678 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2679 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2681 ca_mutex_lock(g_deviceListMutex);
2682 // create new object array
2683 if (g_deviceList == NULL)
2685 OIC_LOG(DEBUG, TAG, "Create device list");
2687 g_deviceList = u_arraylist_create();
2689 ca_mutex_unlock(g_deviceListMutex);
2692 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2694 VERIFY_NON_NULL(device, TAG, "device is null");
2695 VERIFY_NON_NULL(env, TAG, "env is null");
2697 ca_mutex_lock(g_deviceListMutex);
2701 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2702 ca_mutex_unlock(g_deviceListMutex);
2703 return CA_STATUS_FAILED;
2706 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2707 if (!jni_remoteAddress)
2709 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2710 ca_mutex_unlock(g_deviceListMutex);
2711 return CA_STATUS_FAILED;
2714 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2717 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2718 ca_mutex_unlock(g_deviceListMutex);
2719 return CA_STATUS_FAILED;
2722 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2724 jobject gdevice = (*env)->NewGlobalRef(env, device);
2725 u_arraylist_add(g_deviceList, gdevice);
2726 ca_cond_signal(g_deviceDescCond);
2727 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2729 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2731 ca_mutex_unlock(g_deviceListMutex);
2733 return CA_STATUS_OK;
2736 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2738 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2739 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2743 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2747 uint32_t length = u_arraylist_length(g_deviceList);
2748 for (uint32_t index = 0; index < length; index++)
2750 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2753 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2757 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2758 if (!jni_setAddress)
2760 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2764 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2767 OIC_LOG(ERROR, TAG, "setAddress is null");
2771 if (!strcmp(remoteAddress, setAddress))
2773 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2777 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2780 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2785 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2787 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2788 VERIFY_NON_NULL(env, TAG, "env is null");
2790 ca_mutex_lock(g_deviceListMutex);
2794 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2795 ca_mutex_unlock(g_deviceListMutex);
2796 return CA_STATUS_FAILED;
2799 uint32_t length = u_arraylist_length(g_deviceList);
2800 for (uint32_t index = 0; index < length; index++)
2802 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2805 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2808 (*env)->DeleteGlobalRef(env, jarrayObj);
2812 OICFree(g_deviceList);
2813 g_deviceList = NULL;
2815 ca_mutex_unlock(g_deviceListMutex);
2816 return CA_STATUS_OK;
2819 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2821 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2822 VERIFY_NON_NULL(address, TAG, "address is null");
2823 VERIFY_NON_NULL(env, TAG, "env is null");
2825 ca_mutex_lock(g_deviceListMutex);
2829 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2830 ca_mutex_unlock(g_deviceListMutex);
2831 return CA_STATUS_FAILED;
2834 uint32_t length = u_arraylist_length(g_deviceList);
2835 for (uint32_t index = 0; index < length; index++)
2837 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2840 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2841 ca_mutex_unlock(g_deviceListMutex);
2842 return CA_STATUS_FAILED;
2845 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2846 if (!jni_setAddress)
2848 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2849 ca_mutex_unlock(g_deviceListMutex);
2850 return CA_STATUS_FAILED;
2853 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2856 OIC_LOG(ERROR, TAG, "setAddress is null");
2857 ca_mutex_unlock(g_deviceListMutex);
2858 return CA_STATUS_FAILED;
2861 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2864 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2865 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2866 ca_mutex_unlock(g_deviceListMutex);
2867 return CA_STATUS_FAILED;
2870 if (!strcmp(setAddress, remoteAddress))
2872 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2873 (*env)->DeleteGlobalRef(env, jarrayObj);
2875 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2876 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2878 if (NULL == u_arraylist_remove(g_deviceList, index))
2880 OIC_LOG(ERROR, TAG, "List removal failed.");
2881 ca_mutex_unlock(g_deviceListMutex);
2882 return CA_STATUS_FAILED;
2884 ca_mutex_unlock(g_deviceListMutex);
2885 return CA_STATUS_OK;
2887 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2888 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2891 ca_mutex_unlock(g_deviceListMutex);
2892 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2894 return CA_STATUS_OK;
2901 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2903 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2904 VERIFY_NON_NULL(env, TAG, "env is null");
2905 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2907 ca_mutex_lock(g_gattObjectMutex);
2909 if (!g_gattObjectList)
2911 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2912 ca_mutex_unlock(g_gattObjectMutex);
2913 return CA_STATUS_FAILED;
2916 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2917 if (!jni_remoteAddress)
2919 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2920 ca_mutex_unlock(g_gattObjectMutex);
2921 return CA_STATUS_FAILED;
2924 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2927 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2928 ca_mutex_unlock(g_gattObjectMutex);
2929 return CA_STATUS_FAILED;
2932 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2933 if (!CALEClientIsGattObjInList(env, remoteAddress))
2935 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2936 u_arraylist_add(g_gattObjectList, newGatt);
2937 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2940 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2941 ca_mutex_unlock(g_gattObjectMutex);
2942 return CA_STATUS_OK;
2945 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2947 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2948 VERIFY_NON_NULL(env, TAG, "env is null");
2949 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2951 uint32_t length = u_arraylist_length(g_gattObjectList);
2952 for (uint32_t index = 0; index < length; index++)
2955 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2958 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2962 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2963 if (!jni_setAddress)
2965 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2969 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2972 OIC_LOG(ERROR, TAG, "setAddress is null");
2976 if (!strcmp(remoteAddress, setAddress))
2978 OIC_LOG(DEBUG, TAG, "the device is already set");
2979 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2984 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2989 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2993 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2995 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2996 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2997 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2999 ca_mutex_lock(g_gattObjectMutex);
3000 uint32_t length = u_arraylist_length(g_gattObjectList);
3001 for (uint32_t index = 0; index < length; index++)
3003 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3006 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3007 ca_mutex_unlock(g_gattObjectMutex);
3011 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3012 if (!jni_setAddress)
3014 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3015 ca_mutex_unlock(g_gattObjectMutex);
3019 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3022 OIC_LOG(ERROR, TAG, "setAddress is null");
3023 ca_mutex_unlock(g_gattObjectMutex);
3027 if (!strcmp(remoteAddress, setAddress))
3029 OIC_LOG(DEBUG, TAG, "the device is already set");
3030 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3031 ca_mutex_unlock(g_gattObjectMutex);
3034 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3037 ca_mutex_unlock(g_gattObjectMutex);
3038 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3042 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3044 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3045 VERIFY_NON_NULL(env, TAG, "env is null");
3047 ca_mutex_lock(g_gattObjectMutex);
3048 if (!g_gattObjectList)
3050 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3051 ca_mutex_unlock(g_gattObjectMutex);
3052 return CA_STATUS_OK;
3055 uint32_t length = u_arraylist_length(g_gattObjectList);
3056 for (uint32_t index = 0; index < length; index++)
3058 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3061 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3064 (*env)->DeleteGlobalRef(env, jarrayObj);
3068 OICFree(g_gattObjectList);
3069 g_gattObjectList = NULL;
3070 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3071 ca_mutex_unlock(g_gattObjectMutex);
3072 return CA_STATUS_OK;
3075 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3077 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3078 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3079 VERIFY_NON_NULL(env, TAG, "env is null");
3081 ca_mutex_lock(g_gattObjectMutex);
3082 if (!g_gattObjectList)
3084 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3085 ca_mutex_unlock(g_gattObjectMutex);
3086 return CA_STATUS_OK;
3089 uint32_t length = u_arraylist_length(g_gattObjectList);
3090 for (uint32_t index = 0; index < length; index++)
3092 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3095 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3096 ca_mutex_unlock(g_gattObjectMutex);
3097 return CA_STATUS_FAILED;
3100 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3101 if (!jni_setAddress)
3103 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3104 ca_mutex_unlock(g_gattObjectMutex);
3105 return CA_STATUS_FAILED;
3108 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3111 OIC_LOG(ERROR, TAG, "setAddress is null");
3112 ca_mutex_unlock(g_gattObjectMutex);
3113 return CA_STATUS_FAILED;
3116 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3117 if (!jni_remoteAddress)
3119 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3120 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3121 ca_mutex_unlock(g_gattObjectMutex);
3122 return CA_STATUS_FAILED;
3125 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3128 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3129 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3130 ca_mutex_unlock(g_gattObjectMutex);
3131 return CA_STATUS_FAILED;
3134 if (!strcmp(setAddress, remoteAddress))
3136 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3137 (*env)->DeleteGlobalRef(env, jarrayObj);
3139 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3140 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3142 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3144 OIC_LOG(ERROR, TAG, "List removal failed.");
3145 ca_mutex_unlock(g_gattObjectMutex);
3146 return CA_STATUS_FAILED;
3148 ca_mutex_unlock(g_gattObjectMutex);
3149 return CA_STATUS_OK;
3151 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3152 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3155 ca_mutex_unlock(g_gattObjectMutex);
3156 OIC_LOG(DEBUG, TAG, "there are no target object");
3157 return CA_STATUS_OK;
3160 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3162 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3163 VERIFY_NON_NULL(addr, TAG, "addr is null");
3164 VERIFY_NON_NULL(env, TAG, "env is null");
3166 ca_mutex_lock(g_gattObjectMutex);
3167 if (!g_gattObjectList)
3169 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3170 ca_mutex_unlock(g_gattObjectMutex);
3171 return CA_STATUS_OK;
3174 uint32_t length = u_arraylist_length(g_gattObjectList);
3175 for (uint32_t index = 0; index < length; index++)
3177 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3180 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3181 ca_mutex_unlock(g_gattObjectMutex);
3182 return CA_STATUS_FAILED;
3185 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3186 if (!jni_setAddress)
3188 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3189 ca_mutex_unlock(g_gattObjectMutex);
3190 return CA_STATUS_FAILED;
3193 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3196 OIC_LOG(ERROR, TAG, "setAddress is null");
3197 ca_mutex_unlock(g_gattObjectMutex);
3198 return CA_STATUS_FAILED;
3201 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3204 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3205 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3206 ca_mutex_unlock(g_gattObjectMutex);
3207 return CA_STATUS_FAILED;
3210 if (!strcmp(setAddress, remoteAddress))
3212 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3213 (*env)->DeleteGlobalRef(env, jarrayObj);
3215 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3216 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3217 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3219 OIC_LOG(ERROR, TAG, "List removal failed.");
3220 ca_mutex_unlock(g_gattObjectMutex);
3221 return CA_STATUS_FAILED;
3223 ca_mutex_unlock(g_gattObjectMutex);
3224 return CA_STATUS_OK;
3226 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3227 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3230 ca_mutex_unlock(g_gattObjectMutex);
3231 OIC_LOG(DEBUG, TAG, "there are no target object");
3232 return CA_STATUS_FAILED;
3235 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3237 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3239 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3240 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3242 // get Bluetooth Address
3243 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3244 if (!jni_btTargetAddress)
3246 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3250 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3253 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3257 // get method ID of getDevice()
3258 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3259 if (!jni_cid_gattdevice_list)
3261 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3262 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3266 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3267 METHODID_BT_DEVICE);
3268 if (!jni_mid_getDevice)
3270 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3271 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3275 size_t length = u_arraylist_length(g_gattObjectList);
3276 for (size_t index = 0; index < length; index++)
3278 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3281 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3282 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3286 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3287 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3288 if (!jni_obj_device)
3290 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3291 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3295 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3298 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3299 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3303 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3306 OIC_LOG(ERROR, TAG, "btAddress is not available");
3307 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3311 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3312 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3313 if (!strcmp(targetAddress, btAddress))
3315 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3318 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3321 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3323 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3324 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3325 (*env)->DeleteLocalRef(env, jni_btAddress);
3326 (*env)->DeleteLocalRef(env, jni_obj_device);
3327 return jni_LEAddress;
3329 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3330 (*env)->DeleteLocalRef(env, jni_btAddress);
3331 (*env)->DeleteLocalRef(env, jni_obj_device);
3334 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3342 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3343 uint16_t notificationState, uint16_t sendState)
3345 VERIFY_NON_NULL(address, TAG, "address is null");
3347 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3350 OIC_LOG(ERROR, TAG, "out of memory");
3351 return CA_MEMORY_ALLOC_FAILED;
3354 if (strlen(address) > CA_MACADDR_SIZE)
3356 OIC_LOG(ERROR, TAG, "address is not proper");
3358 return CA_STATUS_FAILED;
3361 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3362 newstate->connectedState = connectedState;
3363 newstate->notificationState = notificationState;
3364 newstate->sendState = sendState;
3365 return CALEClientAddDeviceStateToList(newstate);
3368 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3370 VERIFY_NON_NULL(state, TAG, "state is null");
3372 ca_mutex_lock(g_deviceStateListMutex);
3374 if (!g_deviceStateList)
3376 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3377 ca_mutex_unlock(g_deviceStateListMutex);
3378 return CA_STATUS_FAILED;
3381 if (CALEClientIsDeviceInList(state->address))
3383 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3386 OIC_LOG(ERROR, TAG, "curState is null");
3387 ca_mutex_unlock(g_deviceStateListMutex);
3388 return CA_STATUS_FAILED;
3391 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3393 state->notificationState = curState->notificationState;
3395 state->autoConnectFlag = curState->autoConnectFlag;
3397 // delete previous state for update new state
3398 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3399 if (CA_STATUS_OK != res)
3401 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3402 ca_mutex_unlock(g_deviceStateListMutex);
3406 u_arraylist_add(g_deviceStateList, state); // update new state
3407 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
3408 state->connectedState, state->notificationState,
3409 state->address, state->autoConnectFlag);
3411 ca_mutex_unlock(g_deviceStateListMutex);
3412 return CA_STATUS_OK;
3415 bool CALEClientIsDeviceInList(const char* remoteAddress)
3417 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3419 if (!g_deviceStateList)
3421 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3425 uint32_t length = u_arraylist_length(g_deviceStateList);
3426 for (uint32_t index = 0; index < length; index++)
3428 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3431 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3435 if (!strcmp(remoteAddress, state->address))
3437 OIC_LOG(DEBUG, TAG, "the device is already set");
3446 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3450 CAResult_t CALEClientRemoveAllDeviceState()
3452 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3454 ca_mutex_lock(g_deviceStateListMutex);
3455 if (!g_deviceStateList)
3457 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3458 ca_mutex_unlock(g_deviceStateListMutex);
3459 return CA_STATUS_FAILED;
3462 uint32_t length = u_arraylist_length(g_deviceStateList);
3463 for (uint32_t index = 0; index < length; index++)
3465 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3468 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3474 OICFree(g_deviceStateList);
3475 g_deviceStateList = NULL;
3476 ca_mutex_unlock(g_deviceStateListMutex);
3478 return CA_STATUS_OK;
3481 CAResult_t CALEClientResetDeviceStateForAll()
3483 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3485 ca_mutex_lock(g_deviceStateListMutex);
3486 if (!g_deviceStateList)
3488 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3489 ca_mutex_unlock(g_deviceStateListMutex);
3490 return CA_STATUS_FAILED;
3493 size_t length = u_arraylist_length(g_deviceStateList);
3494 for (size_t index = 0; index < length; index++)
3496 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3499 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3503 // autoConnectFlag value will be not changed,
3504 // since it has reset only termination case.
3505 state->connectedState = STATE_DISCONNECTED;
3506 state->notificationState = STATE_CHARACTER_UNSET;
3507 state->sendState = STATE_SEND_NONE;
3509 ca_mutex_unlock(g_deviceStateListMutex);
3511 return CA_STATUS_OK;
3514 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3516 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3517 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3519 if (!g_deviceStateList)
3521 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3522 return CA_STATUS_FAILED;
3525 uint32_t length = u_arraylist_length(g_deviceStateList);
3526 for (uint32_t index = 0; index < length; index++)
3528 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3531 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3535 if (!strcmp(state->address, remoteAddress))
3537 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3539 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3541 if (NULL == targetState)
3543 OIC_LOG(ERROR, TAG, "List removal failed.");
3544 return CA_STATUS_FAILED;
3547 OICFree(targetState);
3548 return CA_STATUS_OK;
3552 return CA_STATUS_OK;
3555 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3557 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3558 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3560 if (!g_deviceStateList)
3562 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3566 uint32_t length = u_arraylist_length(g_deviceStateList);
3567 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3569 for (uint32_t index = 0; index < length; index++)
3571 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3574 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3578 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3579 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3581 if (!strcmp(state->address, remoteAddress))
3583 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3590 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3592 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3593 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3595 ca_mutex_lock(g_deviceStateListMutex);
3596 if (!g_deviceStateList)
3598 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3599 ca_mutex_unlock(g_deviceStateListMutex);
3603 uint32_t length = u_arraylist_length(g_deviceStateList);
3604 for (uint32_t index = 0; index < length; index++)
3606 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3609 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3613 if (!strcmp(state->address, remoteAddress))
3615 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3617 if (STATE_CONNECTED == state->connectedState)
3619 ca_mutex_unlock(g_deviceStateListMutex);
3624 ca_mutex_unlock(g_deviceStateListMutex);
3629 ca_mutex_unlock(g_deviceStateListMutex);
3633 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3635 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3636 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3638 ca_mutex_lock(g_deviceStateListMutex);
3639 if (!g_deviceStateList)
3641 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3642 ca_mutex_unlock(g_deviceStateListMutex);
3646 uint32_t length = u_arraylist_length(g_deviceStateList);
3647 for (uint32_t index = 0; index < length; index++)
3649 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3652 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3656 if (!strcmp(state->address, remoteAddress))
3658 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3660 if (STATE_CHARACTER_SET == state->notificationState)
3662 ca_mutex_unlock(g_deviceStateListMutex);
3667 ca_mutex_unlock(g_deviceStateListMutex);
3673 ca_mutex_unlock(g_deviceStateListMutex);
3677 void CALEClientCreateDeviceList()
3679 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3681 // create new object array
3682 if (!g_gattObjectList)
3684 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3686 g_gattObjectList = u_arraylist_create();
3689 if (!g_deviceStateList)
3691 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3693 g_deviceStateList = u_arraylist_create();
3698 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3700 g_deviceList = u_arraylist_create();
3705 * Check Sent Count for remove g_sendBuffer
3707 void CALEClientUpdateSendCnt(JNIEnv *env)
3709 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3711 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3713 ca_mutex_lock(g_threadMutex);
3717 if (g_targetCnt <= g_currentSentCnt)
3720 g_currentSentCnt = 0;
3724 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3725 g_sendBuffer = NULL;
3727 // notity the thread
3728 ca_cond_signal(g_threadCond);
3730 CALEClientSetSendFinishFlag(true);
3731 OIC_LOG(DEBUG, TAG, "set signal for send data");
3734 ca_mutex_unlock(g_threadMutex);
3737 CAResult_t CALEClientInitGattMutexVaraibles()
3739 if (NULL == g_bleReqRespClientCbMutex)
3741 g_bleReqRespClientCbMutex = ca_mutex_new();
3742 if (NULL == g_bleReqRespClientCbMutex)
3744 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3745 return CA_STATUS_FAILED;
3749 if (NULL == g_bleServerBDAddressMutex)
3751 g_bleServerBDAddressMutex = ca_mutex_new();
3752 if (NULL == g_bleServerBDAddressMutex)
3754 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3755 return CA_STATUS_FAILED;
3759 if (NULL == g_threadMutex)
3761 g_threadMutex = ca_mutex_new();
3762 if (NULL == g_threadMutex)
3764 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3765 return CA_STATUS_FAILED;
3769 if (NULL == g_threadSendMutex)
3771 g_threadSendMutex = ca_mutex_new();
3772 if (NULL == g_threadSendMutex)
3774 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3775 return CA_STATUS_FAILED;
3779 if (NULL == g_deviceListMutex)
3781 g_deviceListMutex = ca_mutex_new();
3782 if (NULL == g_deviceListMutex)
3784 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3785 return CA_STATUS_FAILED;
3789 if (NULL == g_gattObjectMutex)
3791 g_gattObjectMutex = ca_mutex_new();
3792 if (NULL == g_gattObjectMutex)
3794 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3795 return CA_STATUS_FAILED;
3799 if (NULL == g_deviceStateListMutex)
3801 g_deviceStateListMutex = ca_mutex_new();
3802 if (NULL == g_deviceStateListMutex)
3804 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3805 return CA_STATUS_FAILED;
3809 if (NULL == g_SendFinishMutex)
3811 g_SendFinishMutex = ca_mutex_new();
3812 if (NULL == g_SendFinishMutex)
3814 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3815 return CA_STATUS_FAILED;
3819 if (NULL == g_scanMutex)
3821 g_scanMutex = ca_mutex_new();
3822 if (NULL == g_scanMutex)
3824 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3825 return CA_STATUS_FAILED;
3829 if (NULL == g_threadWriteCharacteristicMutex)
3831 g_threadWriteCharacteristicMutex = ca_mutex_new();
3832 if (NULL == g_threadWriteCharacteristicMutex)
3834 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3835 return CA_STATUS_FAILED;
3839 if (NULL == g_deviceScanRetryDelayMutex)
3841 g_deviceScanRetryDelayMutex = ca_mutex_new();
3842 if (NULL == g_deviceScanRetryDelayMutex)
3844 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3845 return CA_STATUS_FAILED;
3849 return CA_STATUS_OK;
3852 void CALEClientTerminateGattMutexVariables()
3854 ca_mutex_free(g_bleReqRespClientCbMutex);
3855 g_bleReqRespClientCbMutex = NULL;
3857 ca_mutex_free(g_bleServerBDAddressMutex);
3858 g_bleServerBDAddressMutex = NULL;
3860 ca_mutex_free(g_threadMutex);
3861 g_threadMutex = NULL;
3863 ca_mutex_free(g_threadSendMutex);
3864 g_threadSendMutex = NULL;
3866 ca_mutex_free(g_deviceListMutex);
3867 g_deviceListMutex = NULL;
3869 ca_mutex_free(g_SendFinishMutex);
3870 g_SendFinishMutex = NULL;
3872 ca_mutex_free(g_scanMutex);
3875 ca_mutex_free(g_threadWriteCharacteristicMutex);
3876 g_threadWriteCharacteristicMutex = NULL;
3878 ca_mutex_free(g_deviceScanRetryDelayMutex);
3879 g_deviceScanRetryDelayMutex = NULL;
3882 void CALEClientSetSendFinishFlag(bool flag)
3884 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3886 ca_mutex_lock(g_SendFinishMutex);
3887 g_isFinishedSendData = flag;
3888 ca_mutex_unlock(g_SendFinishMutex);
3895 CAResult_t CAStartLEGattClient()
3897 // init mutex for send logic
3898 if (!g_deviceDescCond)
3900 g_deviceDescCond = ca_cond_new();
3905 g_threadCond = ca_cond_new();
3908 if (!g_threadWriteCharacteristicCond)
3910 g_threadWriteCharacteristicCond = ca_cond_new();
3913 CAResult_t res = CALEClientStartMulticastServer();
3914 if (CA_STATUS_OK != res)
3916 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3920 g_isStartedLEClient = true;
3926 void CAStopLEGattClient()
3928 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3932 OIC_LOG(ERROR, TAG, "g_jvm is null");
3936 bool isAttached = false;
3938 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3941 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3942 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3946 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3952 CAResult_t ret = CALEClientDisconnectAll(env);
3953 if (CA_STATUS_OK != ret)
3955 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3958 ret = CALEClientStopScan();
3959 if(CA_STATUS_OK != ret)
3961 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3964 ca_mutex_lock(g_threadMutex);
3965 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3966 ca_cond_signal(g_threadCond);
3967 ca_mutex_unlock(g_threadMutex);
3969 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3970 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3971 ca_cond_signal(g_threadWriteCharacteristicCond);
3972 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3974 ca_mutex_lock(g_threadSendMutex);
3975 OIC_LOG(DEBUG, TAG, "signal - send cond");
3976 ca_cond_signal(g_deviceDescCond);
3977 ca_mutex_unlock(g_threadSendMutex);
3979 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3980 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3981 ca_cond_signal(g_deviceScanRetryDelayCond);
3982 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3985 ca_cond_free(g_deviceDescCond);
3986 ca_cond_free(g_threadCond);
3987 ca_cond_free(g_threadWriteCharacteristicCond);
3988 ca_cond_free(g_deviceScanRetryDelayCond);
3990 g_deviceDescCond = NULL;
3991 g_threadCond = NULL;
3992 g_threadWriteCharacteristicCond = NULL;
3993 g_deviceScanRetryDelayCond = NULL;
3997 (*g_jvm)->DetachCurrentThread(g_jvm);
4002 CAResult_t CAInitializeLEGattClient()
4004 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
4005 CALEClientInitialize();
4006 return CA_STATUS_OK;
4009 void CATerminateLEGattClient()
4011 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
4012 CAStopLEGattClient();
4013 CALEClientTerminate();
4016 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
4017 uint32_t dataLen, CALETransferType_t type,
4020 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
4021 VERIFY_NON_NULL(data, TAG, "data is null");
4022 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
4024 if (LE_UNICAST != type || position < 0)
4026 OIC_LOG(ERROR, TAG, "this request is not unicast");
4027 return CA_STATUS_INVALID_PARAM;
4030 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
4033 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
4035 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
4036 VERIFY_NON_NULL(data, TAG, "data is null");
4038 return CALEClientSendMulticastMessage(data, dataLen);
4041 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
4043 ca_mutex_lock(g_bleReqRespClientCbMutex);
4044 g_CABLEClientDataReceivedCallback = callback;
4045 ca_mutex_unlock(g_bleReqRespClientCbMutex);
4048 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
4050 g_threadPoolHandle = handle;
4053 CAResult_t CAGetLEAddress(char **local_address)
4055 VERIFY_NON_NULL(local_address, TAG, "local_address");
4056 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
4057 return CA_NOT_SUPPORTED;
4060 JNIEXPORT void JNICALL
4061 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
4064 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
4065 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4066 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4067 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4069 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4072 JNIEXPORT void JNICALL
4073 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4076 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4077 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4078 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4079 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4081 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4084 JNIEXPORT void JNICALL
4085 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4088 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4089 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4090 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4092 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4093 if (CA_STATUS_OK != res)
4095 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4099 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4101 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4103 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4104 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4106 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4107 if (!jni_cid_gattdevice_list)
4109 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4113 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4114 METHODID_BT_DEVICE);
4115 if (!jni_mid_getDevice)
4117 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4121 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4122 if (!jni_obj_device)
4124 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4128 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4131 OIC_LOG(ERROR, TAG, "jni_address is null");
4135 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4140 * Class: org_iotivity_ca_jar_caleinterface
4141 * Method: CALeGattConnectionStateChangeCallback
4142 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4144 JNIEXPORT void JNICALL
4145 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4151 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4153 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4154 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4155 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4157 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4158 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4159 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4161 if (gatt_success == status && state_connected == newstate) // le connected
4163 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4169 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4172 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4173 STATE_CHARACTER_NO_CHANGE,
4175 if (CA_STATUS_OK != res)
4177 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4178 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4181 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4183 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4186 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4187 if (CA_STATUS_OK != res)
4189 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4193 res = CALEClientDiscoverServices(env, gatt);
4194 if (CA_STATUS_OK != res)
4196 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4200 else if (state_disconnected == newstate) // le disconnected
4202 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4205 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4209 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4212 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4213 STATE_CHARACTER_UNSET,
4215 if (CA_STATUS_OK != res)
4217 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4218 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4221 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4223 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4226 CAResult_t res = CALEClientGattClose(env, gatt);
4227 if (CA_STATUS_OK != res)
4229 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4232 if (gatt_success == status)
4234 // that state is a general reason to disconnect BLE.
4235 // its means manual disconnected message from BT platform.
4236 // in this case Scanning has to start again and clean previous data.
4237 CAResult_t res = CALEClientStartScan();
4238 if (CA_STATUS_OK != res)
4240 if (CA_ADAPTER_NOT_ENABLED == res)
4242 // scan will be started with start server when adapter is enabled
4243 OIC_LOG(INFO, TAG, "Adapter was disabled");
4247 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4252 else if (GATT_ERROR == status)
4254 // when we get GATT ERROR(0x85), gatt connection can be called again.
4255 OIC_LOG(INFO, TAG, "retry gatt connect");
4257 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4260 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4264 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4267 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4271 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4274 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4282 if (CALECheckConnectionStateValue(status))
4284 // this state is unexpected reason to disconnect
4285 // if the reason is suitable, connection logic of the device will be destroyed.
4286 OIC_LOG(INFO, TAG, "connection logic destroy");
4291 // other reason is expected to running background connection in BT platform.
4292 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4293 CALEClientUpdateSendCnt(env);
4300 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4301 g_sendBuffer = NULL;
4309 CALEClientSendFinish(env, gatt);
4314 * Class: org_iotivity_ca_jar_caleinterface
4315 * Method: CALeGattServicesDiscoveredCallback
4316 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4318 JNIEXPORT void JNICALL
4319 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4324 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4325 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4326 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4327 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4329 if (0 != status) // discovery error
4331 CALEClientSendFinish(env, gatt);
4335 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4338 CALEClientSendFinish(env, gatt);
4342 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4345 CALEClientSendFinish(env, gatt);
4349 if (!CALEClientIsSetCharacteristic(address))
4351 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4354 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4358 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4359 if (!jni_obj_GattCharacteristic)
4361 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4365 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4366 jni_obj_GattCharacteristic);
4367 if (CA_STATUS_OK != res)
4369 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4373 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4374 if (CA_STATUS_OK != res)
4376 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4379 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4380 if (CA_STATUS_OK != res)
4382 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4388 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4390 if (CA_STATUS_OK != res)
4392 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4400 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4401 if (CA_STATUS_OK != res)
4403 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4408 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4409 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4414 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4415 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4416 CALEClientSendFinish(env, gatt);
4421 * Class: org_iotivity_ca_jar_caleinterface
4422 * Method: CALeGattCharacteristicWritjclasseCallback
4423 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4425 JNIEXPORT void JNICALL
4426 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4427 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4430 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4431 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4432 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4433 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4435 // send success & signal
4436 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4442 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4448 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4449 if (gatt_success != status) // error case
4451 OIC_LOG(ERROR, TAG, "send failure");
4454 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4455 if (CA_STATUS_OK != res)
4457 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4458 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4459 g_isSignalSetFlag = true;
4460 ca_cond_signal(g_threadWriteCharacteristicCond);
4461 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4463 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4464 STATE_CHARACTER_SET,
4466 if (CA_STATUS_OK != res)
4468 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4471 if (g_clientErrorCallback)
4473 jint length = (*env)->GetArrayLength(env, data);
4474 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4477 CALEClientSendFinish(env, gatt);
4483 OIC_LOG(DEBUG, TAG, "send success");
4484 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4485 STATE_SEND_SUCCESS);
4486 if (CA_STATUS_OK != res)
4488 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4491 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4492 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4493 g_isSignalSetFlag = true;
4494 ca_cond_signal(g_threadWriteCharacteristicCond);
4495 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4497 CALEClientUpdateSendCnt(env);
4500 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4506 CALEClientSendFinish(env, gatt);
4511 * Class: org_iotivity_ca_jar_caleinterface
4512 * Method: CALeGattCharacteristicChangedCallback
4513 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4515 JNIEXPORT void JNICALL
4516 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4517 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4519 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4520 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4521 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4522 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4523 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4525 // get Byte Array and convert to uint8_t*
4526 jint length = (*env)->GetArrayLength(env, data);
4529 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4531 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4532 jni_byte_responseData);
4534 uint8_t* receivedData = OICMalloc(length);
4537 OIC_LOG(ERROR, TAG, "receivedData is null");
4541 memcpy(receivedData, jni_byte_responseData, length);
4542 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4544 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4547 OIC_LOG(ERROR, TAG, "jni_address is null");
4548 OICFree(receivedData);
4552 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4555 OIC_LOG(ERROR, TAG, "address is null");
4556 OICFree(receivedData);
4560 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4561 receivedData, length);
4563 ca_mutex_lock(g_bleServerBDAddressMutex);
4564 uint32_t sentLength = 0;
4565 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4567 ca_mutex_unlock(g_bleServerBDAddressMutex);
4569 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4573 * Class: org_iotivity_ca_jar_caleinterface
4574 * Method: CALeGattDescriptorWriteCallback
4575 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4577 JNIEXPORT void JNICALL
4578 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4582 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4583 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4584 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4585 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4587 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4588 if (gatt_success != status) // error
4595 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4596 if (CA_STATUS_OK != res)
4598 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4607 CALEClientSendFinish(env, gatt);