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_scanMutex = NULL;
97 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
100 * check if retry logic for connection routine has to be stopped or not.
101 * in case of error value including this method, connection routine has to be stopped.
102 * since there is no retry logic for this error reason in this client.
103 * @param state constant value of bluetoothgatt.
104 * @return true - waiting for background connection in BT platform.
105 * false - connection routine has to be stopped.
107 static bool CALECheckConnectionStateValue(jint state)
111 case GATT_CONNECTION_PRIORITY_BALANCED:
113 case GATT_INSUFFICIENT_AUTHENTICATION:
114 case GATT_INSUFFICIENT_ENCRYPTION:
115 case GATT_INVALID_ATTRIBUTE_LENGTH:
116 case GATT_INVALID_OFFSET:
117 case GATT_READ_NOT_PERMITTED:
118 case GATT_REQUEST_NOT_SUPPORTED:
119 case GATT_WRITE_NOT_PERMITTED:
126 void CALEClientJniInit()
128 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
129 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
132 void CALEClientJNISetContext()
134 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
135 g_context = (jobject) CANativeJNIGetContext();
138 CAResult_t CALECreateJniInterfaceObject()
140 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
144 OIC_LOG(ERROR, TAG, "g_context is null");
145 return CA_STATUS_FAILED;
150 OIC_LOG(ERROR, TAG, "g_jvm is null");
151 return CA_STATUS_FAILED;
154 bool isAttached = false;
156 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
159 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
160 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
164 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
165 return CA_STATUS_FAILED;
170 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
171 if (!jni_LEInterface)
173 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
177 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
178 "(Landroid/content/Context;)V");
179 if (!LeInterfaceConstructorMethod)
181 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
185 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
186 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
190 (*g_jvm)->DetachCurrentThread(g_jvm);
199 (*g_jvm)->DetachCurrentThread(g_jvm);
202 return CA_STATUS_FAILED;
205 CAResult_t CALEClientInitialize()
207 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
213 OIC_LOG(ERROR, TAG, "g_jvm is null");
214 return CA_STATUS_FAILED;
217 bool isAttached = false;
219 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
222 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
223 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
227 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
228 return CA_STATUS_FAILED;
233 CAResult_t ret = CALECheckPlatformVersion(env, 18);
234 if (CA_STATUS_OK != ret)
236 OIC_LOG(ERROR, TAG, "it is not supported");
240 (*g_jvm)->DetachCurrentThread(g_jvm);
246 ret = CALEClientInitGattMutexVaraibles();
247 if (CA_STATUS_OK != ret)
249 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
250 CALEClientTerminateGattMutexVariables();
254 (*g_jvm)->DetachCurrentThread(g_jvm);
260 g_deviceDescCond = ca_cond_new();
262 // init mutex for send logic
263 g_threadCond = ca_cond_new();
264 g_threadWriteCharacteristicCond = ca_cond_new();
266 CALEClientCreateDeviceList();
267 CALEClientJNISetContext();
269 ret = CALEClientCreateUUIDList();
270 if (CA_STATUS_OK != ret)
272 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
276 (*g_jvm)->DetachCurrentThread(g_jvm);
282 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
283 if (CA_STATUS_OK != ret)
285 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
289 (*g_jvm)->DetachCurrentThread(g_jvm);
294 g_isStartedLEClient = true;
298 (*g_jvm)->DetachCurrentThread(g_jvm);
304 void CALEClientTerminate()
306 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
310 OIC_LOG(ERROR, TAG, "g_jvm is null");
314 bool isAttached = false;
316 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
319 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
320 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
324 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
330 if (g_leScanCallback)
332 (*env)->DeleteGlobalRef(env, g_leScanCallback);
335 if (g_leGattCallback)
337 (*env)->DeleteGlobalRef(env, g_leGattCallback);
342 (*env)->DeleteGlobalRef(env, g_sendBuffer);
347 (*env)->DeleteGlobalRef(env, g_uuidList);
350 CAResult_t ret = CALEClientRemoveAllDeviceState();
351 if (CA_STATUS_OK != ret)
353 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
356 ret = CALEClientRemoveAllScanDevices(env);
357 if (CA_STATUS_OK != ret)
359 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
362 ret = CALEClientRemoveAllGattObjs(env);
363 if (CA_STATUS_OK != ret)
365 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
368 g_isStartedMulticastServer = false;
369 CALEClientSetScanFlag(false);
370 CALEClientSetSendFinishFlag(false);
372 CALEClientTerminateGattMutexVariables();
373 CALEClientDestroyJniInterface();
375 ca_cond_free(g_deviceDescCond);
376 ca_cond_free(g_threadCond);
377 ca_cond_free(g_threadWriteCharacteristicCond);
379 g_deviceDescCond = NULL;
381 g_threadWriteCharacteristicCond = NULL;
382 g_isSignalSetFlag = false;
386 (*g_jvm)->DetachCurrentThread(g_jvm);
390 CAResult_t CALEClientDestroyJniInterface()
392 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
396 OIC_LOG(ERROR, TAG, "g_jvm is null");
397 return CA_STATUS_FAILED;
400 bool isAttached = false;
402 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
405 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
406 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
410 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
411 return CA_STATUS_FAILED;
416 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
417 if (!jni_LeInterface)
419 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
423 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
424 "destroyLeInterface",
426 if (!jni_InterfaceDestroyMethod)
428 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
432 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
434 if ((*env)->ExceptionCheck(env))
436 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
437 (*env)->ExceptionDescribe(env);
438 (*env)->ExceptionClear(env);
442 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
446 (*g_jvm)->DetachCurrentThread(g_jvm);
455 (*g_jvm)->DetachCurrentThread(g_jvm);
458 return CA_STATUS_FAILED;
461 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
463 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
464 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
468 CAResult_t res = CALEClientDisconnect(env, gatt);
469 if (CA_STATUS_OK != res)
471 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
474 CALEClientUpdateSendCnt(env);
477 CAResult_t CALEClientSendUnicastMessage(const char* address,
479 const uint32_t dataLen)
481 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
482 VERIFY_NON_NULL(address, TAG, "address is null");
483 VERIFY_NON_NULL(data, TAG, "data is null");
485 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
488 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
489 const uint32_t dataLen)
491 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
492 VERIFY_NON_NULL(data, TAG, "data is null");
496 OIC_LOG(ERROR, TAG, "g_jvm is null");
497 return CA_STATUS_FAILED;
500 bool isAttached = false;
502 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
505 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
506 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
510 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
511 return CA_STATUS_FAILED;
516 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
517 if (CA_STATUS_OK != ret)
519 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
524 (*g_jvm)->DetachCurrentThread(g_jvm);
530 CAResult_t CALEClientStartUnicastServer(const char* address)
532 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
534 return CA_NOT_SUPPORTED;
537 CAResult_t CALEClientStartMulticastServer()
539 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
541 if (g_isStartedMulticastServer)
543 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
544 return CA_STATUS_FAILED;
549 OIC_LOG(ERROR, TAG, "g_jvm is null");
550 return CA_STATUS_FAILED;
553 bool isAttached = false;
555 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
558 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
559 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
563 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
564 return CA_STATUS_FAILED;
569 g_isStartedMulticastServer = true;
570 CAResult_t ret = CALEClientStartScan();
571 if (CA_STATUS_OK != ret)
573 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
578 (*g_jvm)->DetachCurrentThread(g_jvm);
584 void CALEClientStopUnicastServer()
586 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
589 void CALEClientStopMulticastServer()
591 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
592 g_isStartedMulticastServer = false;
593 CAResult_t res = CALEClientStopScan();
594 if (CA_STATUS_OK != res)
596 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
601 void CALEClientSetCallback(CAPacketReceiveCallback callback)
603 g_packetReceiveCallback = callback;
606 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
608 g_clientErrorCallback = callback;
611 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
613 VERIFY_NON_NULL(env, TAG, "env");
617 return CA_STATUS_FAILED;
620 if (0 == u_arraylist_length(g_deviceList) // multicast
621 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
623 // Wait for LE peripherals to be discovered.
625 // Number of times to wait for discovery to complete.
626 static size_t const RETRIES = 5;
628 static uint64_t const TIMEOUT =
629 2 * MICROSECS_PER_SEC; // Microseconds
631 bool devicesDiscovered = false;
632 for (size_t i = 0; i < RETRIES; ++i)
634 OIC_LOG(DEBUG, TAG, "waiting for target device");
635 if (ca_cond_wait_for(g_deviceDescCond,
637 TIMEOUT) == CA_WAIT_SUCCESS)
639 ca_mutex_lock(g_deviceListMutex);
640 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
641 ca_mutex_unlock(g_deviceListMutex);
643 if (0 < scannedDeviceLen)
645 if (!address // multicast
646 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
648 devicesDiscovered = true;
655 // time out for scanning devices
656 if (!devicesDiscovered)
658 return CA_STATUS_FAILED;
666 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
667 const uint32_t dataLen)
669 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
671 VERIFY_NON_NULL(address, TAG, "address is null");
672 VERIFY_NON_NULL(data, TAG, "data is null");
676 OIC_LOG(ERROR, TAG, "g_jvm is null");
677 return CA_STATUS_FAILED;
680 bool isAttached = false;
682 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
685 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
686 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
689 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
690 return CA_STATUS_FAILED;
695 ca_mutex_lock(g_threadSendMutex);
697 CALEClientSetSendFinishFlag(false);
699 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
700 if (CA_STATUS_OK != ret)
702 OIC_LOG(INFO, TAG, "there is no scanned device");
706 if (g_context && g_deviceList)
708 uint32_t length = u_arraylist_length(g_deviceList);
709 for (uint32_t index = 0; index < length; index++)
711 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
714 OIC_LOG(ERROR, TAG, "jarrayObj is null");
718 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
721 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
725 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
728 OIC_LOG(ERROR, TAG, "setAddress is null");
732 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
734 if (!strcmp(setAddress, address))
736 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
738 // connect to gatt server
739 ret = CALEClientStopScan();
740 if (CA_STATUS_OK != ret)
742 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
748 (*env)->DeleteGlobalRef(env, g_sendBuffer);
751 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
752 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
753 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
755 // Target device to send message is just one.
758 ret = CALEClientSendData(env, jarrayObj);
759 if (CA_STATUS_OK != ret)
761 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
765 OIC_LOG(INFO, TAG, "wake up");
768 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
772 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
774 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
775 // if there is no connection state.
776 ca_mutex_lock(g_threadMutex);
777 if (!g_isFinishedSendData)
779 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
780 ca_cond_wait(g_threadCond, g_threadMutex);
781 OIC_LOG(DEBUG, TAG, "the data was sent");
783 ca_mutex_unlock(g_threadMutex);
787 (*g_jvm)->DetachCurrentThread(g_jvm);
790 // start LE Scan again
791 ret = CALEClientStartScan();
792 if (CA_STATUS_OK != ret)
794 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
795 ca_mutex_unlock(g_threadSendMutex);
799 ca_mutex_unlock(g_threadSendMutex);
800 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
801 return CALECheckSendState(address);
806 // start LE Scan again
807 ret = CALEClientStartScan();
808 if (CA_STATUS_OK != ret)
810 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
811 ca_mutex_unlock(g_threadSendMutex);
814 (*g_jvm)->DetachCurrentThread(g_jvm);
821 (*g_jvm)->DetachCurrentThread(g_jvm);
824 if (g_clientErrorCallback)
826 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
828 ca_mutex_unlock(g_threadSendMutex);
829 return CA_SEND_FAILED;
832 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
833 const uint32_t dataLen)
835 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
836 VERIFY_NON_NULL(data, TAG, "data is null");
837 VERIFY_NON_NULL(env, TAG, "env is null");
841 OIC_LOG(ERROR, TAG, "g_deviceList is null");
842 return CA_STATUS_FAILED;
845 ca_mutex_lock(g_threadSendMutex);
847 CALEClientSetSendFinishFlag(false);
849 OIC_LOG(DEBUG, TAG, "set byteArray for data");
852 (*env)->DeleteGlobalRef(env, g_sendBuffer);
856 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
857 if (CA_STATUS_OK != res)
859 OIC_LOG(INFO, TAG, "there is no scanned device");
863 // connect to gatt server
864 res = CALEClientStopScan();
865 if (CA_STATUS_OK != res)
867 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
868 ca_mutex_unlock(g_threadSendMutex);
871 uint32_t length = u_arraylist_length(g_deviceList);
872 g_targetCnt = length;
874 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
875 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
876 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
878 for (uint32_t index = 0; index < length; index++)
880 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
883 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
887 res = CALEClientSendData(env, jarrayObj);
888 if (res != CA_STATUS_OK)
890 OIC_LOG(ERROR, TAG, "BT device - send has failed");
893 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
896 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
900 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
903 OIC_LOG(ERROR, TAG, "address is not available");
907 (*env)->ReleaseStringUTFChars(env, jni_address, address);
910 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
912 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
913 ca_mutex_lock(g_threadMutex);
914 if (!g_isFinishedSendData)
916 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
917 ca_cond_wait(g_threadCond, g_threadMutex);
918 OIC_LOG(DEBUG, TAG, "the data was sent");
920 ca_mutex_unlock(g_threadMutex);
922 // start LE Scan again
923 res = CALEClientStartScan();
924 if (CA_STATUS_OK != res)
926 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
927 ca_mutex_unlock(g_threadSendMutex);
931 ca_mutex_unlock(g_threadSendMutex);
932 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
936 res = CALEClientStartScan();
937 if (CA_STATUS_OK != res)
939 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
940 ca_mutex_unlock(g_threadSendMutex);
944 ca_mutex_unlock(g_threadSendMutex);
945 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
946 return CA_SEND_FAILED;
949 CAResult_t CALECheckSendState(const char* address)
951 VERIFY_NON_NULL(address, TAG, "address is null");
953 ca_mutex_lock(g_deviceStateListMutex);
954 CALEState_t* state = CALEClientGetStateInfo(address);
957 OIC_LOG(ERROR, TAG, "state is null");
958 ca_mutex_unlock(g_deviceStateListMutex);
959 return CA_SEND_FAILED;
962 if (STATE_SEND_SUCCESS != state->sendState)
964 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
965 ca_mutex_unlock(g_deviceStateListMutex);
966 return CA_SEND_FAILED;
969 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
970 ca_mutex_unlock(g_deviceStateListMutex);
974 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
976 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
977 VERIFY_NON_NULL(device, TAG, "device is null");
978 VERIFY_NON_NULL(env, TAG, "env is null");
980 // get BLE address from bluetooth device object.
981 char* address = NULL;
982 CALEState_t* state = NULL;
983 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
986 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
987 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
990 OIC_LOG(ERROR, TAG, "address is not available");
991 return CA_STATUS_FAILED;
993 ca_mutex_lock(g_deviceStateListMutex);
994 state = CALEClientGetStateInfo(address);
995 ca_mutex_unlock(g_deviceStateListMutex);
996 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1001 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1003 // cancel previous connection request before connection
1004 // if there is gatt object in g_gattObjectList.
1007 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1010 OIC_LOG(ERROR, TAG, "address is not available");
1011 return CA_STATUS_FAILED;
1014 jobject gatt = CALEClientGetGattObjInList(env, address);
1017 CAResult_t res = CALEClientDisconnect(env, gatt);
1018 if (CA_STATUS_OK != res)
1020 OIC_LOG(INFO, TAG, "there is no gatt object");
1023 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1026 // connection request
1027 jobject newGatt = CALEClientConnect(env, device,
1028 CALEClientGetAutoConnectFlag(env, jni_address));
1029 if (NULL == newGatt)
1031 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1032 return CA_STATUS_FAILED;
1037 if (STATE_CONNECTED == state->connectedState)
1039 OIC_LOG(INFO, TAG, "GATT has already connected");
1042 OIC_LOG(ERROR, TAG, "jni_address is not available");
1043 return CA_STATUS_FAILED;
1046 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1049 OIC_LOG(ERROR, TAG, "address is not available");
1050 return CA_STATUS_FAILED;
1053 jobject gatt = CALEClientGetGattObjInList(env, address);
1056 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1057 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1058 return CA_STATUS_FAILED;
1061 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1062 if (CA_STATUS_OK != ret)
1064 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1065 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1068 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1072 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1074 // cancel previous connection request before connection
1075 // if there is gatt object in g_gattObjectList.
1078 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1081 OIC_LOG(ERROR, TAG, "address is not available");
1082 return CA_STATUS_FAILED;
1085 jobject gatt = CALEClientGetGattObjInList(env, address);
1088 CAResult_t res = CALEClientDisconnect(env, gatt);
1089 if (CA_STATUS_OK != res)
1091 OIC_LOG(INFO, TAG, "there is no gatt object");
1094 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1097 OIC_LOG(DEBUG, TAG, "start to connect LE");
1098 jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
1101 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1102 return CA_STATUS_FAILED;
1107 return CA_STATUS_OK;
1110 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1112 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1113 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1115 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1116 if (!jni_cid_gattdevice_list)
1118 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1122 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1123 "()Landroid/bluetooth/BluetoothDevice;");
1124 if (!jni_mid_getDevice)
1126 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1130 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1131 if (!jni_obj_device)
1133 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1137 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1140 OIC_LOG(ERROR, TAG, "jni_address is null");
1150 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1153 OIC_LOG(DEBUG, TAG, "Gatt Close");
1154 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1155 VERIFY_NON_NULL(env, TAG, "env is null");
1157 // get BluetoothGatt class
1158 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1159 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1160 if (!jni_cid_BluetoothGatt)
1162 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1163 return CA_STATUS_FAILED;
1166 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1167 if (!jni_mid_closeGatt)
1169 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1170 return CA_STATUS_OK;
1173 // call disconnect gatt method
1174 OIC_LOG(DEBUG, TAG, "request to close GATT");
1175 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1177 if ((*env)->ExceptionCheck(env))
1179 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1180 (*env)->ExceptionDescribe(env);
1181 (*env)->ExceptionClear(env);
1182 return CA_STATUS_FAILED;
1185 return CA_STATUS_OK;
1188 CAResult_t CALEClientStartScan()
1190 if (!g_isStartedMulticastServer)
1192 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1193 return CA_STATUS_FAILED;
1196 if (!g_isStartedLEClient)
1198 OIC_LOG(ERROR, TAG, "LE client is not started");
1199 return CA_STATUS_FAILED;
1204 OIC_LOG(ERROR, TAG, "g_jvm is null");
1205 return CA_STATUS_FAILED;
1208 if (g_isStartedScan)
1210 OIC_LOG(INFO, TAG, "scanning is already started");
1211 return CA_STATUS_OK;
1214 bool isAttached = false;
1216 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1219 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1221 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1224 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1225 return CA_STATUS_FAILED;
1230 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1232 CAResult_t ret = CA_STATUS_OK;
1233 // scan gatt server with UUID
1234 if (g_leScanCallback && g_uuidList)
1237 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1239 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1241 if (CA_STATUS_OK != ret)
1243 if (CA_ADAPTER_NOT_ENABLED == ret)
1245 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1249 OIC_LOG(ERROR, TAG, "start scan has failed");
1256 (*g_jvm)->DetachCurrentThread(g_jvm);
1262 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1264 VERIFY_NON_NULL(callback, TAG, "callback is null");
1265 VERIFY_NON_NULL(env, TAG, "env is null");
1267 if (!CALEIsEnableBTAdapter(env))
1269 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1270 return CA_ADAPTER_NOT_ENABLED;
1273 // get default bt adapter class
1274 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1275 if (!jni_cid_BTAdapter)
1277 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1278 return CA_STATUS_FAILED;
1281 // get remote bt adapter method
1282 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1283 "getDefaultAdapter",
1284 METHODID_OBJECTNONPARAM);
1285 if (!jni_mid_getDefaultAdapter)
1287 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1288 return CA_STATUS_FAILED;
1291 // get start le scan method
1292 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1293 "(Landroid/bluetooth/BluetoothAdapter$"
1294 "LeScanCallback;)Z");
1295 if (!jni_mid_startLeScan)
1297 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1298 return CA_STATUS_FAILED;
1301 // gat bt adapter object
1302 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1303 jni_mid_getDefaultAdapter);
1304 if (!jni_obj_BTAdapter)
1306 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1307 return CA_STATUS_FAILED;
1310 // call start le scan method
1311 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1312 jni_mid_startLeScan, callback);
1313 if (!jni_obj_startLeScan)
1315 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1316 return CA_STATUS_FAILED;
1320 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1321 CALEClientSetScanFlag(true);
1324 return CA_STATUS_OK;
1327 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1329 VERIFY_NON_NULL(callback, TAG, "callback is null");
1330 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1331 VERIFY_NON_NULL(env, TAG, "env is null");
1333 if (!CALEIsEnableBTAdapter(env))
1335 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1336 return CA_ADAPTER_NOT_ENABLED;
1339 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1340 if (!jni_cid_BTAdapter)
1342 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1343 return CA_STATUS_FAILED;
1346 // get remote bt adapter method
1347 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1348 "getDefaultAdapter",
1349 METHODID_OBJECTNONPARAM);
1350 if (!jni_mid_getDefaultAdapter)
1352 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1353 return CA_STATUS_FAILED;
1356 // get start le scan method
1357 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1358 "([Ljava/util/UUID;Landroid/bluetooth/"
1359 "BluetoothAdapter$LeScanCallback;)Z");
1360 if (!jni_mid_startLeScan)
1362 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1363 return CA_STATUS_FAILED;
1366 // get bt adapter object
1367 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1368 jni_mid_getDefaultAdapter);
1369 if (!jni_obj_BTAdapter)
1371 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1372 return CA_STATUS_FAILED;
1375 // call start le scan method
1376 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1377 jni_mid_startLeScan, uuids, callback);
1378 if (!jni_obj_startLeScan)
1380 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1381 return CA_STATUS_FAILED;
1385 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1386 CALEClientSetScanFlag(true);
1389 return CA_STATUS_OK;
1392 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1394 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1395 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1398 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1401 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1405 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1406 "(Ljava/lang/String;)"
1407 "Ljava/util/UUID;");
1408 if (!jni_mid_fromString)
1410 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1414 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1415 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1419 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1423 return jni_obj_uuid;
1426 CAResult_t CALEClientStopScan()
1430 OIC_LOG(ERROR, TAG, "g_jvm is null");
1431 return CA_STATUS_FAILED;
1434 if (!g_isStartedScan)
1436 OIC_LOG(INFO, TAG, "scanning is already stopped");
1437 return CA_STATUS_OK;
1440 bool isAttached = false;
1442 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1445 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1446 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1449 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1450 return CA_STATUS_FAILED;
1455 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1456 if (CA_STATUS_OK != ret)
1458 if (CA_ADAPTER_NOT_ENABLED == ret)
1460 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1464 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1469 CALEClientSetScanFlag(false);
1474 (*g_jvm)->DetachCurrentThread(g_jvm);
1480 void CALEClientSetScanFlag(bool flag)
1482 ca_mutex_lock(g_scanMutex);
1483 g_isStartedScan = flag;
1484 ca_mutex_unlock(g_scanMutex);
1487 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1489 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1490 VERIFY_NON_NULL(callback, TAG, "callback is null");
1491 VERIFY_NON_NULL(env, TAG, "env is null");
1493 if (!CALEIsEnableBTAdapter(env))
1495 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1496 return CA_ADAPTER_NOT_ENABLED;
1499 // get default bt adapter class
1500 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1501 if (!jni_cid_BTAdapter)
1503 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1504 return CA_STATUS_FAILED;
1507 // get remote bt adapter method
1508 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1509 "getDefaultAdapter",
1510 METHODID_OBJECTNONPARAM);
1511 if (!jni_mid_getDefaultAdapter)
1513 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1514 return CA_STATUS_FAILED;
1517 // get start le scan method
1518 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1519 "(Landroid/bluetooth/"
1520 "BluetoothAdapter$LeScanCallback;)V");
1521 if (!jni_mid_stopLeScan)
1523 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1524 return CA_STATUS_FAILED;
1527 // gat bt adapter object
1528 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1529 jni_mid_getDefaultAdapter);
1530 if (!jni_obj_BTAdapter)
1532 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1533 return CA_STATUS_FAILED;
1536 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1537 // call start le scan method
1538 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1539 if ((*env)->ExceptionCheck(env))
1541 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1542 (*env)->ExceptionDescribe(env);
1543 (*env)->ExceptionClear(env);
1544 return CA_STATUS_FAILED;
1547 return CA_STATUS_OK;
1550 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1552 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1553 VERIFY_NON_NULL(env, TAG, "env");
1554 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1556 ca_mutex_lock(g_deviceStateListMutex);
1558 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1561 OIC_LOG(ERROR, TAG, "address is not available");
1562 return CA_STATUS_FAILED;
1565 if (CALEClientIsDeviceInList(address))
1567 CALEState_t* curState = CALEClientGetStateInfo(address);
1570 OIC_LOG(ERROR, TAG, "curState is null");
1571 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1572 ca_mutex_unlock(g_deviceStateListMutex);
1573 return CA_STATUS_FAILED;
1575 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1577 curState->autoConnectFlag = flag;
1580 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1581 ca_mutex_unlock(g_deviceStateListMutex);
1582 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1583 return CA_STATUS_OK;
1586 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1588 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1589 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1590 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1592 ca_mutex_lock(g_deviceStateListMutex);
1594 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1597 OIC_LOG(ERROR, TAG, "address is not available");
1601 CALEState_t* curState = CALEClientGetStateInfo(address);
1604 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1605 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1606 ca_mutex_unlock(g_deviceStateListMutex);
1609 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1611 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1612 ca_mutex_unlock(g_deviceStateListMutex);
1614 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1615 return curState->autoConnectFlag;
1618 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1620 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1621 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1622 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1624 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1625 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1628 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1631 OIC_LOG(ERROR, TAG, "address is not available");
1635 // close the gatt service
1636 jobject gatt = CALEClientGetGattObjInList(env, address);
1639 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1640 if (CA_STATUS_OK != res)
1642 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1643 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1647 // clean previous gatt object after close profile service
1648 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1649 if (CA_STATUS_OK != res)
1651 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1652 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1656 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1659 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1662 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1666 // add new gatt object into g_gattObjectList
1667 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1668 if (CA_STATUS_OK != res)
1670 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1677 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1679 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1680 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1681 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1683 if (!CALEIsEnableBTAdapter(env))
1685 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1689 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1692 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1696 // get BluetoothDevice class
1697 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1698 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1699 if (!jni_cid_BluetoothDevice)
1701 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1705 // get connectGatt method
1706 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1707 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1708 "(Landroid/content/Context;ZLandroid/"
1709 "bluetooth/BluetoothGattCallback;)"
1710 "Landroid/bluetooth/BluetoothGatt;");
1711 if (!jni_mid_connectGatt)
1713 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1717 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1718 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1719 jni_mid_connectGatt,
1721 autoconnect, g_leGattCallback);
1722 if (!jni_obj_connectGatt)
1724 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1725 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1726 CALEClientUpdateSendCnt(env);
1731 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1733 return jni_obj_connectGatt;
1736 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1738 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1740 VERIFY_NON_NULL(env, TAG, "env is null");
1741 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1743 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1744 if (!jni_cid_BTAdapter)
1746 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1747 return CA_STATUS_FAILED;
1750 // get remote bt adapter method
1751 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1752 "getDefaultAdapter",
1753 METHODID_OBJECTNONPARAM);
1754 if (!jni_mid_getDefaultAdapter)
1756 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1757 return CA_STATUS_FAILED;
1760 // gat bt adapter object
1761 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1762 jni_mid_getDefaultAdapter);
1763 if (!jni_obj_BTAdapter)
1765 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1766 return CA_STATUS_FAILED;
1769 // get closeProfileProxy method
1770 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1771 "closeProfileProxy",
1772 "(ILandroid/bluetooth/"
1773 "BluetoothProfile;)V");
1774 if (!jni_mid_closeProfileProxy)
1776 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1777 return CA_STATUS_FAILED;
1780 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1781 if (!jni_cid_BTProfile)
1783 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1784 return CA_STATUS_FAILED;
1787 // GATT - Constant value : 7 (0x00000007)
1788 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1792 OIC_LOG(ERROR, TAG, "id_gatt is null");
1793 return CA_STATUS_FAILED;
1796 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1798 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1799 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1800 if ((*env)->ExceptionCheck(env))
1802 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1803 (*env)->ExceptionDescribe(env);
1804 (*env)->ExceptionClear(env);
1805 return CA_STATUS_FAILED;
1808 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1809 return CA_STATUS_OK;
1813 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1815 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1816 VERIFY_NON_NULL(env, TAG, "env is null");
1817 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1819 // get BluetoothGatt class
1820 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1821 if (!jni_cid_BluetoothGatt)
1823 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1824 return CA_STATUS_FAILED;
1827 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1828 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1829 "disconnect", "()V");
1830 if (!jni_mid_disconnectGatt)
1832 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1833 return CA_STATUS_FAILED;
1836 // call disconnect gatt method
1837 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1838 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1839 if ((*env)->ExceptionCheck(env))
1841 OIC_LOG(ERROR, TAG, "disconnect has failed");
1842 (*env)->ExceptionDescribe(env);
1843 (*env)->ExceptionClear(env);
1844 return CA_STATUS_FAILED;
1847 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1849 return CA_STATUS_OK;
1852 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1854 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1855 VERIFY_NON_NULL(env, TAG, "env is null");
1857 if (!g_gattObjectList)
1859 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1860 return CA_STATUS_OK;
1863 uint32_t length = u_arraylist_length(g_gattObjectList);
1864 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1865 for (uint32_t index = 0; index < length; index++)
1867 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1868 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1871 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1874 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1875 if (CA_STATUS_OK != res)
1877 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1882 return CA_STATUS_OK;
1885 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1887 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1888 VERIFY_NON_NULL(env, TAG, "env is null");
1890 if (!g_gattObjectList)
1892 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1893 return CA_STATUS_OK;
1896 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1899 OIC_LOG(ERROR, TAG, "address is null");
1900 return CA_STATUS_FAILED;
1903 uint32_t length = u_arraylist_length(g_gattObjectList);
1904 for (uint32_t index = 0; index < length; index++)
1906 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1909 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1913 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1914 if (!jni_setAddress)
1916 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1917 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1918 return CA_STATUS_FAILED;
1921 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1924 OIC_LOG(ERROR, TAG, "setAddress is null");
1925 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1926 return CA_STATUS_FAILED;
1929 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1930 if (!strcmp(address, setAddress))
1932 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1933 if (CA_STATUS_OK != res)
1935 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1936 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1937 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1938 return CA_STATUS_FAILED;
1940 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1941 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1942 return CA_STATUS_OK;
1944 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1946 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1948 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1949 return CA_STATUS_OK;
1952 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1954 VERIFY_NON_NULL(env, TAG, "env is null");
1955 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1957 if (!CALEIsEnableBTAdapter(env))
1959 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1960 return CA_ADAPTER_NOT_ENABLED;
1963 // get BluetoothGatt class
1964 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1965 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1966 if (!jni_cid_BluetoothGatt)
1968 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1969 return CA_STATUS_FAILED;
1972 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1973 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1974 "discoverServices", "()Z");
1975 if (!jni_mid_discoverServices)
1977 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1978 return CA_STATUS_FAILED;
1980 // call disconnect gatt method
1981 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1982 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1985 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1986 return CA_STATUS_FAILED;
1989 return CA_STATUS_OK;
1992 static void CALEWriteCharacteristicThread(void* object)
1994 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1996 bool isAttached = false;
1998 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2001 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2002 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2006 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2012 jobject gatt = (jobject)object;
2013 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2014 if (CA_STATUS_OK != ret)
2016 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2021 (*g_jvm)->DetachCurrentThread(g_jvm);
2025 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2027 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2028 VERIFY_NON_NULL(env, TAG, "env is null");
2031 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2032 if (!jni_obj_character)
2034 CALEClientSendFinish(env, gatt);
2035 return CA_STATUS_FAILED;
2038 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2039 if (CA_STATUS_OK != ret)
2041 CALEClientSendFinish(env, gatt);
2042 return CA_STATUS_FAILED;
2045 // wait for callback for write Characteristic with success to sent data
2046 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2047 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2048 if (!g_isSignalSetFlag)
2050 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2051 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2052 g_threadWriteCharacteristicMutex,
2053 WAIT_TIME_WRITE_CHARACTERISTIC))
2055 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2056 g_isSignalSetFlag = false;
2057 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2058 return CA_STATUS_FAILED;
2061 // reset flag set by writeCharacteristic Callback
2062 g_isSignalSetFlag = false;
2063 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2065 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2066 return CA_STATUS_OK;
2069 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2071 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2072 VERIFY_NON_NULL(env, TAG, "env is null");
2073 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2075 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2076 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2077 CALEWriteCharacteristicThread, (void*)gattParam))
2079 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2080 return CA_STATUS_FAILED;
2083 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2084 return CA_STATUS_OK;
2087 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2088 jobject gattCharacteristic)
2090 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2091 VERIFY_NON_NULL(env, TAG, "env is null");
2092 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2093 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2095 if (!CALEIsEnableBTAdapter(env))
2097 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2098 return CA_STATUS_FAILED;
2101 // get BluetoothGatt class
2102 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2103 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2104 if (!jni_cid_BluetoothGatt)
2106 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2107 return CA_STATUS_FAILED;
2110 OIC_LOG(DEBUG, TAG, "write characteristic method");
2111 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2112 "writeCharacteristic",
2113 "(Landroid/bluetooth/"
2114 "BluetoothGattCharacteristic;)Z");
2115 if (!jni_mid_writeCharacteristic)
2117 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2118 return CA_STATUS_FAILED;
2121 // call disconnect gatt method
2122 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2123 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2124 jni_mid_writeCharacteristic,
2125 gattCharacteristic);
2128 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2132 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2133 return CA_STATUS_FAILED;
2136 return CA_STATUS_OK;
2139 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2141 VERIFY_NON_NULL(env, TAG, "env is null");
2142 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2144 if (!CALEIsEnableBTAdapter(env))
2146 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2147 return CA_STATUS_FAILED;
2150 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2151 if (!jni_cid_BluetoothGatt)
2153 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2154 return CA_STATUS_FAILED;
2157 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2160 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2161 return CA_STATUS_FAILED;
2164 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2165 if (!jni_obj_GattCharacteristic)
2167 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2168 return CA_STATUS_FAILED;
2171 OIC_LOG(DEBUG, TAG, "read characteristic method");
2172 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2173 "readCharacteristic",
2174 "(Landroid/bluetooth/"
2175 "BluetoothGattCharacteristic;)Z");
2176 if (!jni_mid_readCharacteristic)
2178 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2179 return CA_STATUS_FAILED;
2182 // call disconnect gatt method
2183 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2184 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2185 jni_obj_GattCharacteristic);
2188 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2192 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2193 return CA_STATUS_FAILED;
2196 return CA_STATUS_OK;
2199 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2200 jobject characteristic)
2202 VERIFY_NON_NULL(env, TAG, "env is null");
2203 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2204 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2206 if (!CALEIsEnableBTAdapter(env))
2208 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2209 return CA_ADAPTER_NOT_ENABLED;
2212 // get BluetoothGatt class
2213 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2214 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2215 if (!jni_cid_BluetoothGatt)
2217 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2218 return CA_STATUS_FAILED;
2221 // set Characteristic Notification
2222 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2223 "setCharacteristicNotification",
2224 "(Landroid/bluetooth/"
2225 "BluetoothGattCharacteristic;Z)Z");
2226 if (!jni_mid_setNotification)
2228 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2229 return CA_STATUS_FAILED;
2232 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2233 characteristic, JNI_TRUE);
2234 if (JNI_TRUE == ret)
2236 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2240 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2241 return CA_STATUS_FAILED;
2244 return CA_STATUS_OK;
2247 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2249 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2250 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2251 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2253 if (!CALEIsEnableBTAdapter(env))
2255 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2259 // get BluetoothGatt class
2260 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2261 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2262 if (!jni_cid_BluetoothGatt)
2264 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2268 jmethodID jni_mid_getService = (*env)->GetMethodID(
2269 env, jni_cid_BluetoothGatt, "getService",
2270 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2271 if (!jni_mid_getService)
2273 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2277 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2278 if (!jni_obj_service_uuid)
2280 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2284 // get bluetooth gatt service
2285 OIC_LOG(DEBUG, TAG, "request to get service");
2286 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2287 jni_obj_service_uuid);
2288 if (!jni_obj_gattService)
2290 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2294 // get bluetooth gatt service class
2295 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2296 env, "android/bluetooth/BluetoothGattService");
2297 if (!jni_cid_BluetoothGattService)
2299 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2303 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2304 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2305 "getCharacteristic",
2306 "(Ljava/util/UUID;)"
2307 "Landroid/bluetooth/"
2308 "BluetoothGattCharacteristic;");
2309 if (!jni_mid_getCharacteristic)
2311 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2315 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2318 OIC_LOG(ERROR, TAG, "uuid is null");
2322 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2323 if (!jni_obj_tx_uuid)
2325 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2326 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2330 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2331 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2332 jni_mid_getCharacteristic,
2335 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2336 return jni_obj_GattCharacteristic;
2339 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2341 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2342 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2343 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2344 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2346 if (!CALEIsEnableBTAdapter(env))
2348 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2352 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2355 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2359 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2360 if (!jni_obj_GattCharacteristic)
2362 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2366 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2367 "/BluetoothGattCharacteristic");
2368 if (!jni_cid_BTGattCharacteristic)
2370 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2374 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2375 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2377 if (!jni_mid_setValue)
2379 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2383 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2385 if (JNI_TRUE == ret)
2387 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2391 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2396 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2397 "setWriteType", "(I)V");
2398 if (!jni_mid_setWriteType)
2400 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2404 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2405 "WRITE_TYPE_NO_RESPONSE", "I");
2406 if (!jni_fid_no_response)
2408 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2412 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2413 jni_fid_no_response);
2415 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2417 return jni_obj_GattCharacteristic;
2420 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2422 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2423 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2425 if (!CALEIsEnableBTAdapter(env))
2427 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2431 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2432 "BluetoothGattCharacteristic");
2433 if (!jni_cid_BTGattCharacteristic)
2435 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2439 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2440 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2442 if (!jni_mid_getValue)
2444 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2448 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2450 return jni_obj_data_array;
2453 CAResult_t CALEClientCreateUUIDList()
2457 OIC_LOG(ERROR, TAG, "g_jvm is null");
2458 return CA_STATUS_FAILED;
2461 bool isAttached = false;
2463 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2466 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2467 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2471 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2472 return CA_STATUS_FAILED;
2477 // create new object array
2478 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2479 if (!jni_cid_uuid_list)
2481 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2485 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2486 jni_cid_uuid_list, NULL);
2487 if (!jni_obj_uuid_list)
2489 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2494 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2497 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2500 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2502 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2506 (*g_jvm)->DetachCurrentThread(g_jvm);
2509 return CA_STATUS_OK;
2516 (*g_jvm)->DetachCurrentThread(g_jvm);
2518 return CA_STATUS_FAILED;
2521 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2522 jobject characteristic)
2524 VERIFY_NON_NULL(env, TAG, "env is null");
2525 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2526 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2528 if (!CALEIsEnableBTAdapter(env))
2530 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2531 return CA_ADAPTER_NOT_ENABLED;
2534 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2535 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2536 "BluetoothGattCharacteristic");
2537 if (!jni_cid_BTGattCharacteristic)
2539 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2540 return CA_STATUS_FAILED;
2543 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2544 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2546 "(Ljava/util/UUID;)Landroid/bluetooth/"
2547 "BluetoothGattDescriptor;");
2548 if (!jni_mid_getDescriptor)
2550 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2551 return CA_STATUS_FAILED;
2554 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2555 if (!jni_obj_cc_uuid)
2557 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2558 return CA_STATUS_FAILED;
2561 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2562 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2563 jni_mid_getDescriptor, jni_obj_cc_uuid);
2564 if (!jni_obj_descriptor)
2566 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2567 return CA_NOT_SUPPORTED;
2570 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2571 jclass jni_cid_descriptor = (*env)->FindClass(env,
2572 "android/bluetooth/BluetoothGattDescriptor");
2573 if (!jni_cid_descriptor)
2575 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2576 return CA_STATUS_FAILED;
2579 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2580 if (!jni_mid_setValue)
2582 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2583 return CA_STATUS_FAILED;
2586 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2587 "ENABLE_NOTIFICATION_VALUE", "[B");
2588 if (!jni_fid_NotiValue)
2590 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2591 return CA_STATUS_FAILED;
2594 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2596 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2597 env, jni_obj_descriptor, jni_mid_setValue,
2598 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2601 OIC_LOG(DEBUG, TAG, "setValue success");
2605 OIC_LOG(ERROR, TAG, "setValue has failed");
2606 return CA_STATUS_FAILED;
2609 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2612 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2613 return CA_STATUS_FAILED;
2616 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2617 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2618 "(Landroid/bluetooth/"
2619 "BluetoothGattDescriptor;)Z");
2620 if (!jni_mid_writeDescriptor)
2622 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2623 return CA_STATUS_FAILED;
2626 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2627 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2628 jni_obj_descriptor);
2631 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2635 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2636 return CA_STATUS_FAILED;
2639 return CA_STATUS_OK;
2642 void CALEClientCreateScanDeviceList(JNIEnv *env)
2644 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2645 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2647 ca_mutex_lock(g_deviceListMutex);
2648 // create new object array
2649 if (g_deviceList == NULL)
2651 OIC_LOG(DEBUG, TAG, "Create device list");
2653 g_deviceList = u_arraylist_create();
2655 ca_mutex_unlock(g_deviceListMutex);
2658 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2660 VERIFY_NON_NULL(device, TAG, "device is null");
2661 VERIFY_NON_NULL(env, TAG, "env is null");
2663 ca_mutex_lock(g_deviceListMutex);
2667 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2668 ca_mutex_unlock(g_deviceListMutex);
2669 return CA_STATUS_FAILED;
2672 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2673 if (!jni_remoteAddress)
2675 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2676 ca_mutex_unlock(g_deviceListMutex);
2677 return CA_STATUS_FAILED;
2680 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2683 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2684 ca_mutex_unlock(g_deviceListMutex);
2685 return CA_STATUS_FAILED;
2688 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2690 jobject gdevice = (*env)->NewGlobalRef(env, device);
2691 u_arraylist_add(g_deviceList, gdevice);
2692 ca_cond_signal(g_deviceDescCond);
2693 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2695 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2697 ca_mutex_unlock(g_deviceListMutex);
2699 return CA_STATUS_OK;
2702 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2704 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2705 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2709 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2713 uint32_t length = u_arraylist_length(g_deviceList);
2714 for (uint32_t index = 0; index < length; index++)
2716 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2719 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2723 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2724 if (!jni_setAddress)
2726 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2730 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2733 OIC_LOG(ERROR, TAG, "setAddress is null");
2737 if (!strcmp(remoteAddress, setAddress))
2739 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2743 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2746 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2751 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2753 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2754 VERIFY_NON_NULL(env, TAG, "env is null");
2756 ca_mutex_lock(g_deviceListMutex);
2760 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2761 ca_mutex_unlock(g_deviceListMutex);
2762 return CA_STATUS_FAILED;
2765 uint32_t length = u_arraylist_length(g_deviceList);
2766 for (uint32_t index = 0; index < length; index++)
2768 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2771 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2774 (*env)->DeleteGlobalRef(env, jarrayObj);
2777 OICFree(g_deviceList);
2778 g_deviceList = NULL;
2780 ca_mutex_unlock(g_deviceListMutex);
2781 return CA_STATUS_OK;
2784 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2786 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2787 VERIFY_NON_NULL(address, TAG, "address is null");
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");
2806 ca_mutex_unlock(g_deviceListMutex);
2807 return CA_STATUS_FAILED;
2810 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2811 if (!jni_setAddress)
2813 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2814 ca_mutex_unlock(g_deviceListMutex);
2815 return CA_STATUS_FAILED;
2818 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2821 OIC_LOG(ERROR, TAG, "setAddress is null");
2822 ca_mutex_unlock(g_deviceListMutex);
2823 return CA_STATUS_FAILED;
2826 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2829 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2830 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2831 ca_mutex_unlock(g_deviceListMutex);
2832 return CA_STATUS_FAILED;
2835 if (!strcmp(setAddress, remoteAddress))
2837 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2838 (*env)->DeleteGlobalRef(env, jarrayObj);
2839 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2840 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2842 if (NULL == u_arraylist_remove(g_deviceList, index))
2844 OIC_LOG(ERROR, TAG, "List removal failed.");
2845 ca_mutex_unlock(g_deviceListMutex);
2846 return CA_STATUS_FAILED;
2848 ca_mutex_unlock(g_deviceListMutex);
2849 return CA_STATUS_OK;
2851 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2852 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2855 ca_mutex_unlock(g_deviceListMutex);
2856 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2858 return CA_STATUS_OK;
2865 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2867 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2868 VERIFY_NON_NULL(env, TAG, "env is null");
2869 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2871 ca_mutex_lock(g_gattObjectMutex);
2873 if (!g_gattObjectList)
2875 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2876 ca_mutex_unlock(g_gattObjectMutex);
2877 return CA_STATUS_FAILED;
2880 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2881 if (!jni_remoteAddress)
2883 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2884 ca_mutex_unlock(g_gattObjectMutex);
2885 return CA_STATUS_FAILED;
2888 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2891 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2892 ca_mutex_unlock(g_gattObjectMutex);
2893 return CA_STATUS_FAILED;
2896 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2897 if (!CALEClientIsGattObjInList(env, remoteAddress))
2899 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2900 u_arraylist_add(g_gattObjectList, newGatt);
2901 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2904 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2905 ca_mutex_unlock(g_gattObjectMutex);
2906 return CA_STATUS_OK;
2909 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2911 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2912 VERIFY_NON_NULL(env, TAG, "env is null");
2913 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2915 uint32_t length = u_arraylist_length(g_gattObjectList);
2916 for (uint32_t index = 0; index < length; index++)
2919 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2922 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2926 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2927 if (!jni_setAddress)
2929 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2933 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2936 OIC_LOG(ERROR, TAG, "setAddress is null");
2940 if (!strcmp(remoteAddress, setAddress))
2942 OIC_LOG(DEBUG, TAG, "the device is already set");
2943 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2948 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2953 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2957 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2959 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2960 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2961 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2963 ca_mutex_lock(g_gattObjectMutex);
2964 uint32_t length = u_arraylist_length(g_gattObjectList);
2965 for (uint32_t index = 0; index < length; index++)
2967 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2970 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2971 ca_mutex_unlock(g_gattObjectMutex);
2975 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2976 if (!jni_setAddress)
2978 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2979 ca_mutex_unlock(g_gattObjectMutex);
2983 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2986 OIC_LOG(ERROR, TAG, "setAddress is null");
2987 ca_mutex_unlock(g_gattObjectMutex);
2991 if (!strcmp(remoteAddress, setAddress))
2993 OIC_LOG(DEBUG, TAG, "the device is already set");
2994 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2995 ca_mutex_unlock(g_gattObjectMutex);
2998 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3001 ca_mutex_unlock(g_gattObjectMutex);
3002 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3006 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3008 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3009 VERIFY_NON_NULL(env, TAG, "env is null");
3011 ca_mutex_lock(g_gattObjectMutex);
3012 if (!g_gattObjectList)
3014 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3015 ca_mutex_unlock(g_gattObjectMutex);
3016 return CA_STATUS_OK;
3019 uint32_t length = u_arraylist_length(g_gattObjectList);
3020 for (uint32_t index = 0; index < length; index++)
3022 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3025 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3028 (*env)->DeleteGlobalRef(env, jarrayObj);
3031 OICFree(g_gattObjectList);
3032 g_gattObjectList = NULL;
3033 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3034 ca_mutex_unlock(g_gattObjectMutex);
3035 return CA_STATUS_OK;
3038 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3040 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3041 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3042 VERIFY_NON_NULL(env, TAG, "env is null");
3044 ca_mutex_lock(g_gattObjectMutex);
3045 if (!g_gattObjectList)
3047 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3048 ca_mutex_unlock(g_gattObjectMutex);
3049 return CA_STATUS_OK;
3052 uint32_t length = u_arraylist_length(g_gattObjectList);
3053 for (uint32_t index = 0; index < length; index++)
3055 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3058 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3059 ca_mutex_unlock(g_gattObjectMutex);
3060 return CA_STATUS_FAILED;
3063 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3064 if (!jni_setAddress)
3066 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3067 ca_mutex_unlock(g_gattObjectMutex);
3068 return CA_STATUS_FAILED;
3071 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3074 OIC_LOG(ERROR, TAG, "setAddress is null");
3075 ca_mutex_unlock(g_gattObjectMutex);
3076 return CA_STATUS_FAILED;
3079 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3080 if (!jni_remoteAddress)
3082 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3083 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3084 ca_mutex_unlock(g_gattObjectMutex);
3085 return CA_STATUS_FAILED;
3088 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3091 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3092 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3093 ca_mutex_unlock(g_gattObjectMutex);
3094 return CA_STATUS_FAILED;
3097 if (!strcmp(setAddress, remoteAddress))
3099 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3100 (*env)->DeleteGlobalRef(env, jarrayObj);
3101 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3102 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3104 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3106 OIC_LOG(ERROR, TAG, "List removal failed.");
3107 ca_mutex_unlock(g_gattObjectMutex);
3108 return CA_STATUS_FAILED;
3110 ca_mutex_unlock(g_gattObjectMutex);
3111 return CA_STATUS_OK;
3113 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3114 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3117 ca_mutex_unlock(g_gattObjectMutex);
3118 OIC_LOG(DEBUG, TAG, "there are no target object");
3119 return CA_STATUS_OK;
3122 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3124 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3125 VERIFY_NON_NULL(addr, TAG, "addr is null");
3126 VERIFY_NON_NULL(env, TAG, "env is null");
3128 ca_mutex_lock(g_gattObjectMutex);
3129 if (!g_gattObjectList)
3131 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3132 ca_mutex_unlock(g_gattObjectMutex);
3133 return CA_STATUS_OK;
3136 uint32_t length = u_arraylist_length(g_gattObjectList);
3137 for (uint32_t index = 0; index < length; index++)
3139 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3142 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3143 ca_mutex_unlock(g_gattObjectMutex);
3144 return CA_STATUS_FAILED;
3147 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3148 if (!jni_setAddress)
3150 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3151 ca_mutex_unlock(g_gattObjectMutex);
3152 return CA_STATUS_FAILED;
3155 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3158 OIC_LOG(ERROR, TAG, "setAddress is null");
3159 ca_mutex_unlock(g_gattObjectMutex);
3160 return CA_STATUS_FAILED;
3163 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3166 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3167 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3168 ca_mutex_unlock(g_gattObjectMutex);
3169 return CA_STATUS_FAILED;
3172 if (!strcmp(setAddress, remoteAddress))
3174 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3175 (*env)->DeleteGlobalRef(env, jarrayObj);
3177 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3178 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3179 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3181 OIC_LOG(ERROR, TAG, "List removal failed.");
3182 ca_mutex_unlock(g_gattObjectMutex);
3183 return CA_STATUS_FAILED;
3185 ca_mutex_unlock(g_gattObjectMutex);
3186 return CA_STATUS_OK;
3188 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3189 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3192 ca_mutex_unlock(g_gattObjectMutex);
3193 OIC_LOG(DEBUG, TAG, "there are no target object");
3194 return CA_STATUS_FAILED;
3197 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3199 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3201 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3202 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3204 // get Bluetooth Address
3205 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3206 if (!jni_btTargetAddress)
3208 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3212 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3215 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3219 // get method ID of getDevice()
3220 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3221 if (!jni_cid_gattdevice_list)
3223 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3224 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3228 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3229 METHODID_BT_DEVICE);
3230 if (!jni_mid_getDevice)
3232 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3233 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3237 size_t length = u_arraylist_length(g_gattObjectList);
3238 for (size_t index = 0; index < length; index++)
3240 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3243 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3244 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3248 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3249 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3250 if (!jni_obj_device)
3252 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3253 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3257 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3260 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3261 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3265 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3268 OIC_LOG(ERROR, TAG, "btAddress is not available");
3269 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3273 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3274 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3275 if (!strcmp(targetAddress, btAddress))
3277 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3280 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3283 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3285 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3286 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3287 (*env)->DeleteLocalRef(env, jni_btAddress);
3288 (*env)->DeleteLocalRef(env, jni_obj_device);
3289 return jni_LEAddress;
3291 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3292 (*env)->DeleteLocalRef(env, jni_btAddress);
3293 (*env)->DeleteLocalRef(env, jni_obj_device);
3296 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3304 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3305 uint16_t notificationState, uint16_t sendState)
3307 VERIFY_NON_NULL(address, TAG, "address is null");
3309 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3312 OIC_LOG(ERROR, TAG, "out of memory");
3313 return CA_MEMORY_ALLOC_FAILED;
3316 if (strlen(address) > CA_MACADDR_SIZE)
3318 OIC_LOG(ERROR, TAG, "address is not proper");
3320 return CA_STATUS_FAILED;
3323 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3324 newstate->connectedState = connectedState;
3325 newstate->notificationState = notificationState;
3326 newstate->sendState = sendState;
3327 return CALEClientAddDeviceStateToList(newstate);
3330 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3332 VERIFY_NON_NULL(state, TAG, "state is null");
3334 ca_mutex_lock(g_deviceStateListMutex);
3336 if (!g_deviceStateList)
3338 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3339 ca_mutex_unlock(g_deviceStateListMutex);
3340 return CA_STATUS_FAILED;
3343 if (CALEClientIsDeviceInList(state->address))
3345 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3348 OIC_LOG(ERROR, TAG, "curState is null");
3349 ca_mutex_unlock(g_deviceStateListMutex);
3350 return CA_STATUS_FAILED;
3353 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3355 state->notificationState = curState->notificationState;
3357 state->autoConnectFlag = curState->autoConnectFlag;
3359 // delete previous state for update new state
3360 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3361 if (CA_STATUS_OK != res)
3363 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3364 ca_mutex_unlock(g_deviceStateListMutex);
3368 u_arraylist_add(g_deviceStateList, state); // update new state
3369 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3370 state->connectedState, state->notificationState, state->address);
3372 ca_mutex_unlock(g_deviceStateListMutex);
3373 return CA_STATUS_OK;
3376 bool CALEClientIsDeviceInList(const char* remoteAddress)
3378 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3380 if (!g_deviceStateList)
3382 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3386 uint32_t length = u_arraylist_length(g_deviceStateList);
3387 for (uint32_t index = 0; index < length; index++)
3389 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3392 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3396 if (!strcmp(remoteAddress, state->address))
3398 OIC_LOG(DEBUG, TAG, "the device is already set");
3407 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3411 CAResult_t CALEClientRemoveAllDeviceState()
3413 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3415 ca_mutex_lock(g_deviceStateListMutex);
3416 if (!g_deviceStateList)
3418 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3419 ca_mutex_unlock(g_deviceStateListMutex);
3420 return CA_STATUS_FAILED;
3423 uint32_t length = u_arraylist_length(g_deviceStateList);
3424 for (uint32_t index = 0; index < length; index++)
3426 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3429 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3435 OICFree(g_deviceStateList);
3436 g_deviceStateList = NULL;
3437 ca_mutex_unlock(g_deviceStateListMutex);
3439 return CA_STATUS_OK;
3442 CAResult_t CALEClientResetDeviceStateForAll()
3444 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3446 ca_mutex_lock(g_deviceStateListMutex);
3447 if (!g_deviceStateList)
3449 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3450 ca_mutex_unlock(g_deviceStateListMutex);
3451 return CA_STATUS_FAILED;
3454 size_t length = u_arraylist_length(g_deviceStateList);
3455 for (size_t index = 0; index < length; index++)
3457 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3460 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3464 // autoConnectFlag value will be not changed,
3465 // since it has reset only termination case.
3466 state->connectedState = STATE_DISCONNECTED;
3467 state->notificationState = STATE_CHARACTER_UNSET;
3468 state->sendState = STATE_SEND_NONE;
3470 ca_mutex_unlock(g_deviceStateListMutex);
3472 return CA_STATUS_OK;
3475 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3477 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3478 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3480 if (!g_deviceStateList)
3482 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3483 return CA_STATUS_FAILED;
3486 uint32_t length = u_arraylist_length(g_deviceStateList);
3487 for (uint32_t index = 0; index < length; index++)
3489 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3492 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3496 if (!strcmp(state->address, remoteAddress))
3498 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3500 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3502 if (NULL == targetState)
3504 OIC_LOG(ERROR, TAG, "List removal failed.");
3505 return CA_STATUS_FAILED;
3508 OICFree(targetState);
3509 return CA_STATUS_OK;
3513 return CA_STATUS_OK;
3516 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3518 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3519 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3521 if (!g_deviceStateList)
3523 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3527 uint32_t length = u_arraylist_length(g_deviceStateList);
3528 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3530 for (uint32_t index = 0; index < length; index++)
3532 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3535 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3539 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3540 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3542 if (!strcmp(state->address, remoteAddress))
3544 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3551 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3553 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3554 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3556 ca_mutex_lock(g_deviceStateListMutex);
3557 if (!g_deviceStateList)
3559 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3560 ca_mutex_unlock(g_deviceStateListMutex);
3564 uint32_t length = u_arraylist_length(g_deviceStateList);
3565 for (uint32_t index = 0; index < length; index++)
3567 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3570 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3574 if (!strcmp(state->address, remoteAddress))
3576 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3578 if (STATE_CONNECTED == state->connectedState)
3580 ca_mutex_unlock(g_deviceStateListMutex);
3585 ca_mutex_unlock(g_deviceStateListMutex);
3590 ca_mutex_unlock(g_deviceStateListMutex);
3594 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3596 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3597 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3599 ca_mutex_lock(g_deviceStateListMutex);
3600 if (!g_deviceStateList)
3602 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3603 ca_mutex_unlock(g_deviceStateListMutex);
3607 uint32_t length = u_arraylist_length(g_deviceStateList);
3608 for (uint32_t index = 0; index < length; index++)
3610 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3613 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3617 if (!strcmp(state->address, remoteAddress))
3619 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3621 if (STATE_CHARACTER_SET == state->notificationState)
3623 ca_mutex_unlock(g_deviceStateListMutex);
3628 ca_mutex_unlock(g_deviceStateListMutex);
3634 ca_mutex_unlock(g_deviceStateListMutex);
3638 void CALEClientCreateDeviceList()
3640 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3642 // create new object array
3643 if (!g_gattObjectList)
3645 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3647 g_gattObjectList = u_arraylist_create();
3650 if (!g_deviceStateList)
3652 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3654 g_deviceStateList = u_arraylist_create();
3659 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3661 g_deviceList = u_arraylist_create();
3666 * Check Sent Count for remove g_sendBuffer
3668 void CALEClientUpdateSendCnt(JNIEnv *env)
3670 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3672 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3674 ca_mutex_lock(g_threadMutex);
3678 if (g_targetCnt <= g_currentSentCnt)
3681 g_currentSentCnt = 0;
3685 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3686 g_sendBuffer = NULL;
3688 // notity the thread
3689 ca_cond_signal(g_threadCond);
3691 CALEClientSetSendFinishFlag(true);
3692 OIC_LOG(DEBUG, TAG, "set signal for send data");
3695 ca_mutex_unlock(g_threadMutex);
3698 CAResult_t CALEClientInitGattMutexVaraibles()
3700 if (NULL == g_bleReqRespClientCbMutex)
3702 g_bleReqRespClientCbMutex = ca_mutex_new();
3703 if (NULL == g_bleReqRespClientCbMutex)
3705 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3706 return CA_STATUS_FAILED;
3710 if (NULL == g_bleServerBDAddressMutex)
3712 g_bleServerBDAddressMutex = ca_mutex_new();
3713 if (NULL == g_bleServerBDAddressMutex)
3715 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3716 return CA_STATUS_FAILED;
3720 if (NULL == g_threadMutex)
3722 g_threadMutex = ca_mutex_new();
3723 if (NULL == g_threadMutex)
3725 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3726 return CA_STATUS_FAILED;
3730 if (NULL == g_threadSendMutex)
3732 g_threadSendMutex = ca_mutex_new();
3733 if (NULL == g_threadSendMutex)
3735 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3736 return CA_STATUS_FAILED;
3740 if (NULL == g_deviceListMutex)
3742 g_deviceListMutex = ca_mutex_new();
3743 if (NULL == g_deviceListMutex)
3745 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3746 return CA_STATUS_FAILED;
3750 if (NULL == g_gattObjectMutex)
3752 g_gattObjectMutex = ca_mutex_new();
3753 if (NULL == g_gattObjectMutex)
3755 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3756 return CA_STATUS_FAILED;
3760 if (NULL == g_deviceStateListMutex)
3762 g_deviceStateListMutex = ca_mutex_new();
3763 if (NULL == g_deviceStateListMutex)
3765 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3766 return CA_STATUS_FAILED;
3770 if (NULL == g_SendFinishMutex)
3772 g_SendFinishMutex = ca_mutex_new();
3773 if (NULL == g_SendFinishMutex)
3775 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3776 return CA_STATUS_FAILED;
3780 if (NULL == g_scanMutex)
3782 g_scanMutex = ca_mutex_new();
3783 if (NULL == g_scanMutex)
3785 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3786 return CA_STATUS_FAILED;
3790 if (NULL == g_threadWriteCharacteristicMutex)
3792 g_threadWriteCharacteristicMutex = ca_mutex_new();
3793 if (NULL == g_threadWriteCharacteristicMutex)
3795 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3796 return CA_STATUS_FAILED;
3800 return CA_STATUS_OK;
3803 void CALEClientTerminateGattMutexVariables()
3805 ca_mutex_free(g_bleReqRespClientCbMutex);
3806 g_bleReqRespClientCbMutex = NULL;
3808 ca_mutex_free(g_bleServerBDAddressMutex);
3809 g_bleServerBDAddressMutex = NULL;
3811 ca_mutex_free(g_threadMutex);
3812 g_threadMutex = NULL;
3814 ca_mutex_free(g_threadSendMutex);
3815 g_threadSendMutex = NULL;
3817 ca_mutex_free(g_deviceListMutex);
3818 g_deviceListMutex = NULL;
3820 ca_mutex_free(g_SendFinishMutex);
3821 g_SendFinishMutex = NULL;
3823 ca_mutex_free(g_scanMutex);
3826 ca_mutex_free(g_threadWriteCharacteristicMutex);
3827 g_threadWriteCharacteristicMutex = NULL;
3830 void CALEClientSetSendFinishFlag(bool flag)
3832 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3834 ca_mutex_lock(g_SendFinishMutex);
3835 g_isFinishedSendData = flag;
3836 ca_mutex_unlock(g_SendFinishMutex);
3843 CAResult_t CAStartLEGattClient()
3845 CAResult_t res = CALEClientStartMulticastServer();
3846 if (CA_STATUS_OK != res)
3848 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3852 g_isStartedLEClient = true;
3858 void CAStopLEGattClient()
3860 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3864 OIC_LOG(ERROR, TAG, "g_jvm is null");
3868 bool isAttached = false;
3870 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3873 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3874 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3878 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3884 CAResult_t ret = CALEClientDisconnectAll(env);
3885 if (CA_STATUS_OK != ret)
3887 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3890 ret = CALEClientStopScan();
3891 if(CA_STATUS_OK != ret)
3893 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3896 ca_mutex_lock(g_threadMutex);
3897 ca_cond_signal(g_threadCond);
3898 ca_mutex_unlock(g_threadMutex);
3900 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3901 ca_cond_signal(g_threadWriteCharacteristicCond);
3902 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3906 (*g_jvm)->DetachCurrentThread(g_jvm);
3911 CAResult_t CAInitializeLEGattClient()
3913 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3914 CALEClientInitialize();
3915 return CA_STATUS_OK;
3918 void CATerminateLEGattClient()
3920 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3921 CAStopLEGattClient();
3922 CALEClientTerminate();
3925 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3926 uint32_t dataLen, CALETransferType_t type,
3929 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3930 VERIFY_NON_NULL(data, TAG, "data is null");
3931 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3933 if (LE_UNICAST != type || position < 0)
3935 OIC_LOG(ERROR, TAG, "this request is not unicast");
3936 return CA_STATUS_INVALID_PARAM;
3939 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3942 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3944 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3945 VERIFY_NON_NULL(data, TAG, "data is null");
3947 return CALEClientSendMulticastMessage(data, dataLen);
3950 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3952 ca_mutex_lock(g_bleReqRespClientCbMutex);
3953 g_CABLEClientDataReceivedCallback = callback;
3954 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3957 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3959 g_threadPoolHandle = handle;
3962 CAResult_t CAGetLEAddress(char **local_address)
3964 VERIFY_NON_NULL(local_address, TAG, "local_address");
3965 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3966 return CA_NOT_SUPPORTED;
3969 JNIEXPORT void JNICALL
3970 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3973 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3974 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3975 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3976 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3978 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3981 JNIEXPORT void JNICALL
3982 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3985 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3986 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3987 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3988 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3990 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3993 JNIEXPORT void JNICALL
3994 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3997 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3998 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3999 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4001 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4002 if (CA_STATUS_OK != res)
4004 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4008 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4010 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4012 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4013 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4015 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4016 if (!jni_cid_gattdevice_list)
4018 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4022 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4023 METHODID_BT_DEVICE);
4024 if (!jni_mid_getDevice)
4026 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4030 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4031 if (!jni_obj_device)
4033 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4037 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4040 OIC_LOG(ERROR, TAG, "jni_address is null");
4044 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4049 * Class: org_iotivity_ca_jar_caleinterface
4050 * Method: CALeGattConnectionStateChangeCallback
4051 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4053 JNIEXPORT void JNICALL
4054 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4060 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4062 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4063 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4064 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4066 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4067 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4068 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4070 if (gatt_success == status && state_connected == newstate) // le connected
4072 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4078 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4081 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4082 STATE_CHARACTER_NO_CHANGE,
4084 if (CA_STATUS_OK != res)
4086 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4087 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4090 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4092 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4095 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4096 if (CA_STATUS_OK != res)
4098 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4102 res = CALEClientDiscoverServices(env, gatt);
4103 if (CA_STATUS_OK != res)
4105 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4109 else if (state_disconnected == newstate) // le disconnected
4111 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4114 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4118 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4121 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4122 STATE_CHARACTER_UNSET,
4124 if (CA_STATUS_OK != res)
4126 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4127 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4130 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4132 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4135 CAResult_t res = CALEClientGattClose(env, gatt);
4136 if (CA_STATUS_OK != res)
4138 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4141 if (gatt_success == status)
4143 // that state is a general reason to disconnect BLE.
4144 // its means manual disconnected message from BT platform.
4145 // in this case Scanning has to start again and clean previous data.
4146 CAResult_t res = CALEClientStartScan();
4147 if (CA_STATUS_OK != res)
4149 if (CA_ADAPTER_NOT_ENABLED == res)
4151 // scan will be started with start server when adapter is enabled
4152 OIC_LOG(INFO, TAG, "Adapter was disabled");
4156 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4161 else if (GATT_ERROR == status)
4163 // when we get GATT ERROR(0x85), gatt connection can be called again.
4164 OIC_LOG(INFO, TAG, "retry gatt connect");
4166 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4169 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4173 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4176 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4180 jobject newGatt = CALEClientConnect(env, btObject,
4181 CALEClientGetAutoConnectFlag(env, leAddress));
4184 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4191 if (CALECheckConnectionStateValue(status))
4193 // this state is unexpected reason to disconnect
4194 // if the reason is suitable, connection logic of the device will be destroyed.
4195 OIC_LOG(INFO, TAG, "connection logic destroy");
4200 // other reason is expected to running background connection in BT platform.
4201 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4202 CALEClientUpdateSendCnt(env);
4209 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4210 g_sendBuffer = NULL;
4218 CALEClientSendFinish(env, gatt);
4223 * Class: org_iotivity_ca_jar_caleinterface
4224 * Method: CALeGattServicesDiscoveredCallback
4225 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4227 JNIEXPORT void JNICALL
4228 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4233 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4234 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4235 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4236 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4238 if (0 != status) // discovery error
4240 CALEClientSendFinish(env, gatt);
4244 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4247 CALEClientSendFinish(env, gatt);
4251 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4254 CALEClientSendFinish(env, gatt);
4258 if (!CALEClientIsSetCharacteristic(address))
4260 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4263 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4267 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4268 if (!jni_obj_GattCharacteristic)
4270 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4274 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4275 jni_obj_GattCharacteristic);
4276 if (CA_STATUS_OK != res)
4278 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4282 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4283 if (CA_STATUS_OK != res)
4285 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4288 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4289 if (CA_STATUS_OK != res)
4291 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4297 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4299 if (CA_STATUS_OK != res)
4301 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4309 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4310 if (CA_STATUS_OK != res)
4312 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4317 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4318 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4323 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4324 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4325 CALEClientSendFinish(env, gatt);
4330 * Class: org_iotivity_ca_jar_caleinterface
4331 * Method: CALeGattCharacteristicWritjclasseCallback
4332 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4334 JNIEXPORT void JNICALL
4335 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4336 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4339 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4340 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4341 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4342 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4344 // send success & signal
4345 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4351 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4357 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4358 if (gatt_success != status) // error case
4360 OIC_LOG(ERROR, TAG, "send failure");
4363 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4364 if (CA_STATUS_OK != res)
4366 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4367 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4368 g_isSignalSetFlag = true;
4369 ca_cond_signal(g_threadWriteCharacteristicCond);
4370 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4372 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4373 STATE_CHARACTER_SET,
4375 if (CA_STATUS_OK != res)
4377 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4380 if (g_clientErrorCallback)
4382 jint length = (*env)->GetArrayLength(env, data);
4383 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4386 CALEClientSendFinish(env, gatt);
4392 OIC_LOG(DEBUG, TAG, "send success");
4393 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4394 STATE_SEND_SUCCESS);
4395 if (CA_STATUS_OK != res)
4397 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4400 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4401 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4402 g_isSignalSetFlag = true;
4403 ca_cond_signal(g_threadWriteCharacteristicCond);
4404 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4406 CALEClientUpdateSendCnt(env);
4409 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4415 CALEClientSendFinish(env, gatt);
4420 * Class: org_iotivity_ca_jar_caleinterface
4421 * Method: CALeGattCharacteristicChangedCallback
4422 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4424 JNIEXPORT void JNICALL
4425 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4426 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4428 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4429 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4430 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4431 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4432 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4434 // get Byte Array and convert to uint8_t*
4435 jint length = (*env)->GetArrayLength(env, data);
4438 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4440 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4441 jni_byte_responseData);
4443 uint8_t* receivedData = OICMalloc(length);
4446 OIC_LOG(ERROR, TAG, "receivedData is null");
4450 memcpy(receivedData, jni_byte_responseData, length);
4451 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4453 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4456 OIC_LOG(ERROR, TAG, "jni_address is null");
4457 OICFree(receivedData);
4461 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4464 OIC_LOG(ERROR, TAG, "address is null");
4465 OICFree(receivedData);
4469 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4470 receivedData, length);
4472 ca_mutex_lock(g_bleServerBDAddressMutex);
4473 uint32_t sentLength = 0;
4474 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4476 ca_mutex_unlock(g_bleServerBDAddressMutex);
4478 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4482 * Class: org_iotivity_ca_jar_caleinterface
4483 * Method: CALeGattDescriptorWriteCallback
4484 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4486 JNIEXPORT void JNICALL
4487 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4491 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4492 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4493 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4494 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4496 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4497 if (gatt_success != status) // error
4504 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4505 if (CA_STATUS_OK != res)
4507 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4516 CALEClientSendFinish(env, gatt);