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,
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,
1099 CALEClientGetAutoConnectFlag(env, jni_address));
1102 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1103 return CA_STATUS_FAILED;
1108 return CA_STATUS_OK;
1111 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1113 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1114 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1116 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1117 if (!jni_cid_gattdevice_list)
1119 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1123 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1124 "()Landroid/bluetooth/BluetoothDevice;");
1125 if (!jni_mid_getDevice)
1127 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1131 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1132 if (!jni_obj_device)
1134 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1138 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1141 OIC_LOG(ERROR, TAG, "jni_address is null");
1151 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1154 OIC_LOG(DEBUG, TAG, "Gatt Close");
1155 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1156 VERIFY_NON_NULL(env, TAG, "env is null");
1158 // get BluetoothGatt class
1159 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1160 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1161 if (!jni_cid_BluetoothGatt)
1163 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1164 return CA_STATUS_FAILED;
1167 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1168 if (!jni_mid_closeGatt)
1170 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1171 return CA_STATUS_OK;
1174 // call disconnect gatt method
1175 OIC_LOG(DEBUG, TAG, "request to close GATT");
1176 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1178 if ((*env)->ExceptionCheck(env))
1180 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1181 (*env)->ExceptionDescribe(env);
1182 (*env)->ExceptionClear(env);
1183 return CA_STATUS_FAILED;
1186 return CA_STATUS_OK;
1189 CAResult_t CALEClientStartScan()
1191 if (!g_isStartedMulticastServer)
1193 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1194 return CA_STATUS_FAILED;
1197 if (!g_isStartedLEClient)
1199 OIC_LOG(ERROR, TAG, "LE client is not started");
1200 return CA_STATUS_FAILED;
1205 OIC_LOG(ERROR, TAG, "g_jvm is null");
1206 return CA_STATUS_FAILED;
1209 if (g_isStartedScan)
1211 OIC_LOG(INFO, TAG, "scanning is already started");
1212 return CA_STATUS_OK;
1215 bool isAttached = false;
1217 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1220 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1222 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1225 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1226 return CA_STATUS_FAILED;
1231 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1233 CAResult_t ret = CA_STATUS_OK;
1234 // scan gatt server with UUID
1235 if (g_leScanCallback && g_uuidList)
1238 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1240 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1242 if (CA_STATUS_OK != ret)
1244 if (CA_ADAPTER_NOT_ENABLED == ret)
1246 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1250 OIC_LOG(ERROR, TAG, "start scan has failed");
1257 (*g_jvm)->DetachCurrentThread(g_jvm);
1263 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1265 VERIFY_NON_NULL(callback, TAG, "callback is null");
1266 VERIFY_NON_NULL(env, TAG, "env is null");
1268 if (!CALEIsEnableBTAdapter(env))
1270 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1271 return CA_ADAPTER_NOT_ENABLED;
1274 // get default bt adapter class
1275 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1276 if (!jni_cid_BTAdapter)
1278 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1279 return CA_STATUS_FAILED;
1282 // get remote bt adapter method
1283 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1284 "getDefaultAdapter",
1285 METHODID_OBJECTNONPARAM);
1286 if (!jni_mid_getDefaultAdapter)
1288 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1289 return CA_STATUS_FAILED;
1292 // get start le scan method
1293 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1294 "(Landroid/bluetooth/BluetoothAdapter$"
1295 "LeScanCallback;)Z");
1296 if (!jni_mid_startLeScan)
1298 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1299 return CA_STATUS_FAILED;
1302 // gat bt adapter object
1303 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1304 jni_mid_getDefaultAdapter);
1305 if (!jni_obj_BTAdapter)
1307 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1308 return CA_STATUS_FAILED;
1311 // call start le scan method
1312 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1313 jni_mid_startLeScan, callback);
1314 if (!jni_obj_startLeScan)
1316 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1317 return CA_STATUS_FAILED;
1321 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1322 CALEClientSetScanFlag(true);
1325 return CA_STATUS_OK;
1328 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1330 VERIFY_NON_NULL(callback, TAG, "callback is null");
1331 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1332 VERIFY_NON_NULL(env, TAG, "env is null");
1334 if (!CALEIsEnableBTAdapter(env))
1336 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1337 return CA_ADAPTER_NOT_ENABLED;
1340 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1341 if (!jni_cid_BTAdapter)
1343 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1344 return CA_STATUS_FAILED;
1347 // get remote bt adapter method
1348 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1349 "getDefaultAdapter",
1350 METHODID_OBJECTNONPARAM);
1351 if (!jni_mid_getDefaultAdapter)
1353 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1354 return CA_STATUS_FAILED;
1357 // get start le scan method
1358 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1359 "([Ljava/util/UUID;Landroid/bluetooth/"
1360 "BluetoothAdapter$LeScanCallback;)Z");
1361 if (!jni_mid_startLeScan)
1363 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1364 return CA_STATUS_FAILED;
1367 // get bt adapter object
1368 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1369 jni_mid_getDefaultAdapter);
1370 if (!jni_obj_BTAdapter)
1372 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1373 return CA_STATUS_FAILED;
1376 // call start le scan method
1377 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1378 jni_mid_startLeScan, uuids, callback);
1379 if (!jni_obj_startLeScan)
1381 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1382 return CA_STATUS_FAILED;
1386 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1387 CALEClientSetScanFlag(true);
1390 return CA_STATUS_OK;
1393 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1395 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1396 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1399 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1402 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1406 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1407 "(Ljava/lang/String;)"
1408 "Ljava/util/UUID;");
1409 if (!jni_mid_fromString)
1411 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1415 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1416 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1420 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1424 return jni_obj_uuid;
1427 CAResult_t CALEClientStopScan()
1431 OIC_LOG(ERROR, TAG, "g_jvm is null");
1432 return CA_STATUS_FAILED;
1435 if (!g_isStartedScan)
1437 OIC_LOG(INFO, TAG, "scanning is already stopped");
1438 return CA_STATUS_OK;
1441 bool isAttached = false;
1443 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1446 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1447 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1450 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1451 return CA_STATUS_FAILED;
1456 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1457 if (CA_STATUS_OK != ret)
1459 if (CA_ADAPTER_NOT_ENABLED == ret)
1461 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1465 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1470 CALEClientSetScanFlag(false);
1475 (*g_jvm)->DetachCurrentThread(g_jvm);
1481 void CALEClientSetScanFlag(bool flag)
1483 ca_mutex_lock(g_scanMutex);
1484 g_isStartedScan = flag;
1485 ca_mutex_unlock(g_scanMutex);
1488 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1490 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1491 VERIFY_NON_NULL(callback, TAG, "callback is null");
1492 VERIFY_NON_NULL(env, TAG, "env is null");
1494 if (!CALEIsEnableBTAdapter(env))
1496 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1497 return CA_ADAPTER_NOT_ENABLED;
1500 // get default bt adapter class
1501 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1502 if (!jni_cid_BTAdapter)
1504 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1505 return CA_STATUS_FAILED;
1508 // get remote bt adapter method
1509 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1510 "getDefaultAdapter",
1511 METHODID_OBJECTNONPARAM);
1512 if (!jni_mid_getDefaultAdapter)
1514 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1515 return CA_STATUS_FAILED;
1518 // get start le scan method
1519 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1520 "(Landroid/bluetooth/"
1521 "BluetoothAdapter$LeScanCallback;)V");
1522 if (!jni_mid_stopLeScan)
1524 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1525 return CA_STATUS_FAILED;
1528 // gat bt adapter object
1529 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1530 jni_mid_getDefaultAdapter);
1531 if (!jni_obj_BTAdapter)
1533 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1534 return CA_STATUS_FAILED;
1537 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1538 // call start le scan method
1539 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1540 if ((*env)->ExceptionCheck(env))
1542 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1543 (*env)->ExceptionDescribe(env);
1544 (*env)->ExceptionClear(env);
1545 return CA_STATUS_FAILED;
1548 return CA_STATUS_OK;
1551 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1553 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1554 VERIFY_NON_NULL(env, TAG, "env");
1555 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1557 ca_mutex_lock(g_deviceStateListMutex);
1559 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1562 OIC_LOG(ERROR, TAG, "address is not available");
1563 return CA_STATUS_FAILED;
1566 if (CALEClientIsDeviceInList(address))
1568 CALEState_t* curState = CALEClientGetStateInfo(address);
1571 OIC_LOG(ERROR, TAG, "curState is null");
1572 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1573 ca_mutex_unlock(g_deviceStateListMutex);
1574 return CA_STATUS_FAILED;
1576 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1578 curState->autoConnectFlag = flag;
1581 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1582 ca_mutex_unlock(g_deviceStateListMutex);
1583 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1584 return CA_STATUS_OK;
1587 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1589 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1590 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1591 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1593 ca_mutex_lock(g_deviceStateListMutex);
1595 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1598 OIC_LOG(ERROR, TAG, "address is not available");
1602 CALEState_t* curState = CALEClientGetStateInfo(address);
1605 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1606 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1607 ca_mutex_unlock(g_deviceStateListMutex);
1610 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1612 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1613 ca_mutex_unlock(g_deviceStateListMutex);
1615 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1616 return curState->autoConnectFlag;
1619 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1621 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1622 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1623 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1625 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1626 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1629 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1632 OIC_LOG(ERROR, TAG, "address is not available");
1636 // close the gatt service
1637 jobject gatt = CALEClientGetGattObjInList(env, address);
1640 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1641 if (CA_STATUS_OK != res)
1643 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1644 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1648 // clean previous gatt object after close profile service
1649 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1650 if (CA_STATUS_OK != res)
1652 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1653 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1657 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1660 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1663 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1667 // add new gatt object into g_gattObjectList
1668 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1669 if (CA_STATUS_OK != res)
1671 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1678 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1680 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1681 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1682 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1684 if (!CALEIsEnableBTAdapter(env))
1686 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1690 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1693 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1697 // get BluetoothDevice class
1698 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1699 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1700 if (!jni_cid_BluetoothDevice)
1702 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1706 // get connectGatt method
1707 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1708 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1709 "(Landroid/content/Context;ZLandroid/"
1710 "bluetooth/BluetoothGattCallback;)"
1711 "Landroid/bluetooth/BluetoothGatt;");
1712 if (!jni_mid_connectGatt)
1714 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1718 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1719 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1720 jni_mid_connectGatt,
1722 autoconnect, g_leGattCallback);
1723 if (!jni_obj_connectGatt)
1725 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1726 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1727 CALEClientUpdateSendCnt(env);
1732 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1734 return jni_obj_connectGatt;
1737 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1739 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1741 VERIFY_NON_NULL(env, TAG, "env is null");
1742 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1744 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1745 if (!jni_cid_BTAdapter)
1747 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1748 return CA_STATUS_FAILED;
1751 // get remote bt adapter method
1752 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1753 "getDefaultAdapter",
1754 METHODID_OBJECTNONPARAM);
1755 if (!jni_mid_getDefaultAdapter)
1757 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1758 return CA_STATUS_FAILED;
1761 // gat bt adapter object
1762 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1763 jni_mid_getDefaultAdapter);
1764 if (!jni_obj_BTAdapter)
1766 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1767 return CA_STATUS_FAILED;
1770 // get closeProfileProxy method
1771 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1772 "closeProfileProxy",
1773 "(ILandroid/bluetooth/"
1774 "BluetoothProfile;)V");
1775 if (!jni_mid_closeProfileProxy)
1777 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1778 return CA_STATUS_FAILED;
1781 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1782 if (!jni_cid_BTProfile)
1784 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1785 return CA_STATUS_FAILED;
1788 // GATT - Constant value : 7 (0x00000007)
1789 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1793 OIC_LOG(ERROR, TAG, "id_gatt is null");
1794 return CA_STATUS_FAILED;
1797 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1799 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1800 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1801 if ((*env)->ExceptionCheck(env))
1803 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1804 (*env)->ExceptionDescribe(env);
1805 (*env)->ExceptionClear(env);
1806 return CA_STATUS_FAILED;
1809 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1810 return CA_STATUS_OK;
1814 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1816 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1817 VERIFY_NON_NULL(env, TAG, "env is null");
1818 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1820 // get BluetoothGatt class
1821 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1822 if (!jni_cid_BluetoothGatt)
1824 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1825 return CA_STATUS_FAILED;
1828 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1829 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1830 "disconnect", "()V");
1831 if (!jni_mid_disconnectGatt)
1833 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1834 return CA_STATUS_FAILED;
1837 // call disconnect gatt method
1838 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1839 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1840 if ((*env)->ExceptionCheck(env))
1842 OIC_LOG(ERROR, TAG, "disconnect has failed");
1843 (*env)->ExceptionDescribe(env);
1844 (*env)->ExceptionClear(env);
1845 return CA_STATUS_FAILED;
1848 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1850 return CA_STATUS_OK;
1853 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1855 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1856 VERIFY_NON_NULL(env, TAG, "env is null");
1858 if (!g_gattObjectList)
1860 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1861 return CA_STATUS_OK;
1864 uint32_t length = u_arraylist_length(g_gattObjectList);
1865 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1866 for (uint32_t index = 0; index < length; index++)
1868 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1869 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1872 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1875 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1876 if (CA_STATUS_OK != res)
1878 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1883 return CA_STATUS_OK;
1886 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1888 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1889 VERIFY_NON_NULL(env, TAG, "env is null");
1891 if (!g_gattObjectList)
1893 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1894 return CA_STATUS_OK;
1897 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1900 OIC_LOG(ERROR, TAG, "address is null");
1901 return CA_STATUS_FAILED;
1904 uint32_t length = u_arraylist_length(g_gattObjectList);
1905 for (uint32_t index = 0; index < length; index++)
1907 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1910 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1914 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1915 if (!jni_setAddress)
1917 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1918 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1919 return CA_STATUS_FAILED;
1922 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1925 OIC_LOG(ERROR, TAG, "setAddress is null");
1926 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1927 return CA_STATUS_FAILED;
1930 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1931 if (!strcmp(address, setAddress))
1933 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1934 if (CA_STATUS_OK != res)
1936 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1937 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1938 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1939 return CA_STATUS_FAILED;
1941 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1942 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1943 return CA_STATUS_OK;
1945 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1947 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1949 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1950 return CA_STATUS_OK;
1953 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1955 VERIFY_NON_NULL(env, TAG, "env is null");
1956 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1958 if (!CALEIsEnableBTAdapter(env))
1960 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1961 return CA_ADAPTER_NOT_ENABLED;
1964 // get BluetoothGatt class
1965 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1966 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1967 if (!jni_cid_BluetoothGatt)
1969 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1970 return CA_STATUS_FAILED;
1973 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1974 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1975 "discoverServices", "()Z");
1976 if (!jni_mid_discoverServices)
1978 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1979 return CA_STATUS_FAILED;
1981 // call disconnect gatt method
1982 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1983 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1986 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1987 return CA_STATUS_FAILED;
1990 return CA_STATUS_OK;
1993 static void CALEWriteCharacteristicThread(void* object)
1995 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1997 bool isAttached = false;
1999 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2002 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2003 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2007 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2013 jobject gatt = (jobject)object;
2014 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2015 if (CA_STATUS_OK != ret)
2017 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2022 (*g_jvm)->DetachCurrentThread(g_jvm);
2026 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2028 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2029 VERIFY_NON_NULL(env, TAG, "env is null");
2032 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2033 if (!jni_obj_character)
2035 CALEClientSendFinish(env, gatt);
2036 return CA_STATUS_FAILED;
2039 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2040 if (CA_STATUS_OK != ret)
2042 CALEClientSendFinish(env, gatt);
2043 return CA_STATUS_FAILED;
2046 // wait for callback for write Characteristic with success to sent data
2047 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2048 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2049 if (!g_isSignalSetFlag)
2051 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2052 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2053 g_threadWriteCharacteristicMutex,
2054 WAIT_TIME_WRITE_CHARACTERISTIC))
2056 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2057 g_isSignalSetFlag = false;
2058 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2059 return CA_STATUS_FAILED;
2062 // reset flag set by writeCharacteristic Callback
2063 g_isSignalSetFlag = false;
2064 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2066 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2067 return CA_STATUS_OK;
2070 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2072 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2073 VERIFY_NON_NULL(env, TAG, "env is null");
2074 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2076 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2077 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2078 CALEWriteCharacteristicThread, (void*)gattParam))
2080 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2081 return CA_STATUS_FAILED;
2084 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2085 return CA_STATUS_OK;
2088 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2089 jobject gattCharacteristic)
2091 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2092 VERIFY_NON_NULL(env, TAG, "env is null");
2093 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2094 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2096 if (!CALEIsEnableBTAdapter(env))
2098 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2099 return CA_STATUS_FAILED;
2102 // get BluetoothGatt class
2103 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
2104 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2105 if (!jni_cid_BluetoothGatt)
2107 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2108 return CA_STATUS_FAILED;
2111 OIC_LOG(DEBUG, TAG, "write characteristic method");
2112 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2113 "writeCharacteristic",
2114 "(Landroid/bluetooth/"
2115 "BluetoothGattCharacteristic;)Z");
2116 if (!jni_mid_writeCharacteristic)
2118 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2119 return CA_STATUS_FAILED;
2122 // call disconnect gatt method
2123 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2124 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2125 jni_mid_writeCharacteristic,
2126 gattCharacteristic);
2129 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2133 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2134 return CA_STATUS_FAILED;
2137 return CA_STATUS_OK;
2140 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2142 VERIFY_NON_NULL(env, TAG, "env is null");
2143 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2145 if (!CALEIsEnableBTAdapter(env))
2147 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2148 return CA_STATUS_FAILED;
2151 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2152 if (!jni_cid_BluetoothGatt)
2154 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2155 return CA_STATUS_FAILED;
2158 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2161 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2162 return CA_STATUS_FAILED;
2165 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2166 if (!jni_obj_GattCharacteristic)
2168 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2169 return CA_STATUS_FAILED;
2172 OIC_LOG(DEBUG, TAG, "read characteristic method");
2173 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2174 "readCharacteristic",
2175 "(Landroid/bluetooth/"
2176 "BluetoothGattCharacteristic;)Z");
2177 if (!jni_mid_readCharacteristic)
2179 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2180 return CA_STATUS_FAILED;
2183 // call disconnect gatt method
2184 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2185 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2186 jni_obj_GattCharacteristic);
2189 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2193 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2194 return CA_STATUS_FAILED;
2197 return CA_STATUS_OK;
2200 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2201 jobject characteristic)
2203 VERIFY_NON_NULL(env, TAG, "env is null");
2204 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2205 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2207 if (!CALEIsEnableBTAdapter(env))
2209 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2210 return CA_ADAPTER_NOT_ENABLED;
2213 // get BluetoothGatt class
2214 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2215 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2216 if (!jni_cid_BluetoothGatt)
2218 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2219 return CA_STATUS_FAILED;
2222 // set Characteristic Notification
2223 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2224 "setCharacteristicNotification",
2225 "(Landroid/bluetooth/"
2226 "BluetoothGattCharacteristic;Z)Z");
2227 if (!jni_mid_setNotification)
2229 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2230 return CA_STATUS_FAILED;
2233 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2234 characteristic, JNI_TRUE);
2235 if (JNI_TRUE == ret)
2237 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2241 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2242 return CA_STATUS_FAILED;
2245 return CA_STATUS_OK;
2248 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2250 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2251 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2252 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2254 if (!CALEIsEnableBTAdapter(env))
2256 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2260 // get BluetoothGatt class
2261 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2262 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2263 if (!jni_cid_BluetoothGatt)
2265 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2269 jmethodID jni_mid_getService = (*env)->GetMethodID(
2270 env, jni_cid_BluetoothGatt, "getService",
2271 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2272 if (!jni_mid_getService)
2274 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2278 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2279 if (!jni_obj_service_uuid)
2281 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2285 // get bluetooth gatt service
2286 OIC_LOG(DEBUG, TAG, "request to get service");
2287 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2288 jni_obj_service_uuid);
2289 if (!jni_obj_gattService)
2291 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2295 // get bluetooth gatt service class
2296 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2297 env, "android/bluetooth/BluetoothGattService");
2298 if (!jni_cid_BluetoothGattService)
2300 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2304 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2305 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2306 "getCharacteristic",
2307 "(Ljava/util/UUID;)"
2308 "Landroid/bluetooth/"
2309 "BluetoothGattCharacteristic;");
2310 if (!jni_mid_getCharacteristic)
2312 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2316 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2319 OIC_LOG(ERROR, TAG, "uuid is null");
2323 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2324 if (!jni_obj_tx_uuid)
2326 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2327 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2331 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2332 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2333 jni_mid_getCharacteristic,
2336 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2337 return jni_obj_GattCharacteristic;
2340 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2342 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2343 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2344 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2345 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2347 if (!CALEIsEnableBTAdapter(env))
2349 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2353 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2356 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2360 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2361 if (!jni_obj_GattCharacteristic)
2363 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2367 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2368 "/BluetoothGattCharacteristic");
2369 if (!jni_cid_BTGattCharacteristic)
2371 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2375 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2376 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2378 if (!jni_mid_setValue)
2380 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2384 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2386 if (JNI_TRUE == ret)
2388 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2392 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2397 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2398 "setWriteType", "(I)V");
2399 if (!jni_mid_setWriteType)
2401 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2405 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2406 "WRITE_TYPE_NO_RESPONSE", "I");
2407 if (!jni_fid_no_response)
2409 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2413 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2414 jni_fid_no_response);
2416 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2418 return jni_obj_GattCharacteristic;
2421 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2423 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2424 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2426 if (!CALEIsEnableBTAdapter(env))
2428 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2432 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2433 "BluetoothGattCharacteristic");
2434 if (!jni_cid_BTGattCharacteristic)
2436 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2440 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2441 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2443 if (!jni_mid_getValue)
2445 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2449 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2451 return jni_obj_data_array;
2454 CAResult_t CALEClientCreateUUIDList()
2458 OIC_LOG(ERROR, TAG, "g_jvm is null");
2459 return CA_STATUS_FAILED;
2462 bool isAttached = false;
2464 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2467 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2468 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2472 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2473 return CA_STATUS_FAILED;
2478 // create new object array
2479 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2480 if (!jni_cid_uuid_list)
2482 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2486 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2487 jni_cid_uuid_list, NULL);
2488 if (!jni_obj_uuid_list)
2490 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2495 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2498 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2501 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2503 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2507 (*g_jvm)->DetachCurrentThread(g_jvm);
2510 return CA_STATUS_OK;
2517 (*g_jvm)->DetachCurrentThread(g_jvm);
2519 return CA_STATUS_FAILED;
2522 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2523 jobject characteristic)
2525 VERIFY_NON_NULL(env, TAG, "env is null");
2526 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2527 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2529 if (!CALEIsEnableBTAdapter(env))
2531 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2532 return CA_ADAPTER_NOT_ENABLED;
2535 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2536 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2537 "BluetoothGattCharacteristic");
2538 if (!jni_cid_BTGattCharacteristic)
2540 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2541 return CA_STATUS_FAILED;
2544 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2545 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2547 "(Ljava/util/UUID;)Landroid/bluetooth/"
2548 "BluetoothGattDescriptor;");
2549 if (!jni_mid_getDescriptor)
2551 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2552 return CA_STATUS_FAILED;
2555 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2556 if (!jni_obj_cc_uuid)
2558 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2559 return CA_STATUS_FAILED;
2562 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2563 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2564 jni_mid_getDescriptor, jni_obj_cc_uuid);
2565 if (!jni_obj_descriptor)
2567 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2568 return CA_NOT_SUPPORTED;
2571 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2572 jclass jni_cid_descriptor = (*env)->FindClass(env,
2573 "android/bluetooth/BluetoothGattDescriptor");
2574 if (!jni_cid_descriptor)
2576 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2577 return CA_STATUS_FAILED;
2580 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2581 if (!jni_mid_setValue)
2583 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2584 return CA_STATUS_FAILED;
2587 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2588 "ENABLE_NOTIFICATION_VALUE", "[B");
2589 if (!jni_fid_NotiValue)
2591 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2592 return CA_STATUS_FAILED;
2595 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2597 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2598 env, jni_obj_descriptor, jni_mid_setValue,
2599 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2602 OIC_LOG(DEBUG, TAG, "setValue success");
2606 OIC_LOG(ERROR, TAG, "setValue has failed");
2607 return CA_STATUS_FAILED;
2610 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2613 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2614 return CA_STATUS_FAILED;
2617 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2618 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2619 "(Landroid/bluetooth/"
2620 "BluetoothGattDescriptor;)Z");
2621 if (!jni_mid_writeDescriptor)
2623 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2624 return CA_STATUS_FAILED;
2627 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2628 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2629 jni_obj_descriptor);
2632 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2636 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2637 return CA_STATUS_FAILED;
2640 return CA_STATUS_OK;
2643 void CALEClientCreateScanDeviceList(JNIEnv *env)
2645 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2646 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2648 ca_mutex_lock(g_deviceListMutex);
2649 // create new object array
2650 if (g_deviceList == NULL)
2652 OIC_LOG(DEBUG, TAG, "Create device list");
2654 g_deviceList = u_arraylist_create();
2656 ca_mutex_unlock(g_deviceListMutex);
2659 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2661 VERIFY_NON_NULL(device, TAG, "device is null");
2662 VERIFY_NON_NULL(env, TAG, "env is null");
2664 ca_mutex_lock(g_deviceListMutex);
2668 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2669 ca_mutex_unlock(g_deviceListMutex);
2670 return CA_STATUS_FAILED;
2673 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2674 if (!jni_remoteAddress)
2676 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2677 ca_mutex_unlock(g_deviceListMutex);
2678 return CA_STATUS_FAILED;
2681 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2684 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2685 ca_mutex_unlock(g_deviceListMutex);
2686 return CA_STATUS_FAILED;
2689 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2691 jobject gdevice = (*env)->NewGlobalRef(env, device);
2692 u_arraylist_add(g_deviceList, gdevice);
2693 ca_cond_signal(g_deviceDescCond);
2694 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2696 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2698 ca_mutex_unlock(g_deviceListMutex);
2700 return CA_STATUS_OK;
2703 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2705 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2706 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2710 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2714 uint32_t length = u_arraylist_length(g_deviceList);
2715 for (uint32_t index = 0; index < length; index++)
2717 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2720 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2724 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2725 if (!jni_setAddress)
2727 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2731 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2734 OIC_LOG(ERROR, TAG, "setAddress is null");
2738 if (!strcmp(remoteAddress, setAddress))
2740 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2744 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2747 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2752 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2754 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2755 VERIFY_NON_NULL(env, TAG, "env is null");
2757 ca_mutex_lock(g_deviceListMutex);
2761 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2762 ca_mutex_unlock(g_deviceListMutex);
2763 return CA_STATUS_FAILED;
2766 uint32_t length = u_arraylist_length(g_deviceList);
2767 for (uint32_t index = 0; index < length; index++)
2769 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2772 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2775 (*env)->DeleteGlobalRef(env, jarrayObj);
2779 OICFree(g_deviceList);
2780 g_deviceList = NULL;
2782 ca_mutex_unlock(g_deviceListMutex);
2783 return CA_STATUS_OK;
2786 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2788 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2789 VERIFY_NON_NULL(address, TAG, "address is null");
2790 VERIFY_NON_NULL(env, TAG, "env is null");
2792 ca_mutex_lock(g_deviceListMutex);
2796 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2797 ca_mutex_unlock(g_deviceListMutex);
2798 return CA_STATUS_FAILED;
2801 uint32_t length = u_arraylist_length(g_deviceList);
2802 for (uint32_t index = 0; index < length; index++)
2804 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2807 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2808 ca_mutex_unlock(g_deviceListMutex);
2809 return CA_STATUS_FAILED;
2812 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2813 if (!jni_setAddress)
2815 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2816 ca_mutex_unlock(g_deviceListMutex);
2817 return CA_STATUS_FAILED;
2820 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2823 OIC_LOG(ERROR, TAG, "setAddress is null");
2824 ca_mutex_unlock(g_deviceListMutex);
2825 return CA_STATUS_FAILED;
2828 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2831 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2832 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2833 ca_mutex_unlock(g_deviceListMutex);
2834 return CA_STATUS_FAILED;
2837 if (!strcmp(setAddress, remoteAddress))
2839 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2840 (*env)->DeleteGlobalRef(env, jarrayObj);
2842 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2843 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2845 if (NULL == u_arraylist_remove(g_deviceList, index))
2847 OIC_LOG(ERROR, TAG, "List removal failed.");
2848 ca_mutex_unlock(g_deviceListMutex);
2849 return CA_STATUS_FAILED;
2851 ca_mutex_unlock(g_deviceListMutex);
2852 return CA_STATUS_OK;
2854 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2855 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2858 ca_mutex_unlock(g_deviceListMutex);
2859 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2861 return CA_STATUS_OK;
2868 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2870 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2871 VERIFY_NON_NULL(env, TAG, "env is null");
2872 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2874 ca_mutex_lock(g_gattObjectMutex);
2876 if (!g_gattObjectList)
2878 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2879 ca_mutex_unlock(g_gattObjectMutex);
2880 return CA_STATUS_FAILED;
2883 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2884 if (!jni_remoteAddress)
2886 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2887 ca_mutex_unlock(g_gattObjectMutex);
2888 return CA_STATUS_FAILED;
2891 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2894 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2895 ca_mutex_unlock(g_gattObjectMutex);
2896 return CA_STATUS_FAILED;
2899 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2900 if (!CALEClientIsGattObjInList(env, remoteAddress))
2902 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2903 u_arraylist_add(g_gattObjectList, newGatt);
2904 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2907 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2908 ca_mutex_unlock(g_gattObjectMutex);
2909 return CA_STATUS_OK;
2912 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2914 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2915 VERIFY_NON_NULL(env, TAG, "env is null");
2916 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2918 uint32_t length = u_arraylist_length(g_gattObjectList);
2919 for (uint32_t index = 0; index < length; index++)
2922 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2925 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2929 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2930 if (!jni_setAddress)
2932 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2936 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2939 OIC_LOG(ERROR, TAG, "setAddress is null");
2943 if (!strcmp(remoteAddress, setAddress))
2945 OIC_LOG(DEBUG, TAG, "the device is already set");
2946 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2951 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2956 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2960 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2962 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2963 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2964 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2966 ca_mutex_lock(g_gattObjectMutex);
2967 uint32_t length = u_arraylist_length(g_gattObjectList);
2968 for (uint32_t index = 0; index < length; index++)
2970 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2973 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2974 ca_mutex_unlock(g_gattObjectMutex);
2978 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2979 if (!jni_setAddress)
2981 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2982 ca_mutex_unlock(g_gattObjectMutex);
2986 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2989 OIC_LOG(ERROR, TAG, "setAddress is null");
2990 ca_mutex_unlock(g_gattObjectMutex);
2994 if (!strcmp(remoteAddress, setAddress))
2996 OIC_LOG(DEBUG, TAG, "the device is already set");
2997 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2998 ca_mutex_unlock(g_gattObjectMutex);
3001 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3004 ca_mutex_unlock(g_gattObjectMutex);
3005 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
3009 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
3011 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
3012 VERIFY_NON_NULL(env, TAG, "env is null");
3014 ca_mutex_lock(g_gattObjectMutex);
3015 if (!g_gattObjectList)
3017 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3018 ca_mutex_unlock(g_gattObjectMutex);
3019 return CA_STATUS_OK;
3022 uint32_t length = u_arraylist_length(g_gattObjectList);
3023 for (uint32_t index = 0; index < length; index++)
3025 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3028 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3031 (*env)->DeleteGlobalRef(env, jarrayObj);
3035 OICFree(g_gattObjectList);
3036 g_gattObjectList = NULL;
3037 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3038 ca_mutex_unlock(g_gattObjectMutex);
3039 return CA_STATUS_OK;
3042 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3044 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3045 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3046 VERIFY_NON_NULL(env, TAG, "env is null");
3048 ca_mutex_lock(g_gattObjectMutex);
3049 if (!g_gattObjectList)
3051 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3052 ca_mutex_unlock(g_gattObjectMutex);
3053 return CA_STATUS_OK;
3056 uint32_t length = u_arraylist_length(g_gattObjectList);
3057 for (uint32_t index = 0; index < length; index++)
3059 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3062 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3063 ca_mutex_unlock(g_gattObjectMutex);
3064 return CA_STATUS_FAILED;
3067 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3068 if (!jni_setAddress)
3070 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3071 ca_mutex_unlock(g_gattObjectMutex);
3072 return CA_STATUS_FAILED;
3075 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3078 OIC_LOG(ERROR, TAG, "setAddress is null");
3079 ca_mutex_unlock(g_gattObjectMutex);
3080 return CA_STATUS_FAILED;
3083 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3084 if (!jni_remoteAddress)
3086 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3087 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3088 ca_mutex_unlock(g_gattObjectMutex);
3089 return CA_STATUS_FAILED;
3092 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3095 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3096 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3097 ca_mutex_unlock(g_gattObjectMutex);
3098 return CA_STATUS_FAILED;
3101 if (!strcmp(setAddress, remoteAddress))
3103 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3104 (*env)->DeleteGlobalRef(env, jarrayObj);
3106 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3107 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3109 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3111 OIC_LOG(ERROR, TAG, "List removal failed.");
3112 ca_mutex_unlock(g_gattObjectMutex);
3113 return CA_STATUS_FAILED;
3115 ca_mutex_unlock(g_gattObjectMutex);
3116 return CA_STATUS_OK;
3118 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3119 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3122 ca_mutex_unlock(g_gattObjectMutex);
3123 OIC_LOG(DEBUG, TAG, "there are no target object");
3124 return CA_STATUS_OK;
3127 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3129 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3130 VERIFY_NON_NULL(addr, TAG, "addr is null");
3131 VERIFY_NON_NULL(env, TAG, "env is null");
3133 ca_mutex_lock(g_gattObjectMutex);
3134 if (!g_gattObjectList)
3136 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3137 ca_mutex_unlock(g_gattObjectMutex);
3138 return CA_STATUS_OK;
3141 uint32_t length = u_arraylist_length(g_gattObjectList);
3142 for (uint32_t index = 0; index < length; index++)
3144 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3147 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3148 ca_mutex_unlock(g_gattObjectMutex);
3149 return CA_STATUS_FAILED;
3152 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3153 if (!jni_setAddress)
3155 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3156 ca_mutex_unlock(g_gattObjectMutex);
3157 return CA_STATUS_FAILED;
3160 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3163 OIC_LOG(ERROR, TAG, "setAddress is null");
3164 ca_mutex_unlock(g_gattObjectMutex);
3165 return CA_STATUS_FAILED;
3168 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3171 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3172 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3173 ca_mutex_unlock(g_gattObjectMutex);
3174 return CA_STATUS_FAILED;
3177 if (!strcmp(setAddress, remoteAddress))
3179 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3180 (*env)->DeleteGlobalRef(env, jarrayObj);
3182 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3183 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3184 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3186 OIC_LOG(ERROR, TAG, "List removal failed.");
3187 ca_mutex_unlock(g_gattObjectMutex);
3188 return CA_STATUS_FAILED;
3190 ca_mutex_unlock(g_gattObjectMutex);
3191 return CA_STATUS_OK;
3193 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3194 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3197 ca_mutex_unlock(g_gattObjectMutex);
3198 OIC_LOG(DEBUG, TAG, "there are no target object");
3199 return CA_STATUS_FAILED;
3202 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3204 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3206 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3207 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3209 // get Bluetooth Address
3210 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3211 if (!jni_btTargetAddress)
3213 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3217 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3220 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3224 // get method ID of getDevice()
3225 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3226 if (!jni_cid_gattdevice_list)
3228 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3229 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3233 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3234 METHODID_BT_DEVICE);
3235 if (!jni_mid_getDevice)
3237 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3238 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3242 size_t length = u_arraylist_length(g_gattObjectList);
3243 for (size_t index = 0; index < length; index++)
3245 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3248 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3249 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3253 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3254 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3255 if (!jni_obj_device)
3257 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3258 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3262 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3265 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3266 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3270 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3273 OIC_LOG(ERROR, TAG, "btAddress is not available");
3274 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3278 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3279 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3280 if (!strcmp(targetAddress, btAddress))
3282 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3285 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3288 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3290 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3291 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3292 (*env)->DeleteLocalRef(env, jni_btAddress);
3293 (*env)->DeleteLocalRef(env, jni_obj_device);
3294 return jni_LEAddress;
3296 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3297 (*env)->DeleteLocalRef(env, jni_btAddress);
3298 (*env)->DeleteLocalRef(env, jni_obj_device);
3301 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3309 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3310 uint16_t notificationState, uint16_t sendState)
3312 VERIFY_NON_NULL(address, TAG, "address is null");
3314 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3317 OIC_LOG(ERROR, TAG, "out of memory");
3318 return CA_MEMORY_ALLOC_FAILED;
3321 if (strlen(address) > CA_MACADDR_SIZE)
3323 OIC_LOG(ERROR, TAG, "address is not proper");
3325 return CA_STATUS_FAILED;
3328 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3329 newstate->connectedState = connectedState;
3330 newstate->notificationState = notificationState;
3331 newstate->sendState = sendState;
3332 return CALEClientAddDeviceStateToList(newstate);
3335 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3337 VERIFY_NON_NULL(state, TAG, "state is null");
3339 ca_mutex_lock(g_deviceStateListMutex);
3341 if (!g_deviceStateList)
3343 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3344 ca_mutex_unlock(g_deviceStateListMutex);
3345 return CA_STATUS_FAILED;
3348 if (CALEClientIsDeviceInList(state->address))
3350 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3353 OIC_LOG(ERROR, TAG, "curState is null");
3354 ca_mutex_unlock(g_deviceStateListMutex);
3355 return CA_STATUS_FAILED;
3358 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3360 state->notificationState = curState->notificationState;
3362 state->autoConnectFlag = curState->autoConnectFlag;
3364 // delete previous state for update new state
3365 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3366 if (CA_STATUS_OK != res)
3368 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3369 ca_mutex_unlock(g_deviceStateListMutex);
3373 u_arraylist_add(g_deviceStateList, state); // update new state
3374 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3375 state->connectedState, state->notificationState, state->address);
3377 ca_mutex_unlock(g_deviceStateListMutex);
3378 return CA_STATUS_OK;
3381 bool CALEClientIsDeviceInList(const char* remoteAddress)
3383 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3385 if (!g_deviceStateList)
3387 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3391 uint32_t length = u_arraylist_length(g_deviceStateList);
3392 for (uint32_t index = 0; index < length; index++)
3394 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3397 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3401 if (!strcmp(remoteAddress, state->address))
3403 OIC_LOG(DEBUG, TAG, "the device is already set");
3412 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3416 CAResult_t CALEClientRemoveAllDeviceState()
3418 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3420 ca_mutex_lock(g_deviceStateListMutex);
3421 if (!g_deviceStateList)
3423 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3424 ca_mutex_unlock(g_deviceStateListMutex);
3425 return CA_STATUS_FAILED;
3428 uint32_t length = u_arraylist_length(g_deviceStateList);
3429 for (uint32_t index = 0; index < length; index++)
3431 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3434 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3440 OICFree(g_deviceStateList);
3441 g_deviceStateList = NULL;
3442 ca_mutex_unlock(g_deviceStateListMutex);
3444 return CA_STATUS_OK;
3447 CAResult_t CALEClientResetDeviceStateForAll()
3449 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3451 ca_mutex_lock(g_deviceStateListMutex);
3452 if (!g_deviceStateList)
3454 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3455 ca_mutex_unlock(g_deviceStateListMutex);
3456 return CA_STATUS_FAILED;
3459 size_t length = u_arraylist_length(g_deviceStateList);
3460 for (size_t index = 0; index < length; index++)
3462 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3465 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3469 // autoConnectFlag value will be not changed,
3470 // since it has reset only termination case.
3471 state->connectedState = STATE_DISCONNECTED;
3472 state->notificationState = STATE_CHARACTER_UNSET;
3473 state->sendState = STATE_SEND_NONE;
3475 ca_mutex_unlock(g_deviceStateListMutex);
3477 return CA_STATUS_OK;
3480 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3482 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3483 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3485 if (!g_deviceStateList)
3487 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3488 return CA_STATUS_FAILED;
3491 uint32_t length = u_arraylist_length(g_deviceStateList);
3492 for (uint32_t index = 0; index < length; index++)
3494 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3497 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3501 if (!strcmp(state->address, remoteAddress))
3503 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3505 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3507 if (NULL == targetState)
3509 OIC_LOG(ERROR, TAG, "List removal failed.");
3510 return CA_STATUS_FAILED;
3513 OICFree(targetState);
3514 return CA_STATUS_OK;
3518 return CA_STATUS_OK;
3521 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3523 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3524 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3526 if (!g_deviceStateList)
3528 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3532 uint32_t length = u_arraylist_length(g_deviceStateList);
3533 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3535 for (uint32_t index = 0; index < length; index++)
3537 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3540 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3544 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3545 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3547 if (!strcmp(state->address, remoteAddress))
3549 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3556 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3558 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3559 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3561 ca_mutex_lock(g_deviceStateListMutex);
3562 if (!g_deviceStateList)
3564 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3565 ca_mutex_unlock(g_deviceStateListMutex);
3569 uint32_t length = u_arraylist_length(g_deviceStateList);
3570 for (uint32_t index = 0; index < length; index++)
3572 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3575 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3579 if (!strcmp(state->address, remoteAddress))
3581 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3583 if (STATE_CONNECTED == state->connectedState)
3585 ca_mutex_unlock(g_deviceStateListMutex);
3590 ca_mutex_unlock(g_deviceStateListMutex);
3595 ca_mutex_unlock(g_deviceStateListMutex);
3599 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3601 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3602 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3604 ca_mutex_lock(g_deviceStateListMutex);
3605 if (!g_deviceStateList)
3607 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3608 ca_mutex_unlock(g_deviceStateListMutex);
3612 uint32_t length = u_arraylist_length(g_deviceStateList);
3613 for (uint32_t index = 0; index < length; index++)
3615 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3618 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3622 if (!strcmp(state->address, remoteAddress))
3624 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3626 if (STATE_CHARACTER_SET == state->notificationState)
3628 ca_mutex_unlock(g_deviceStateListMutex);
3633 ca_mutex_unlock(g_deviceStateListMutex);
3639 ca_mutex_unlock(g_deviceStateListMutex);
3643 void CALEClientCreateDeviceList()
3645 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3647 // create new object array
3648 if (!g_gattObjectList)
3650 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3652 g_gattObjectList = u_arraylist_create();
3655 if (!g_deviceStateList)
3657 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3659 g_deviceStateList = u_arraylist_create();
3664 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3666 g_deviceList = u_arraylist_create();
3671 * Check Sent Count for remove g_sendBuffer
3673 void CALEClientUpdateSendCnt(JNIEnv *env)
3675 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3677 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3679 ca_mutex_lock(g_threadMutex);
3683 if (g_targetCnt <= g_currentSentCnt)
3686 g_currentSentCnt = 0;
3690 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3691 g_sendBuffer = NULL;
3693 // notity the thread
3694 ca_cond_signal(g_threadCond);
3696 CALEClientSetSendFinishFlag(true);
3697 OIC_LOG(DEBUG, TAG, "set signal for send data");
3700 ca_mutex_unlock(g_threadMutex);
3703 CAResult_t CALEClientInitGattMutexVaraibles()
3705 if (NULL == g_bleReqRespClientCbMutex)
3707 g_bleReqRespClientCbMutex = ca_mutex_new();
3708 if (NULL == g_bleReqRespClientCbMutex)
3710 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3711 return CA_STATUS_FAILED;
3715 if (NULL == g_bleServerBDAddressMutex)
3717 g_bleServerBDAddressMutex = ca_mutex_new();
3718 if (NULL == g_bleServerBDAddressMutex)
3720 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3721 return CA_STATUS_FAILED;
3725 if (NULL == g_threadMutex)
3727 g_threadMutex = ca_mutex_new();
3728 if (NULL == g_threadMutex)
3730 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3731 return CA_STATUS_FAILED;
3735 if (NULL == g_threadSendMutex)
3737 g_threadSendMutex = ca_mutex_new();
3738 if (NULL == g_threadSendMutex)
3740 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3741 return CA_STATUS_FAILED;
3745 if (NULL == g_deviceListMutex)
3747 g_deviceListMutex = ca_mutex_new();
3748 if (NULL == g_deviceListMutex)
3750 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3751 return CA_STATUS_FAILED;
3755 if (NULL == g_gattObjectMutex)
3757 g_gattObjectMutex = ca_mutex_new();
3758 if (NULL == g_gattObjectMutex)
3760 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3761 return CA_STATUS_FAILED;
3765 if (NULL == g_deviceStateListMutex)
3767 g_deviceStateListMutex = ca_mutex_new();
3768 if (NULL == g_deviceStateListMutex)
3770 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3771 return CA_STATUS_FAILED;
3775 if (NULL == g_SendFinishMutex)
3777 g_SendFinishMutex = ca_mutex_new();
3778 if (NULL == g_SendFinishMutex)
3780 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3781 return CA_STATUS_FAILED;
3785 if (NULL == g_scanMutex)
3787 g_scanMutex = ca_mutex_new();
3788 if (NULL == g_scanMutex)
3790 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3791 return CA_STATUS_FAILED;
3795 if (NULL == g_threadWriteCharacteristicMutex)
3797 g_threadWriteCharacteristicMutex = ca_mutex_new();
3798 if (NULL == g_threadWriteCharacteristicMutex)
3800 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3801 return CA_STATUS_FAILED;
3805 return CA_STATUS_OK;
3808 void CALEClientTerminateGattMutexVariables()
3810 ca_mutex_free(g_bleReqRespClientCbMutex);
3811 g_bleReqRespClientCbMutex = NULL;
3813 ca_mutex_free(g_bleServerBDAddressMutex);
3814 g_bleServerBDAddressMutex = NULL;
3816 ca_mutex_free(g_threadMutex);
3817 g_threadMutex = NULL;
3819 ca_mutex_free(g_threadSendMutex);
3820 g_threadSendMutex = NULL;
3822 ca_mutex_free(g_deviceListMutex);
3823 g_deviceListMutex = NULL;
3825 ca_mutex_free(g_SendFinishMutex);
3826 g_SendFinishMutex = NULL;
3828 ca_mutex_free(g_scanMutex);
3831 ca_mutex_free(g_threadWriteCharacteristicMutex);
3832 g_threadWriteCharacteristicMutex = NULL;
3835 void CALEClientSetSendFinishFlag(bool flag)
3837 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3839 ca_mutex_lock(g_SendFinishMutex);
3840 g_isFinishedSendData = flag;
3841 ca_mutex_unlock(g_SendFinishMutex);
3848 CAResult_t CAStartLEGattClient()
3850 CAResult_t res = CALEClientStartMulticastServer();
3851 if (CA_STATUS_OK != res)
3853 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3857 g_isStartedLEClient = true;
3863 void CAStopLEGattClient()
3865 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3869 OIC_LOG(ERROR, TAG, "g_jvm is null");
3873 bool isAttached = false;
3875 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3878 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3879 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3883 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3889 CAResult_t ret = CALEClientDisconnectAll(env);
3890 if (CA_STATUS_OK != ret)
3892 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3895 ret = CALEClientStopScan();
3896 if(CA_STATUS_OK != ret)
3898 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3901 ca_mutex_lock(g_threadMutex);
3902 ca_cond_signal(g_threadCond);
3903 ca_mutex_unlock(g_threadMutex);
3905 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3906 ca_cond_signal(g_threadWriteCharacteristicCond);
3907 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3911 (*g_jvm)->DetachCurrentThread(g_jvm);
3916 CAResult_t CAInitializeLEGattClient()
3918 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3919 CALEClientInitialize();
3920 return CA_STATUS_OK;
3923 void CATerminateLEGattClient()
3925 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3926 CAStopLEGattClient();
3927 CALEClientTerminate();
3930 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3931 uint32_t dataLen, CALETransferType_t type,
3934 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3935 VERIFY_NON_NULL(data, TAG, "data is null");
3936 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3938 if (LE_UNICAST != type || position < 0)
3940 OIC_LOG(ERROR, TAG, "this request is not unicast");
3941 return CA_STATUS_INVALID_PARAM;
3944 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3947 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3949 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3950 VERIFY_NON_NULL(data, TAG, "data is null");
3952 return CALEClientSendMulticastMessage(data, dataLen);
3955 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3957 ca_mutex_lock(g_bleReqRespClientCbMutex);
3958 g_CABLEClientDataReceivedCallback = callback;
3959 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3962 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3964 g_threadPoolHandle = handle;
3967 CAResult_t CAGetLEAddress(char **local_address)
3969 VERIFY_NON_NULL(local_address, TAG, "local_address");
3970 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3971 return CA_NOT_SUPPORTED;
3974 JNIEXPORT void JNICALL
3975 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3978 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3979 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3980 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3981 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3983 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3986 JNIEXPORT void JNICALL
3987 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3990 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3991 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3992 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3993 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3995 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3998 JNIEXPORT void JNICALL
3999 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4002 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4003 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4004 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4006 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4007 if (CA_STATUS_OK != res)
4009 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4013 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4015 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4017 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4018 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4020 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
4021 if (!jni_cid_gattdevice_list)
4023 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
4027 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
4028 METHODID_BT_DEVICE);
4029 if (!jni_mid_getDevice)
4031 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4035 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4036 if (!jni_obj_device)
4038 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4042 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4045 OIC_LOG(ERROR, TAG, "jni_address is null");
4049 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4054 * Class: org_iotivity_ca_jar_caleinterface
4055 * Method: CALeGattConnectionStateChangeCallback
4056 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4058 JNIEXPORT void JNICALL
4059 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4065 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4067 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4068 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4069 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4071 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4072 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4073 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4075 if (gatt_success == status && state_connected == newstate) // le connected
4077 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4083 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4086 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4087 STATE_CHARACTER_NO_CHANGE,
4089 if (CA_STATUS_OK != res)
4091 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4092 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4095 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4097 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4100 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4101 if (CA_STATUS_OK != res)
4103 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4107 res = CALEClientDiscoverServices(env, gatt);
4108 if (CA_STATUS_OK != res)
4110 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4114 else if (state_disconnected == newstate) // le disconnected
4116 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4119 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4123 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4126 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4127 STATE_CHARACTER_UNSET,
4129 if (CA_STATUS_OK != res)
4131 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4132 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4135 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4137 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4140 CAResult_t res = CALEClientGattClose(env, gatt);
4141 if (CA_STATUS_OK != res)
4143 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4146 if (gatt_success == status)
4148 // that state is a general reason to disconnect BLE.
4149 // its means manual disconnected message from BT platform.
4150 // in this case Scanning has to start again and clean previous data.
4151 CAResult_t res = CALEClientStartScan();
4152 if (CA_STATUS_OK != res)
4154 if (CA_ADAPTER_NOT_ENABLED == res)
4156 // scan will be started with start server when adapter is enabled
4157 OIC_LOG(INFO, TAG, "Adapter was disabled");
4161 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4166 else if (GATT_ERROR == status)
4168 // when we get GATT ERROR(0x85), gatt connection can be called again.
4169 OIC_LOG(INFO, TAG, "retry gatt connect");
4171 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4174 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4178 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4181 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4185 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4188 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4196 if (CALECheckConnectionStateValue(status))
4198 // this state is unexpected reason to disconnect
4199 // if the reason is suitable, connection logic of the device will be destroyed.
4200 OIC_LOG(INFO, TAG, "connection logic destroy");
4205 // other reason is expected to running background connection in BT platform.
4206 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4207 CALEClientUpdateSendCnt(env);
4214 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4215 g_sendBuffer = NULL;
4223 CALEClientSendFinish(env, gatt);
4228 * Class: org_iotivity_ca_jar_caleinterface
4229 * Method: CALeGattServicesDiscoveredCallback
4230 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4232 JNIEXPORT void JNICALL
4233 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4238 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4239 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4240 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4241 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4243 if (0 != status) // discovery error
4245 CALEClientSendFinish(env, gatt);
4249 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4252 CALEClientSendFinish(env, gatt);
4256 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4259 CALEClientSendFinish(env, gatt);
4263 if (!CALEClientIsSetCharacteristic(address))
4265 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4268 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4272 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4273 if (!jni_obj_GattCharacteristic)
4275 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4279 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4280 jni_obj_GattCharacteristic);
4281 if (CA_STATUS_OK != res)
4283 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4287 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4288 if (CA_STATUS_OK != res)
4290 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4293 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4294 if (CA_STATUS_OK != res)
4296 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4302 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4304 if (CA_STATUS_OK != res)
4306 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4314 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4315 if (CA_STATUS_OK != res)
4317 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4322 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4323 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4328 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4329 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4330 CALEClientSendFinish(env, gatt);
4335 * Class: org_iotivity_ca_jar_caleinterface
4336 * Method: CALeGattCharacteristicWritjclasseCallback
4337 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4339 JNIEXPORT void JNICALL
4340 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4341 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4344 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4345 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4346 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4347 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4349 // send success & signal
4350 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4356 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4362 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4363 if (gatt_success != status) // error case
4365 OIC_LOG(ERROR, TAG, "send failure");
4368 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4369 if (CA_STATUS_OK != res)
4371 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4372 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4373 g_isSignalSetFlag = true;
4374 ca_cond_signal(g_threadWriteCharacteristicCond);
4375 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4377 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4378 STATE_CHARACTER_SET,
4380 if (CA_STATUS_OK != res)
4382 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4385 if (g_clientErrorCallback)
4387 jint length = (*env)->GetArrayLength(env, data);
4388 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4391 CALEClientSendFinish(env, gatt);
4397 OIC_LOG(DEBUG, TAG, "send success");
4398 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4399 STATE_SEND_SUCCESS);
4400 if (CA_STATUS_OK != res)
4402 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4405 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4406 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4407 g_isSignalSetFlag = true;
4408 ca_cond_signal(g_threadWriteCharacteristicCond);
4409 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4411 CALEClientUpdateSendCnt(env);
4414 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4420 CALEClientSendFinish(env, gatt);
4425 * Class: org_iotivity_ca_jar_caleinterface
4426 * Method: CALeGattCharacteristicChangedCallback
4427 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4429 JNIEXPORT void JNICALL
4430 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4431 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4433 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4434 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4435 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4436 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4437 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4439 // get Byte Array and convert to uint8_t*
4440 jint length = (*env)->GetArrayLength(env, data);
4443 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4445 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4446 jni_byte_responseData);
4448 uint8_t* receivedData = OICMalloc(length);
4451 OIC_LOG(ERROR, TAG, "receivedData is null");
4455 memcpy(receivedData, jni_byte_responseData, length);
4456 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4458 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4461 OIC_LOG(ERROR, TAG, "jni_address is null");
4462 OICFree(receivedData);
4466 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4469 OIC_LOG(ERROR, TAG, "address is null");
4470 OICFree(receivedData);
4474 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4475 receivedData, length);
4477 ca_mutex_lock(g_bleServerBDAddressMutex);
4478 uint32_t sentLength = 0;
4479 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4481 ca_mutex_unlock(g_bleServerBDAddressMutex);
4483 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4487 * Class: org_iotivity_ca_jar_caleinterface
4488 * Method: CALeGattDescriptorWriteCallback
4489 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4491 JNIEXPORT void JNICALL
4492 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4496 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4497 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4498 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4499 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4501 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4502 if (gatt_success != status) // error
4509 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4510 if (CA_STATUS_OK != res)
4512 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4521 CALEClientSendFinish(env, gatt);