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_isStartedScan = false;
73 static jbyteArray g_sendBuffer = NULL;
74 static uint32_t g_targetCnt = 0;
75 static uint32_t g_currentSentCnt = 0;
76 static bool g_isFinishedSendData = false;
77 static ca_mutex g_SendFinishMutex = NULL;
78 static ca_mutex g_threadMutex = NULL;
79 static ca_cond g_threadCond = NULL;
80 static ca_cond g_deviceDescCond = NULL;
82 static ca_mutex g_threadSendMutex = NULL;
83 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
84 static ca_cond g_threadWriteCharacteristicCond = NULL;
85 static bool g_isSignalSetFlag = false;
87 static ca_mutex g_bleReqRespClientCbMutex = NULL;
88 static ca_mutex g_bleServerBDAddressMutex = NULL;
90 static ca_mutex g_deviceListMutex = NULL;
91 static ca_mutex g_gattObjectMutex = NULL;
92 static ca_mutex g_deviceStateListMutex = NULL;
94 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
95 static ca_cond g_deviceScanRetryDelayCond = NULL;
97 static ca_mutex g_scanMutex = NULL;
98 static ca_mutex g_threadSendStateMutex = NULL;
100 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
103 * check if retry logic for connection routine has to be stopped or not.
104 * in case of error value including this method, connection routine has to be stopped.
105 * since there is no retry logic for this error reason in this client.
106 * @param state constant value of bluetoothgatt.
107 * @return true - waiting for background connection in BT platform.
108 * false - connection routine has to be stopped.
110 static bool CALECheckConnectionStateValue(jint state)
114 case GATT_CONNECTION_PRIORITY_BALANCED:
116 case GATT_INSUFFICIENT_AUTHENTICATION:
117 case GATT_INSUFFICIENT_ENCRYPTION:
118 case GATT_INVALID_ATTRIBUTE_LENGTH:
119 case GATT_INVALID_OFFSET:
120 case GATT_READ_NOT_PERMITTED:
121 case GATT_REQUEST_NOT_SUPPORTED:
122 case GATT_WRITE_NOT_PERMITTED:
129 void CALEClientJniInit()
131 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
132 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
135 void CALEClientJNISetContext()
137 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
138 g_context = (jobject) CANativeJNIGetContext();
141 CAResult_t CALECreateJniInterfaceObject()
143 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
147 OIC_LOG(ERROR, TAG, "g_context is null");
148 return CA_STATUS_FAILED;
153 OIC_LOG(ERROR, TAG, "g_jvm is null");
154 return CA_STATUS_FAILED;
157 bool isAttached = false;
159 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
162 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
163 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
167 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
168 return CA_STATUS_FAILED;
173 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
174 "getApplicationContext",
175 "()Landroid/content/Context;");
177 if (!mid_getApplicationContext)
179 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
180 return CA_STATUS_FAILED;
183 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
184 mid_getApplicationContext);
185 if (!jApplicationContext)
187 OIC_LOG(ERROR, TAG, "Could not get application context");
188 return CA_STATUS_FAILED;
191 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
192 if (!jni_LEInterface)
194 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
198 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
199 "(Landroid/content/Context;)V");
200 if (!LeInterfaceConstructorMethod)
202 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
206 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
207 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
211 (*g_jvm)->DetachCurrentThread(g_jvm);
220 (*g_jvm)->DetachCurrentThread(g_jvm);
223 return CA_STATUS_FAILED;
226 CAResult_t CALEClientInitialize()
228 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
234 OIC_LOG(ERROR, TAG, "g_jvm is null");
235 return CA_STATUS_FAILED;
238 bool isAttached = false;
240 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
243 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
244 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
248 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
249 return CA_STATUS_FAILED;
254 CAResult_t ret = CALECheckPlatformVersion(env, 18);
255 if (CA_STATUS_OK != ret)
257 OIC_LOG(ERROR, TAG, "it is not supported");
261 (*g_jvm)->DetachCurrentThread(g_jvm);
267 ret = CALEClientInitGattMutexVaraibles();
268 if (CA_STATUS_OK != ret)
270 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
271 CALEClientTerminateGattMutexVariables();
275 (*g_jvm)->DetachCurrentThread(g_jvm);
281 g_deviceDescCond = ca_cond_new();
283 // init mutex for send logic
284 g_threadCond = ca_cond_new();
285 g_threadWriteCharacteristicCond = ca_cond_new();
286 g_deviceScanRetryDelayCond = ca_cond_new();
288 CALEClientCreateDeviceList();
289 CALEClientJNISetContext();
291 ret = CALEClientCreateUUIDList();
292 if (CA_STATUS_OK != ret)
294 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
298 (*g_jvm)->DetachCurrentThread(g_jvm);
304 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
305 if (CA_STATUS_OK != ret)
307 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
311 (*g_jvm)->DetachCurrentThread(g_jvm);
316 g_isStartedLEClient = true;
320 (*g_jvm)->DetachCurrentThread(g_jvm);
326 void CALEClientTerminate()
328 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
332 OIC_LOG(ERROR, TAG, "g_jvm is null");
336 bool isAttached = false;
338 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
341 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
342 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
346 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
352 if (g_leScanCallback)
354 (*env)->DeleteGlobalRef(env, g_leScanCallback);
355 g_leScanCallback = NULL;
358 if (g_leGattCallback)
360 (*env)->DeleteGlobalRef(env, g_leGattCallback);
361 g_leGattCallback = NULL;
366 (*env)->DeleteGlobalRef(env, g_sendBuffer);
372 (*env)->DeleteGlobalRef(env, g_uuidList);
376 CAResult_t ret = CALEClientRemoveAllDeviceState();
377 if (CA_STATUS_OK != ret)
379 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
382 ret = CALEClientRemoveAllScanDevices(env);
383 if (CA_STATUS_OK != ret)
385 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
388 ret = CALEClientRemoveAllGattObjs(env);
389 if (CA_STATUS_OK != ret)
391 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
394 CALEClientSetScanFlag(false);
395 CALEClientSetSendFinishFlag(true);
397 CALEClientTerminateGattMutexVariables();
398 CALEClientDestroyJniInterface();
400 ca_cond_free(g_deviceDescCond);
401 ca_cond_free(g_threadCond);
402 ca_cond_free(g_threadWriteCharacteristicCond);
403 ca_cond_free(g_deviceScanRetryDelayCond);
405 g_deviceDescCond = NULL;
407 g_threadWriteCharacteristicCond = NULL;
408 g_deviceScanRetryDelayCond = NULL;
410 g_isSignalSetFlag = false;
414 (*g_jvm)->DetachCurrentThread(g_jvm);
418 CAResult_t CALEClientDestroyJniInterface()
420 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
424 OIC_LOG(ERROR, TAG, "g_jvm is null");
425 return CA_STATUS_FAILED;
428 bool isAttached = false;
430 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
433 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
434 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
438 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
439 return CA_STATUS_FAILED;
444 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
445 if (!jni_LeInterface)
447 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
451 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
452 "destroyLeInterface",
454 if (!jni_InterfaceDestroyMethod)
456 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
460 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
462 if ((*env)->ExceptionCheck(env))
464 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
465 (*env)->ExceptionDescribe(env);
466 (*env)->ExceptionClear(env);
470 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
474 (*g_jvm)->DetachCurrentThread(g_jvm);
483 (*g_jvm)->DetachCurrentThread(g_jvm);
486 return CA_STATUS_FAILED;
489 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
491 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
492 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
496 CAResult_t res = CALEClientDisconnect(env, gatt);
497 if (CA_STATUS_OK != res)
499 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
502 CALEClientUpdateSendCnt(env);
505 CAResult_t CALEClientSendUnicastMessage(const char* address,
507 const uint32_t dataLen)
509 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
510 VERIFY_NON_NULL(address, TAG, "address is null");
511 VERIFY_NON_NULL(data, TAG, "data is null");
513 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
516 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
517 const uint32_t dataLen)
519 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
520 VERIFY_NON_NULL(data, TAG, "data is null");
524 OIC_LOG(ERROR, TAG, "g_jvm is null");
525 return CA_STATUS_FAILED;
528 bool isAttached = false;
530 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
533 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
534 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
538 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
539 return CA_STATUS_FAILED;
544 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
545 if (CA_STATUS_OK != ret)
547 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
552 (*g_jvm)->DetachCurrentThread(g_jvm);
558 CAResult_t CALEClientStartUnicastServer(const char* address)
560 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
562 return CA_NOT_SUPPORTED;
565 CAResult_t CALEClientStartMulticastServer()
567 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
569 return CA_NOT_SUPPORTED;
572 void CALEClientStopUnicastServer()
574 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
577 void CALEClientStopMulticastServer()
579 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
582 void CALEClientSetCallback(CAPacketReceiveCallback callback)
584 g_packetReceiveCallback = callback;
587 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
589 g_clientErrorCallback = callback;
592 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
594 VERIFY_NON_NULL(env, TAG, "env");
598 return CA_STATUS_FAILED;
601 if (0 == u_arraylist_length(g_deviceList) // multicast
602 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
604 // Wait for LE peripherals to be discovered.
606 // Number of times to wait for discovery to complete.
607 static size_t const RETRIES = 5;
609 static uint64_t const TIMEOUT =
610 2 * MICROSECS_PER_SEC; // Microseconds
612 bool devicesDiscovered = false;
613 for (size_t i = 0; i < RETRIES; ++i)
615 OIC_LOG(DEBUG, TAG, "waiting for target device");
616 if (ca_cond_wait_for(g_deviceDescCond,
618 TIMEOUT) == CA_WAIT_SUCCESS)
620 ca_mutex_lock(g_deviceListMutex);
621 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
622 ca_mutex_unlock(g_deviceListMutex);
624 if (0 < scannedDeviceLen)
626 if (!address // multicast
627 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
629 devicesDiscovered = true;
636 OIC_LOG(INFO, TAG, "waiting..");
638 ca_mutex_lock(g_deviceScanRetryDelayMutex);
639 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
640 g_deviceScanRetryDelayMutex,
641 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
643 OIC_LOG(INFO, TAG, "finish to waiting for target device");
644 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
647 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
650 // checking whether a target device is found while waiting for time-out.
651 if (CALEClientIsDeviceInScanDeviceList(env, address))
653 devicesDiscovered = true;
662 // time out for scanning devices
663 if (!devicesDiscovered)
665 return CA_STATUS_FAILED;
673 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
674 const uint32_t dataLen)
676 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
678 VERIFY_NON_NULL(address, TAG, "address is null");
679 VERIFY_NON_NULL(data, TAG, "data is null");
683 OIC_LOG(ERROR, TAG, "g_jvm is null");
684 return CA_STATUS_FAILED;
687 bool isAttached = false;
689 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
692 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
693 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
696 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
697 return CA_STATUS_FAILED;
702 ca_mutex_lock(g_threadSendMutex);
704 CALEClientSetSendFinishFlag(false);
706 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
707 if (CA_STATUS_OK != ret)
709 OIC_LOG(INFO, TAG, "there is no scanned device");
713 if (g_context && g_deviceList)
715 uint32_t length = u_arraylist_length(g_deviceList);
716 for (uint32_t index = 0; index < length; index++)
718 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
721 OIC_LOG(ERROR, TAG, "jarrayObj is null");
725 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
728 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
732 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
735 OIC_LOG(ERROR, TAG, "setAddress is null");
739 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
741 if (!strcmp(setAddress, address))
743 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
744 (*env)->DeleteLocalRef(env, jni_setAddress);
746 // connect to gatt server
747 ret = CALEClientStopScan();
748 if (CA_STATUS_OK != ret)
750 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
756 (*env)->DeleteGlobalRef(env, g_sendBuffer);
759 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
760 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
761 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
763 // Target device to send message is just one.
766 ret = CALEClientSendData(env, jarrayObj);
767 if (CA_STATUS_OK != ret)
769 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
773 OIC_LOG(INFO, TAG, "wake up");
776 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
777 (*env)->DeleteLocalRef(env, jni_setAddress);
781 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
783 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
784 // if there is no connection state.
785 ca_mutex_lock(g_threadMutex);
786 if (!g_isFinishedSendData)
788 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
789 ca_cond_wait(g_threadCond, g_threadMutex);
790 OIC_LOG(DEBUG, TAG, "the data was sent");
792 ca_mutex_unlock(g_threadMutex);
796 (*g_jvm)->DetachCurrentThread(g_jvm);
799 // start LE Scan again
800 ret = CALEClientStartScan();
801 if (CA_STATUS_OK != ret)
803 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
804 ca_mutex_unlock(g_threadSendMutex);
808 ca_mutex_unlock(g_threadSendMutex);
809 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
810 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
817 ret = CA_SEND_FAILED;
821 ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
823 if (CA_STATUS_OK != ret)
825 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
833 // start LE Scan again
834 ret = CALEClientStartScan();
835 if (CA_STATUS_OK != ret)
837 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
838 ca_mutex_unlock(g_threadSendMutex);
841 (*g_jvm)->DetachCurrentThread(g_jvm);
848 (*g_jvm)->DetachCurrentThread(g_jvm);
851 ca_mutex_unlock(g_threadSendMutex);
852 return CA_SEND_FAILED;
855 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
856 const uint32_t dataLen)
858 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
859 VERIFY_NON_NULL(data, TAG, "data is null");
860 VERIFY_NON_NULL(env, TAG, "env is null");
864 OIC_LOG(ERROR, TAG, "g_deviceList is null");
865 return CA_STATUS_FAILED;
868 ca_mutex_lock(g_threadSendMutex);
870 CALEClientSetSendFinishFlag(false);
872 OIC_LOG(DEBUG, TAG, "set byteArray for data");
875 (*env)->DeleteGlobalRef(env, g_sendBuffer);
879 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
880 if (CA_STATUS_OK != res)
882 OIC_LOG(INFO, TAG, "there is no scanned device");
886 // connect to gatt server
887 res = CALEClientStopScan();
888 if (CA_STATUS_OK != res)
890 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
891 ca_mutex_unlock(g_threadSendMutex);
894 uint32_t length = u_arraylist_length(g_deviceList);
895 g_targetCnt = length;
897 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
898 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
899 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
901 for (uint32_t index = 0; index < length; index++)
903 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
906 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
910 res = CALEClientSendData(env, jarrayObj);
911 if (res != CA_STATUS_OK)
913 OIC_LOG(ERROR, TAG, "BT device - send has failed");
917 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
919 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
920 ca_mutex_lock(g_threadMutex);
921 if (!g_isFinishedSendData)
923 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
924 ca_cond_wait(g_threadCond, g_threadMutex);
925 OIC_LOG(DEBUG, TAG, "the data was sent");
927 ca_mutex_unlock(g_threadMutex);
929 // start LE Scan again
930 res = CALEClientStartScan();
931 if (CA_STATUS_OK != res)
933 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
934 ca_mutex_unlock(g_threadSendMutex);
938 ca_mutex_unlock(g_threadSendMutex);
939 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
943 res = CALEClientStartScan();
944 if (CA_STATUS_OK != res)
946 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
947 ca_mutex_unlock(g_threadSendMutex);
951 ca_mutex_unlock(g_threadSendMutex);
952 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
953 return CA_SEND_FAILED;
956 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
958 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
959 VERIFY_NON_NULL(device, TAG, "device is null");
960 VERIFY_NON_NULL(env, TAG, "env is null");
962 // get BLE address from bluetooth device object.
963 char* address = NULL;
964 CALEState_t* state = NULL;
965 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
968 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
969 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
972 OIC_LOG(ERROR, TAG, "address is not available");
973 return CA_STATUS_FAILED;
975 ca_mutex_lock(g_deviceStateListMutex);
976 state = CALEClientGetStateInfo(address);
977 ca_mutex_unlock(g_deviceStateListMutex);
982 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
984 // cancel previous connection request before connection
985 // if there is gatt object in g_gattObjectList.
988 jobject gatt = CALEClientGetGattObjInList(env, address);
991 CAResult_t res = CALEClientDisconnect(env, gatt);
992 if (CA_STATUS_OK != res)
994 OIC_LOG(INFO, TAG, "there is no gatt object");
997 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1000 // connection request
1001 jobject newGatt = CALEClientConnect(env, device,
1003 if (NULL == newGatt)
1005 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1006 return CA_STATUS_FAILED;
1011 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1012 STATE_SERVICE_CONNECTED))
1014 OIC_LOG(INFO, TAG, "GATT has already connected");
1016 jobject gatt = CALEClientGetGattObjInList(env, address);
1019 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1020 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1021 return CA_STATUS_FAILED;
1024 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1025 if (CA_STATUS_OK != ret)
1027 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1028 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1031 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1033 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1036 OIC_LOG(INFO, TAG, "service connecting...");
1038 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1039 STATE_DISCONNECTED))
1041 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1043 // cancel previous connection request before connection
1044 // if there is gatt object in g_gattObjectList.
1047 jobject gatt = CALEClientGetGattObjInList(env, address);
1050 CAResult_t res = CALEClientDisconnect(env, gatt);
1051 if (CA_STATUS_OK != res)
1053 OIC_LOG(INFO, TAG, "there is no gatt object");
1056 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1059 OIC_LOG(DEBUG, TAG, "start to connect LE");
1060 jobject gatt = CALEClientConnect(env, device,
1061 CALEClientGetFlagFromState(env, jni_address,
1062 CA_LE_AUTO_CONNECT_FLAG));
1066 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1067 return CA_STATUS_FAILED;
1072 return CA_STATUS_OK;
1075 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1077 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1078 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1080 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1081 "()Landroid/bluetooth/BluetoothDevice;");
1082 if (!jni_mid_getDevice)
1084 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1088 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1089 if (!jni_obj_device)
1091 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1095 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1098 OIC_LOG(ERROR, TAG, "jni_address is null");
1108 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1111 OIC_LOG(DEBUG, TAG, "Gatt Close");
1112 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1113 VERIFY_NON_NULL(env, TAG, "env is null");
1115 // get BluetoothGatt method
1116 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1117 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1118 if (!jni_mid_closeGatt)
1120 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1121 return CA_STATUS_OK;
1124 // call disconnect gatt method
1125 OIC_LOG(DEBUG, TAG, "request to close GATT");
1126 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1128 if ((*env)->ExceptionCheck(env))
1130 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1131 (*env)->ExceptionDescribe(env);
1132 (*env)->ExceptionClear(env);
1133 return CA_STATUS_FAILED;
1136 return CA_STATUS_OK;
1139 CAResult_t CALEClientStartScan()
1141 if (!g_isStartedLEClient)
1143 OIC_LOG(ERROR, TAG, "LE client is not started");
1144 return CA_STATUS_FAILED;
1149 OIC_LOG(ERROR, TAG, "g_jvm is null");
1150 return CA_STATUS_FAILED;
1153 if (g_isStartedScan)
1155 OIC_LOG(INFO, TAG, "scanning is already started");
1156 return CA_STATUS_OK;
1159 bool isAttached = false;
1161 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1164 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1166 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1169 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1170 return CA_STATUS_FAILED;
1175 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1177 CAResult_t ret = CA_STATUS_OK;
1178 // scan gatt server with UUID
1179 if (g_leScanCallback && g_uuidList)
1182 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1184 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1186 if (CA_STATUS_OK != ret)
1188 if (CA_ADAPTER_NOT_ENABLED == ret)
1190 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1194 OIC_LOG(ERROR, TAG, "start scan has failed");
1201 (*g_jvm)->DetachCurrentThread(g_jvm);
1207 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1209 VERIFY_NON_NULL(callback, TAG, "callback is null");
1210 VERIFY_NON_NULL(env, TAG, "env is null");
1212 if (!CALEIsEnableBTAdapter(env))
1214 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1215 return CA_ADAPTER_NOT_ENABLED;
1218 // get default bt adapter class
1219 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1220 if (!jni_cid_BTAdapter)
1222 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1223 return CA_STATUS_FAILED;
1226 // get remote bt adapter method
1227 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1228 "getDefaultAdapter",
1229 METHODID_OBJECTNONPARAM);
1230 if (!jni_mid_getDefaultAdapter)
1232 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1233 return CA_STATUS_FAILED;
1236 // get start le scan method
1237 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1238 "(Landroid/bluetooth/BluetoothAdapter$"
1239 "LeScanCallback;)Z");
1240 if (!jni_mid_startLeScan)
1242 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1243 return CA_STATUS_FAILED;
1246 // gat bt adapter object
1247 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1248 jni_mid_getDefaultAdapter);
1249 if (!jni_obj_BTAdapter)
1251 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1252 return CA_STATUS_FAILED;
1255 // call start le scan method
1256 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1257 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1258 jni_mid_startLeScan, callback);
1259 if (!jni_obj_startLeScan)
1261 OIC_LOG(INFO, TAG, "startLeScan has failed");
1265 OIC_LOG(DEBUG, TAG, "LeScan has started");
1266 CALEClientSetScanFlag(true);
1269 return CA_STATUS_OK;
1272 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1274 VERIFY_NON_NULL(callback, TAG, "callback is null");
1275 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1276 VERIFY_NON_NULL(env, TAG, "env is null");
1278 if (!CALEIsEnableBTAdapter(env))
1280 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1281 return CA_ADAPTER_NOT_ENABLED;
1284 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1285 if (!jni_cid_BTAdapter)
1287 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1288 return CA_STATUS_FAILED;
1291 // get remote bt adapter method
1292 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1293 "getDefaultAdapter",
1294 METHODID_OBJECTNONPARAM);
1295 if (!jni_mid_getDefaultAdapter)
1297 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1298 return CA_STATUS_FAILED;
1301 // get start le scan method
1302 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1303 "([Ljava/util/UUID;Landroid/bluetooth/"
1304 "BluetoothAdapter$LeScanCallback;)Z");
1305 if (!jni_mid_startLeScan)
1307 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1308 return CA_STATUS_FAILED;
1311 // get bt adapter object
1312 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1313 jni_mid_getDefaultAdapter);
1314 if (!jni_obj_BTAdapter)
1316 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1317 return CA_STATUS_FAILED;
1320 // call start le scan method
1321 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1322 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1323 jni_mid_startLeScan, uuids, callback);
1324 if (!jni_obj_startLeScan)
1326 OIC_LOG(INFO, TAG, "startLeScan has failed");
1330 OIC_LOG(DEBUG, TAG, "LeScan has started");
1331 CALEClientSetScanFlag(true);
1334 return CA_STATUS_OK;
1337 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1339 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1340 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1343 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1346 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1350 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1351 "(Ljava/lang/String;)"
1352 "Ljava/util/UUID;");
1353 if (!jni_mid_fromString)
1355 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1359 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1360 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1364 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1368 return jni_obj_uuid;
1371 CAResult_t CALEClientStopScan()
1375 OIC_LOG(ERROR, TAG, "g_jvm is null");
1376 return CA_STATUS_FAILED;
1379 if (!g_isStartedScan)
1381 OIC_LOG(INFO, TAG, "scanning is already stopped");
1382 return CA_STATUS_OK;
1385 bool isAttached = false;
1387 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1390 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1391 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1394 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1395 return CA_STATUS_FAILED;
1400 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1401 if (CA_STATUS_OK != ret)
1403 if (CA_ADAPTER_NOT_ENABLED == ret)
1405 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1409 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1414 CALEClientSetScanFlag(false);
1419 (*g_jvm)->DetachCurrentThread(g_jvm);
1425 void CALEClientSetScanFlag(bool flag)
1427 ca_mutex_lock(g_scanMutex);
1428 g_isStartedScan = flag;
1429 ca_mutex_unlock(g_scanMutex);
1432 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1434 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1435 VERIFY_NON_NULL(callback, TAG, "callback is null");
1436 VERIFY_NON_NULL(env, TAG, "env is null");
1438 if (!CALEIsEnableBTAdapter(env))
1440 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1441 return CA_ADAPTER_NOT_ENABLED;
1444 // get default bt adapter class
1445 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1446 if (!jni_cid_BTAdapter)
1448 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1449 return CA_STATUS_FAILED;
1452 // get remote bt adapter method
1453 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1454 "getDefaultAdapter",
1455 METHODID_OBJECTNONPARAM);
1456 if (!jni_mid_getDefaultAdapter)
1458 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1459 return CA_STATUS_FAILED;
1462 // get start le scan method
1463 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1464 "(Landroid/bluetooth/"
1465 "BluetoothAdapter$LeScanCallback;)V");
1466 if (!jni_mid_stopLeScan)
1468 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1469 return CA_STATUS_FAILED;
1472 // gat bt adapter object
1473 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1474 jni_mid_getDefaultAdapter);
1475 if (!jni_obj_BTAdapter)
1477 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1478 return CA_STATUS_FAILED;
1481 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1482 // call start le scan method
1483 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1484 if ((*env)->ExceptionCheck(env))
1486 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1487 (*env)->ExceptionDescribe(env);
1488 (*env)->ExceptionClear(env);
1489 return CA_STATUS_FAILED;
1492 return CA_STATUS_OK;
1495 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1497 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1498 VERIFY_NON_NULL(env, TAG, "env");
1499 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1501 ca_mutex_lock(g_deviceStateListMutex);
1503 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1506 OIC_LOG(ERROR, TAG, "address is not available");
1507 return CA_STATUS_FAILED;
1510 if (CALEClientIsDeviceInList(address))
1512 CALEState_t* curState = CALEClientGetStateInfo(address);
1515 OIC_LOG(ERROR, TAG, "curState is null");
1516 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1517 ca_mutex_unlock(g_deviceStateListMutex);
1518 return CA_STATUS_FAILED;
1520 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1524 case CA_LE_AUTO_CONNECT_FLAG:
1525 curState->autoConnectFlag = flag;
1527 case CA_LE_DESCRIPTOR_FOUND:
1528 curState->isDescriptorFound = flag;
1535 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1536 ca_mutex_unlock(g_deviceStateListMutex);
1537 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1538 return CA_STATUS_OK;
1541 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1543 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1544 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1545 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1547 ca_mutex_lock(g_deviceStateListMutex);
1549 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1552 OIC_LOG(ERROR, TAG, "address is not available");
1553 ca_mutex_unlock(g_deviceStateListMutex);
1557 CALEState_t* curState = CALEClientGetStateInfo(address);
1558 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1561 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1562 ca_mutex_unlock(g_deviceStateListMutex);
1566 jboolean ret = JNI_FALSE;
1569 case CA_LE_AUTO_CONNECT_FLAG:
1570 ret = curState->autoConnectFlag;
1572 case CA_LE_DESCRIPTOR_FOUND:
1573 ret = curState->isDescriptorFound;
1578 ca_mutex_unlock(g_deviceStateListMutex);
1580 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1581 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1585 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1587 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1588 VERIFY_NON_NULL(env, TAG, "env is null");
1589 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1591 ca_mutex_lock(g_threadSendMutex);
1593 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1596 OIC_LOG(ERROR, TAG, "jni_address is not available");
1597 ca_mutex_unlock(g_threadSendMutex);
1598 return CA_STATUS_FAILED;
1601 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1604 OIC_LOG(ERROR, TAG, "address is not available");
1605 ca_mutex_unlock(g_threadSendMutex);
1606 return CA_STATUS_FAILED;
1609 CAResult_t res = CA_STATUS_OK;
1610 if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1611 STATE_DISCONNECTED))
1613 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1614 if (NULL == newGatt)
1616 OIC_LOG(INFO, TAG, "newGatt is not available");
1617 res = CA_STATUS_FAILED;
1620 ca_mutex_unlock(g_threadSendMutex);
1625 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1627 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1628 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1629 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1631 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1632 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1635 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1638 OIC_LOG(ERROR, TAG, "address is not available");
1642 // close the gatt service
1643 jobject gatt = CALEClientGetGattObjInList(env, address);
1646 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1647 if (CA_STATUS_OK != res)
1649 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1650 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1654 // clean previous gatt object after close profile service
1655 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1656 if (CA_STATUS_OK != res)
1658 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1659 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1663 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1666 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1669 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1673 // add new gatt object into g_gattObjectList
1674 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1675 if (CA_STATUS_OK != res)
1677 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1684 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1686 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1687 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1688 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1690 if (!g_leGattCallback)
1692 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1696 if (!CALEIsEnableBTAdapter(env))
1698 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1702 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1705 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1709 // get BluetoothDevice method
1710 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1711 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1713 "(Landroid/content/Context;ZLandroid/"
1714 "bluetooth/BluetoothGattCallback;)"
1715 "Landroid/bluetooth/BluetoothGatt;");
1716 if (!jni_mid_connectGatt)
1718 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1722 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1723 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1724 jni_mid_connectGatt,
1726 autoconnect, g_leGattCallback);
1727 if (!jni_obj_connectGatt)
1729 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1730 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1731 CALEClientUpdateSendCnt(env);
1736 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1738 return jni_obj_connectGatt;
1741 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1743 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1745 VERIFY_NON_NULL(env, TAG, "env is null");
1746 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1748 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1749 if (!jni_cid_BTAdapter)
1751 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1752 return CA_STATUS_FAILED;
1755 // get remote bt adapter method
1756 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1757 "getDefaultAdapter",
1758 METHODID_OBJECTNONPARAM);
1759 if (!jni_mid_getDefaultAdapter)
1761 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1762 return CA_STATUS_FAILED;
1765 // gat bt adapter object
1766 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1767 jni_mid_getDefaultAdapter);
1768 if (!jni_obj_BTAdapter)
1770 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1771 return CA_STATUS_FAILED;
1774 // get closeProfileProxy method
1775 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1776 "closeProfileProxy",
1777 "(ILandroid/bluetooth/"
1778 "BluetoothProfile;)V");
1779 if (!jni_mid_closeProfileProxy)
1781 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1782 return CA_STATUS_FAILED;
1785 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1786 if (!jni_cid_BTProfile)
1788 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1789 return CA_STATUS_FAILED;
1792 // GATT - Constant value : 7 (0x00000007)
1793 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1797 OIC_LOG(ERROR, TAG, "id_gatt is null");
1798 return CA_STATUS_FAILED;
1801 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1803 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1804 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1805 if ((*env)->ExceptionCheck(env))
1807 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1808 (*env)->ExceptionDescribe(env);
1809 (*env)->ExceptionClear(env);
1810 return CA_STATUS_FAILED;
1813 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1814 return CA_STATUS_OK;
1818 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1820 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1821 VERIFY_NON_NULL(env, TAG, "env is null");
1822 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1824 // get BluetoothGatt method
1825 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1826 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1827 "disconnect", "()V");
1828 if (!jni_mid_disconnectGatt)
1830 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1831 return CA_STATUS_FAILED;
1834 // call disconnect gatt method
1835 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1836 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1837 if ((*env)->ExceptionCheck(env))
1839 OIC_LOG(ERROR, TAG, "disconnect has failed");
1840 (*env)->ExceptionDescribe(env);
1841 (*env)->ExceptionClear(env);
1842 return CA_STATUS_FAILED;
1845 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1847 return CA_STATUS_OK;
1850 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1852 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1853 VERIFY_NON_NULL(env, TAG, "env is null");
1855 if (!g_gattObjectList)
1857 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1858 return CA_STATUS_OK;
1861 uint32_t length = u_arraylist_length(g_gattObjectList);
1862 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1863 for (uint32_t index = 0; index < length; index++)
1865 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1866 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1869 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1872 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1873 if (CA_STATUS_OK != res)
1875 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1880 return CA_STATUS_OK;
1883 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1885 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1886 VERIFY_NON_NULL(env, TAG, "env is null");
1888 if (!g_gattObjectList)
1890 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1891 return CA_STATUS_OK;
1894 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1897 OIC_LOG(ERROR, TAG, "address is null");
1898 return CA_STATUS_FAILED;
1901 uint32_t length = u_arraylist_length(g_gattObjectList);
1902 for (uint32_t index = 0; index < length; index++)
1904 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1907 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1911 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1912 if (!jni_setAddress)
1914 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1915 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1916 return CA_STATUS_FAILED;
1919 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1922 OIC_LOG(ERROR, TAG, "setAddress is null");
1923 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1924 return CA_STATUS_FAILED;
1927 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1928 if (!strcmp(address, setAddress))
1930 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1931 if (CA_STATUS_OK != res)
1933 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1934 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1935 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1936 return CA_STATUS_FAILED;
1938 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1939 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1940 return CA_STATUS_OK;
1942 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1944 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1946 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1947 return CA_STATUS_OK;
1950 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1952 VERIFY_NON_NULL(env, TAG, "env is null");
1953 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1955 if (!CALEIsEnableBTAdapter(env))
1957 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1958 return CA_ADAPTER_NOT_ENABLED;
1961 // get BluetoothGatt.discoverServices method
1962 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1963 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1964 "discoverServices", "()Z");
1965 if (!jni_mid_discoverServices)
1967 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1968 return CA_STATUS_FAILED;
1971 // call disconnect gatt method
1972 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
1973 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1976 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1977 return CA_STATUS_FAILED;
1980 return CA_STATUS_OK;
1983 static void CALEWriteCharacteristicThread(void* object)
1985 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1987 bool isAttached = false;
1989 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1992 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1993 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1997 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2003 jobject gatt = (jobject)object;
2004 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2005 if (CA_STATUS_OK != ret)
2007 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2012 (*g_jvm)->DetachCurrentThread(g_jvm);
2016 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2018 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2020 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2021 VERIFY_NON_NULL(env, TAG, "env is null");
2023 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2026 CALEClientSendFinish(env, gatt);
2027 return CA_STATUS_FAILED;
2030 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2033 CALEClientSendFinish(env, gatt);
2034 return CA_STATUS_FAILED;
2037 ca_mutex_lock(g_threadSendStateMutex);
2039 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2041 OIC_LOG(INFO, TAG, "current state is SENDING");
2042 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2043 ca_mutex_unlock(g_threadSendStateMutex);
2044 return CA_STATUS_OK;
2047 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2050 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2051 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2052 CALEClientSendFinish(env, gatt);
2053 ca_mutex_unlock(g_threadSendStateMutex);
2054 return CA_STATUS_FAILED;
2057 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2059 ca_mutex_unlock(g_threadSendStateMutex);
2062 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2063 if (!jni_obj_character)
2065 CALEClientSendFinish(env, gatt);
2066 return CA_STATUS_FAILED;
2069 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2070 if (CA_STATUS_OK != ret)
2072 CALEClientSendFinish(env, gatt);
2073 return CA_STATUS_FAILED;
2076 // wait for callback for write Characteristic with success to sent data
2077 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2078 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2079 if (!g_isSignalSetFlag)
2081 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2082 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2083 g_threadWriteCharacteristicMutex,
2084 WAIT_TIME_WRITE_CHARACTERISTIC))
2086 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2087 g_isSignalSetFlag = false;
2088 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2089 return CA_STATUS_FAILED;
2092 // reset flag set by writeCharacteristic Callback
2093 g_isSignalSetFlag = false;
2094 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2096 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2097 return CA_STATUS_OK;
2100 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2102 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2103 VERIFY_NON_NULL(env, TAG, "env is null");
2104 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2106 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2107 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2108 CALEWriteCharacteristicThread, (void*)gattParam))
2110 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2111 return CA_STATUS_FAILED;
2114 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2115 return CA_STATUS_OK;
2118 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2119 jobject gattCharacteristic)
2121 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2122 VERIFY_NON_NULL(env, TAG, "env is null");
2123 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2124 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2126 if (!CALEIsEnableBTAdapter(env))
2128 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2129 return CA_STATUS_FAILED;
2132 // get BluetoothGatt.write characteristic method
2133 OIC_LOG(DEBUG, TAG, "write characteristic method");
2134 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2135 "writeCharacteristic",
2136 "(Landroid/bluetooth/"
2137 "BluetoothGattCharacteristic;)Z");
2138 if (!jni_mid_writeCharacteristic)
2140 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2141 return CA_STATUS_FAILED;
2144 // call disconnect gatt method
2145 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2146 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2147 jni_mid_writeCharacteristic,
2148 gattCharacteristic);
2151 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2155 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2156 return CA_STATUS_FAILED;
2159 return CA_STATUS_OK;
2162 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2164 VERIFY_NON_NULL(env, TAG, "env is null");
2165 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2167 if (!CALEIsEnableBTAdapter(env))
2169 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2170 return CA_STATUS_FAILED;
2173 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2176 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2177 return CA_STATUS_FAILED;
2180 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2181 if (!jni_obj_GattCharacteristic)
2183 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2184 return CA_STATUS_FAILED;
2187 OIC_LOG(DEBUG, TAG, "read characteristic method");
2188 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2189 "readCharacteristic",
2190 "(Landroid/bluetooth/"
2191 "BluetoothGattCharacteristic;)Z");
2192 if (!jni_mid_readCharacteristic)
2194 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2195 return CA_STATUS_FAILED;
2198 // call disconnect gatt method
2199 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2200 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2201 jni_obj_GattCharacteristic);
2204 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2208 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2209 return CA_STATUS_FAILED;
2212 return CA_STATUS_OK;
2215 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2216 jobject characteristic)
2218 VERIFY_NON_NULL(env, TAG, "env is null");
2219 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2220 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2222 if (!CALEIsEnableBTAdapter(env))
2224 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2225 return CA_ADAPTER_NOT_ENABLED;
2228 // get BluetoothGatt.setCharacteristicNotification method
2229 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2230 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2231 "setCharacteristicNotification",
2232 "(Landroid/bluetooth/"
2233 "BluetoothGattCharacteristic;Z)Z");
2234 if (!jni_mid_setNotification)
2236 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2237 return CA_STATUS_FAILED;
2240 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2241 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2242 characteristic, JNI_TRUE);
2243 if (JNI_TRUE == ret)
2245 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2249 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2250 return CA_STATUS_FAILED;
2253 return CA_STATUS_OK;
2256 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2258 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2259 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2260 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2262 if (!CALEIsEnableBTAdapter(env))
2264 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2268 // get BluetoothGatt.getService method
2269 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2270 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2272 "(Ljava/util/UUID;)Landroid/bluetooth/"
2273 "BluetoothGattService;");
2274 if (!jni_mid_getService)
2276 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2280 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2281 if (!jni_obj_service_uuid)
2283 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2287 // get bluetooth gatt service
2288 OIC_LOG(DEBUG, TAG, "request to get service");
2289 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2290 jni_obj_service_uuid);
2291 if (!jni_obj_gattService)
2293 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2297 // get bluetooth gatt service method
2298 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2299 "BluetoothGattService",
2300 "getCharacteristic",
2301 "(Ljava/util/UUID;)"
2302 "Landroid/bluetooth/"
2303 "BluetoothGattCharacteristic;");
2304 if (!jni_mid_getCharacteristic)
2306 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2310 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2313 OIC_LOG(ERROR, TAG, "uuid is null");
2317 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2318 if (!jni_obj_tx_uuid)
2320 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2321 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2325 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2326 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2327 jni_mid_getCharacteristic,
2330 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2331 return jni_obj_GattCharacteristic;
2334 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2336 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2337 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2338 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2339 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2341 if (!CALEIsEnableBTAdapter(env))
2343 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2347 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2350 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2354 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2355 if (!jni_obj_GattCharacteristic)
2357 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2361 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2362 "/BluetoothGattCharacteristic");
2363 if (!jni_cid_BTGattCharacteristic)
2365 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2369 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2370 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2372 if (!jni_mid_setValue)
2374 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2378 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2380 if (JNI_TRUE == ret)
2382 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2386 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2391 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2392 "setWriteType", "(I)V");
2393 if (!jni_mid_setWriteType)
2395 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2399 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2400 "WRITE_TYPE_NO_RESPONSE", "I");
2401 if (!jni_fid_no_response)
2403 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2407 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2408 jni_fid_no_response);
2410 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2412 return jni_obj_GattCharacteristic;
2415 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2417 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2418 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2420 if (!CALEIsEnableBTAdapter(env))
2422 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2426 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2427 "BluetoothGattCharacteristic",
2428 "getValue", "()[B");
2429 if (!jni_mid_getValue)
2431 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2435 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2437 return jni_obj_data_array;
2440 CAResult_t CALEClientCreateUUIDList()
2444 OIC_LOG(ERROR, TAG, "g_jvm is null");
2445 return CA_STATUS_FAILED;
2448 bool isAttached = false;
2450 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2453 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2454 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2458 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2459 return CA_STATUS_FAILED;
2464 // create new object array
2465 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2466 if (!jni_cid_uuid_list)
2468 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2472 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2473 jni_cid_uuid_list, NULL);
2474 if (!jni_obj_uuid_list)
2476 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2481 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2484 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2487 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2489 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2493 (*g_jvm)->DetachCurrentThread(g_jvm);
2496 return CA_STATUS_OK;
2503 (*g_jvm)->DetachCurrentThread(g_jvm);
2505 return CA_STATUS_FAILED;
2508 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2509 jobject characteristic)
2511 VERIFY_NON_NULL(env, TAG, "env is null");
2512 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2513 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2515 if (!CALEIsEnableBTAdapter(env))
2517 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2518 return CA_ADAPTER_NOT_ENABLED;
2521 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2522 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2523 "BluetoothGattCharacteristic",
2525 "(Ljava/util/UUID;)Landroid/bluetooth/"
2526 "BluetoothGattDescriptor;");
2527 if (!jni_mid_getDescriptor)
2529 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2530 return CA_STATUS_FAILED;
2533 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2534 if (!jni_obj_cc_uuid)
2536 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2537 return CA_STATUS_FAILED;
2540 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2541 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2542 jni_mid_getDescriptor, jni_obj_cc_uuid);
2543 if (!jni_obj_descriptor)
2545 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2546 return CA_NOT_SUPPORTED;
2549 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2550 jclass jni_cid_descriptor = (*env)->FindClass(env,
2551 "android/bluetooth/BluetoothGattDescriptor");
2552 if (!jni_cid_descriptor)
2554 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2555 return CA_STATUS_FAILED;
2558 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2559 if (!jni_mid_setValue)
2561 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2562 return CA_STATUS_FAILED;
2565 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2566 "ENABLE_NOTIFICATION_VALUE", "[B");
2567 if (!jni_fid_NotiValue)
2569 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2570 return CA_STATUS_FAILED;
2573 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2575 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2576 env, jni_obj_descriptor, jni_mid_setValue,
2577 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2580 OIC_LOG(DEBUG, TAG, "setValue success");
2584 OIC_LOG(ERROR, TAG, "setValue has failed");
2585 return CA_STATUS_FAILED;
2588 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2590 "(Landroid/bluetooth/"
2591 "BluetoothGattDescriptor;)Z");
2592 if (!jni_mid_writeDescriptor)
2594 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2595 return CA_STATUS_FAILED;
2598 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2599 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2600 jni_obj_descriptor);
2603 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2607 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2608 return CA_STATUS_FAILED;
2611 return CA_STATUS_OK;
2614 void CALEClientCreateScanDeviceList(JNIEnv *env)
2616 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2617 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2619 ca_mutex_lock(g_deviceListMutex);
2620 // create new object array
2621 if (g_deviceList == NULL)
2623 OIC_LOG(DEBUG, TAG, "Create device list");
2625 g_deviceList = u_arraylist_create();
2627 ca_mutex_unlock(g_deviceListMutex);
2630 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2632 VERIFY_NON_NULL(device, TAG, "device is null");
2633 VERIFY_NON_NULL(env, TAG, "env is null");
2635 ca_mutex_lock(g_deviceListMutex);
2639 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2641 CALEClientSetScanFlag(false);
2642 if (CA_STATUS_OK != CALEClientStopScan())
2644 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2647 ca_mutex_unlock(g_deviceListMutex);
2648 return CA_STATUS_FAILED;
2651 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2652 if (!jni_remoteAddress)
2654 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2655 ca_mutex_unlock(g_deviceListMutex);
2656 return CA_STATUS_FAILED;
2659 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2662 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2663 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2664 ca_mutex_unlock(g_deviceListMutex);
2665 return CA_STATUS_FAILED;
2668 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2670 jobject gdevice = (*env)->NewGlobalRef(env, device);
2671 u_arraylist_add(g_deviceList, gdevice);
2672 ca_cond_signal(g_deviceDescCond);
2673 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2675 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2676 (*env)->DeleteLocalRef(env, jni_remoteAddress);
2678 ca_mutex_unlock(g_deviceListMutex);
2680 return CA_STATUS_OK;
2683 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2685 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2686 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2690 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2694 uint32_t length = u_arraylist_length(g_deviceList);
2695 for (uint32_t index = 0; index < length; index++)
2697 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2700 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2704 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2705 if (!jni_setAddress)
2707 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2711 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2714 OIC_LOG(ERROR, TAG, "setAddress is null");
2715 (*env)->DeleteLocalRef(env, jni_setAddress);
2719 if (!strcmp(remoteAddress, setAddress))
2721 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2722 (*env)->DeleteLocalRef(env, jni_setAddress);
2726 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2727 (*env)->DeleteLocalRef(env, jni_setAddress);
2730 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2735 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2737 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2738 VERIFY_NON_NULL(env, TAG, "env is null");
2740 ca_mutex_lock(g_deviceListMutex);
2744 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2745 ca_mutex_unlock(g_deviceListMutex);
2746 return CA_STATUS_FAILED;
2749 uint32_t length = u_arraylist_length(g_deviceList);
2750 for (uint32_t index = 0; index < length; index++)
2752 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2755 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2758 (*env)->DeleteGlobalRef(env, jarrayObj);
2762 OICFree(g_deviceList);
2763 g_deviceList = NULL;
2765 ca_mutex_unlock(g_deviceListMutex);
2766 return CA_STATUS_OK;
2769 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2771 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2772 VERIFY_NON_NULL(address, TAG, "address is null");
2773 VERIFY_NON_NULL(env, TAG, "env is null");
2775 ca_mutex_lock(g_deviceListMutex);
2779 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2780 ca_mutex_unlock(g_deviceListMutex);
2781 return CA_STATUS_FAILED;
2784 uint32_t length = u_arraylist_length(g_deviceList);
2785 for (uint32_t index = 0; index < length; index++)
2787 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2790 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2791 ca_mutex_unlock(g_deviceListMutex);
2792 return CA_STATUS_FAILED;
2795 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2796 if (!jni_setAddress)
2798 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2799 ca_mutex_unlock(g_deviceListMutex);
2800 return CA_STATUS_FAILED;
2803 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2806 OIC_LOG(ERROR, TAG, "setAddress is null");
2807 ca_mutex_unlock(g_deviceListMutex);
2808 return CA_STATUS_FAILED;
2811 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2814 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2815 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2816 ca_mutex_unlock(g_deviceListMutex);
2817 return CA_STATUS_FAILED;
2820 if (!strcmp(setAddress, remoteAddress))
2822 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2823 (*env)->DeleteGlobalRef(env, jarrayObj);
2825 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2826 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2828 if (NULL == u_arraylist_remove(g_deviceList, index))
2830 OIC_LOG(ERROR, TAG, "List removal failed.");
2831 ca_mutex_unlock(g_deviceListMutex);
2832 return CA_STATUS_FAILED;
2834 ca_mutex_unlock(g_deviceListMutex);
2835 return CA_STATUS_OK;
2837 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2838 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2841 ca_mutex_unlock(g_deviceListMutex);
2842 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2844 return CA_STATUS_OK;
2851 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2853 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2854 VERIFY_NON_NULL(env, TAG, "env is null");
2855 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2857 ca_mutex_lock(g_gattObjectMutex);
2859 if (!g_gattObjectList)
2861 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2862 ca_mutex_unlock(g_gattObjectMutex);
2863 return CA_STATUS_FAILED;
2866 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2867 if (!jni_remoteAddress)
2869 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2870 ca_mutex_unlock(g_gattObjectMutex);
2871 return CA_STATUS_FAILED;
2874 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2877 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2878 ca_mutex_unlock(g_gattObjectMutex);
2879 return CA_STATUS_FAILED;
2882 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
2883 if (!CALEClientIsGattObjInList(env, remoteAddress))
2885 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2886 u_arraylist_add(g_gattObjectList, newGatt);
2887 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
2890 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2891 ca_mutex_unlock(g_gattObjectMutex);
2892 return CA_STATUS_OK;
2895 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2897 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2898 VERIFY_NON_NULL(env, TAG, "env is null");
2899 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2901 uint32_t length = u_arraylist_length(g_gattObjectList);
2902 for (uint32_t index = 0; index < length; index++)
2905 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2908 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2912 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2913 if (!jni_setAddress)
2915 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2919 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2922 OIC_LOG(ERROR, TAG, "setAddress is null");
2926 if (!strcmp(remoteAddress, setAddress))
2928 OIC_LOG(DEBUG, TAG, "the device is already set");
2929 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2934 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2939 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2943 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2945 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2946 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2947 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2949 ca_mutex_lock(g_gattObjectMutex);
2950 uint32_t length = u_arraylist_length(g_gattObjectList);
2951 for (uint32_t index = 0; index < length; index++)
2953 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2956 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2957 ca_mutex_unlock(g_gattObjectMutex);
2961 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2962 if (!jni_setAddress)
2964 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2965 ca_mutex_unlock(g_gattObjectMutex);
2969 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2972 OIC_LOG(ERROR, TAG, "setAddress is null");
2973 ca_mutex_unlock(g_gattObjectMutex);
2977 if (!strcmp(remoteAddress, setAddress))
2979 OIC_LOG(DEBUG, TAG, "the device is already set");
2980 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2981 ca_mutex_unlock(g_gattObjectMutex);
2984 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2987 ca_mutex_unlock(g_gattObjectMutex);
2988 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2992 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2994 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2995 VERIFY_NON_NULL(env, TAG, "env is null");
2997 ca_mutex_lock(g_gattObjectMutex);
2998 if (!g_gattObjectList)
3000 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3001 ca_mutex_unlock(g_gattObjectMutex);
3002 return CA_STATUS_OK;
3005 uint32_t length = u_arraylist_length(g_gattObjectList);
3006 for (uint32_t index = 0; index < length; index++)
3008 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3011 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3014 (*env)->DeleteGlobalRef(env, jarrayObj);
3018 OICFree(g_gattObjectList);
3019 g_gattObjectList = NULL;
3020 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3021 ca_mutex_unlock(g_gattObjectMutex);
3022 return CA_STATUS_OK;
3025 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3027 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3028 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3029 VERIFY_NON_NULL(env, TAG, "env is null");
3031 ca_mutex_lock(g_gattObjectMutex);
3032 if (!g_gattObjectList)
3034 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3035 ca_mutex_unlock(g_gattObjectMutex);
3036 return CA_STATUS_OK;
3039 uint32_t length = u_arraylist_length(g_gattObjectList);
3040 for (uint32_t index = 0; index < length; index++)
3042 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3045 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3046 ca_mutex_unlock(g_gattObjectMutex);
3047 return CA_STATUS_FAILED;
3050 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3051 if (!jni_setAddress)
3053 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3054 ca_mutex_unlock(g_gattObjectMutex);
3055 return CA_STATUS_FAILED;
3058 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3061 OIC_LOG(ERROR, TAG, "setAddress is null");
3062 ca_mutex_unlock(g_gattObjectMutex);
3063 return CA_STATUS_FAILED;
3066 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3067 if (!jni_remoteAddress)
3069 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3070 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3071 ca_mutex_unlock(g_gattObjectMutex);
3072 return CA_STATUS_FAILED;
3075 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3078 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3079 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3080 ca_mutex_unlock(g_gattObjectMutex);
3081 return CA_STATUS_FAILED;
3084 if (!strcmp(setAddress, remoteAddress))
3086 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3087 (*env)->DeleteGlobalRef(env, jarrayObj);
3089 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3090 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3092 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3094 OIC_LOG(ERROR, TAG, "List removal failed.");
3095 ca_mutex_unlock(g_gattObjectMutex);
3096 return CA_STATUS_FAILED;
3098 ca_mutex_unlock(g_gattObjectMutex);
3099 return CA_STATUS_OK;
3101 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3102 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3105 ca_mutex_unlock(g_gattObjectMutex);
3106 OIC_LOG(DEBUG, TAG, "there are no target object");
3107 return CA_STATUS_OK;
3110 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3112 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3113 VERIFY_NON_NULL(addr, TAG, "addr is null");
3114 VERIFY_NON_NULL(env, TAG, "env is null");
3116 ca_mutex_lock(g_gattObjectMutex);
3117 if (!g_gattObjectList)
3119 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3120 ca_mutex_unlock(g_gattObjectMutex);
3121 return CA_STATUS_OK;
3124 uint32_t length = u_arraylist_length(g_gattObjectList);
3125 for (uint32_t index = 0; index < length; index++)
3127 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3130 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3131 ca_mutex_unlock(g_gattObjectMutex);
3132 return CA_STATUS_FAILED;
3135 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3136 if (!jni_setAddress)
3138 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3139 ca_mutex_unlock(g_gattObjectMutex);
3140 return CA_STATUS_FAILED;
3143 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3146 OIC_LOG(ERROR, TAG, "setAddress is null");
3147 ca_mutex_unlock(g_gattObjectMutex);
3148 return CA_STATUS_FAILED;
3151 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3154 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3155 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3156 ca_mutex_unlock(g_gattObjectMutex);
3157 return CA_STATUS_FAILED;
3160 if (!strcmp(setAddress, remoteAddress))
3162 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3163 (*env)->DeleteGlobalRef(env, jarrayObj);
3165 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3166 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3167 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3169 OIC_LOG(ERROR, TAG, "List removal failed.");
3170 ca_mutex_unlock(g_gattObjectMutex);
3171 return CA_STATUS_FAILED;
3173 ca_mutex_unlock(g_gattObjectMutex);
3174 return CA_STATUS_OK;
3176 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3177 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3180 ca_mutex_unlock(g_gattObjectMutex);
3181 OIC_LOG(DEBUG, TAG, "there are no target object");
3182 return CA_STATUS_FAILED;
3185 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3187 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3189 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3190 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3192 // get Bluetooth Address
3193 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3194 if (!jni_btTargetAddress)
3196 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3200 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3203 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3207 // get method ID of getDevice()
3208 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3209 "getDevice", METHODID_BT_DEVICE);
3210 if (!jni_mid_getDevice)
3212 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3213 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3217 ca_mutex_lock(g_gattObjectMutex);
3219 size_t length = u_arraylist_length(g_gattObjectList);
3220 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3221 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3223 for (size_t index = 0; index < length; index++)
3225 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3228 ca_mutex_unlock(g_gattObjectMutex);
3229 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3230 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3234 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3235 if (!jni_obj_device)
3237 ca_mutex_unlock(g_gattObjectMutex);
3238 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3239 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3243 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3246 ca_mutex_unlock(g_gattObjectMutex);
3247 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3248 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3252 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3255 ca_mutex_unlock(g_gattObjectMutex);
3256 OIC_LOG(ERROR, TAG, "btAddress is not available");
3257 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3261 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3262 if (!strcmp(targetAddress, btAddress))
3264 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3267 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3270 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3272 ca_mutex_unlock(g_gattObjectMutex);
3273 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3274 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3275 (*env)->DeleteLocalRef(env, jni_btAddress);
3276 (*env)->DeleteLocalRef(env, jni_obj_device);
3277 return jni_LEAddress;
3279 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3280 (*env)->DeleteLocalRef(env, jni_btAddress);
3281 (*env)->DeleteLocalRef(env, jni_obj_device);
3283 ca_mutex_unlock(g_gattObjectMutex);
3285 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3286 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3294 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3295 uint16_t target_state)
3297 VERIFY_NON_NULL(address, TAG, "address is null");
3298 VERIFY_NON_NULL(address, TAG, "state_type is null");
3299 VERIFY_NON_NULL(address, TAG, "target_state is null");
3301 if (!g_deviceStateList)
3303 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3304 return CA_STATUS_FAILED;
3307 ca_mutex_lock(g_deviceStateListMutex);
3309 if (CALEClientIsDeviceInList(address))
3311 CALEState_t* curState = CALEClientGetStateInfo(address);
3314 OIC_LOG(ERROR, TAG, "curState is null");
3315 ca_mutex_unlock(g_deviceStateListMutex);
3316 return CA_STATUS_FAILED;
3321 case CA_LE_CONNECTION_STATE:
3322 curState->connectedState = target_state;
3324 case CA_LE_SEND_STATE:
3325 curState->sendState = target_state;
3330 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3331 curState->address, curState->connectedState, curState->sendState,
3332 curState->autoConnectFlag);
3334 else /** state is added newly **/
3336 if (strlen(address) > CA_MACADDR_SIZE)
3338 OIC_LOG(ERROR, TAG, "address is not proper");
3339 ca_mutex_unlock(g_deviceStateListMutex);
3340 return CA_STATUS_INVALID_PARAM;
3343 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3346 OIC_LOG(ERROR, TAG, "out of memory");
3347 ca_mutex_unlock(g_deviceStateListMutex);
3348 return CA_MEMORY_ALLOC_FAILED;
3351 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3355 case CA_LE_CONNECTION_STATE:
3356 newstate->connectedState = target_state;
3357 newstate->sendState = STATE_SEND_NONE;
3359 case CA_LE_SEND_STATE:
3360 newstate->connectedState = STATE_DISCONNECTED;
3361 newstate->sendState = target_state;
3366 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3367 "conn : %d, send : %d, ACFlag : %d",
3368 newstate->address, newstate->connectedState, newstate->sendState,
3369 newstate->autoConnectFlag);
3370 u_arraylist_add(g_deviceStateList, newstate); // update new state
3372 ca_mutex_unlock(g_deviceStateListMutex);
3374 return CA_STATUS_OK;
3377 bool CALEClientIsDeviceInList(const char* remoteAddress)
3379 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3381 if (!g_deviceStateList)
3383 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3387 uint32_t length = u_arraylist_length(g_deviceStateList);
3388 for (uint32_t index = 0; index < length; index++)
3390 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3393 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3397 if (!strcmp(remoteAddress, state->address))
3399 OIC_LOG(DEBUG, TAG, "the device is already set");
3408 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3412 CAResult_t CALEClientRemoveAllDeviceState()
3414 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3416 ca_mutex_lock(g_deviceStateListMutex);
3417 if (!g_deviceStateList)
3419 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3420 ca_mutex_unlock(g_deviceStateListMutex);
3421 return CA_STATUS_FAILED;
3424 uint32_t length = u_arraylist_length(g_deviceStateList);
3425 for (uint32_t index = 0; index < length; index++)
3427 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3430 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3436 OICFree(g_deviceStateList);
3437 g_deviceStateList = NULL;
3438 ca_mutex_unlock(g_deviceStateListMutex);
3440 return CA_STATUS_OK;
3443 CAResult_t CALEClientResetDeviceStateForAll()
3445 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3447 ca_mutex_lock(g_deviceStateListMutex);
3448 if (!g_deviceStateList)
3450 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3451 ca_mutex_unlock(g_deviceStateListMutex);
3452 return CA_STATUS_FAILED;
3455 size_t length = u_arraylist_length(g_deviceStateList);
3456 for (size_t index = 0; index < length; index++)
3458 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3461 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3465 // autoConnectFlag value will be not changed,
3466 // since it has reset only termination case.
3467 state->connectedState = STATE_DISCONNECTED;
3468 state->sendState = STATE_SEND_NONE;
3470 ca_mutex_unlock(g_deviceStateListMutex);
3472 return CA_STATUS_OK;
3475 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3477 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3478 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3480 if (!g_deviceStateList)
3482 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3483 return CA_STATUS_FAILED;
3486 uint32_t length = u_arraylist_length(g_deviceStateList);
3487 for (uint32_t index = 0; index < length; index++)
3489 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3492 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3496 if (!strcmp(state->address, remoteAddress))
3498 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3500 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3502 if (NULL == targetState)
3504 OIC_LOG(ERROR, TAG, "List removal failed.");
3505 return CA_STATUS_FAILED;
3508 OICFree(targetState);
3509 return CA_STATUS_OK;
3513 return CA_STATUS_OK;
3516 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3518 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3520 if (!g_deviceStateList)
3522 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3526 uint32_t length = u_arraylist_length(g_deviceStateList);
3527 OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
3528 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3530 for (uint32_t index = 0; index < length; index++)
3532 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3535 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3539 OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
3541 if (!strcmp(state->address, remoteAddress))
3543 OIC_LOG(DEBUG, TAG, "found state");
3548 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
3552 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3553 uint16_t target_state)
3555 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3556 state_type, target_state);
3557 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3559 ca_mutex_lock(g_deviceStateListMutex);
3560 if (!g_deviceStateList)
3562 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3563 ca_mutex_unlock(g_deviceStateListMutex);
3567 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3570 OIC_LOG(ERROR, TAG, "state is null");
3571 ca_mutex_unlock(g_deviceStateListMutex);
3575 uint16_t curValue = 0;
3578 case CA_LE_CONNECTION_STATE:
3579 curValue = state->connectedState;
3581 case CA_LE_SEND_STATE:
3582 curValue = state->sendState;
3588 if (target_state == curValue)
3590 ca_mutex_unlock(g_deviceStateListMutex);
3595 ca_mutex_unlock(g_deviceStateListMutex);
3599 ca_mutex_unlock(g_deviceStateListMutex);
3603 void CALEClientCreateDeviceList()
3605 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3607 // create new object array
3608 if (!g_gattObjectList)
3610 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3612 g_gattObjectList = u_arraylist_create();
3615 if (!g_deviceStateList)
3617 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3619 g_deviceStateList = u_arraylist_create();
3624 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3626 g_deviceList = u_arraylist_create();
3631 * Check Sent Count for remove g_sendBuffer
3633 void CALEClientUpdateSendCnt(JNIEnv *env)
3635 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3637 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3639 ca_mutex_lock(g_threadMutex);
3643 if (g_targetCnt <= g_currentSentCnt)
3646 g_currentSentCnt = 0;
3650 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3651 g_sendBuffer = NULL;
3653 // notity the thread
3654 ca_cond_signal(g_threadCond);
3656 CALEClientSetSendFinishFlag(true);
3657 OIC_LOG(DEBUG, TAG, "set signal for send data");
3660 ca_mutex_unlock(g_threadMutex);
3663 CAResult_t CALEClientInitGattMutexVaraibles()
3665 if (NULL == g_bleReqRespClientCbMutex)
3667 g_bleReqRespClientCbMutex = ca_mutex_new();
3668 if (NULL == g_bleReqRespClientCbMutex)
3670 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3671 return CA_STATUS_FAILED;
3675 if (NULL == g_bleServerBDAddressMutex)
3677 g_bleServerBDAddressMutex = ca_mutex_new();
3678 if (NULL == g_bleServerBDAddressMutex)
3680 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3681 return CA_STATUS_FAILED;
3685 if (NULL == g_threadMutex)
3687 g_threadMutex = ca_mutex_new();
3688 if (NULL == g_threadMutex)
3690 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3691 return CA_STATUS_FAILED;
3695 if (NULL == g_threadSendMutex)
3697 g_threadSendMutex = ca_mutex_new();
3698 if (NULL == g_threadSendMutex)
3700 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3701 return CA_STATUS_FAILED;
3705 if (NULL == g_deviceListMutex)
3707 g_deviceListMutex = ca_mutex_new();
3708 if (NULL == g_deviceListMutex)
3710 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3711 return CA_STATUS_FAILED;
3715 if (NULL == g_gattObjectMutex)
3717 g_gattObjectMutex = ca_mutex_new();
3718 if (NULL == g_gattObjectMutex)
3720 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3721 return CA_STATUS_FAILED;
3725 if (NULL == g_deviceStateListMutex)
3727 g_deviceStateListMutex = ca_mutex_new();
3728 if (NULL == g_deviceStateListMutex)
3730 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3731 return CA_STATUS_FAILED;
3735 if (NULL == g_SendFinishMutex)
3737 g_SendFinishMutex = ca_mutex_new();
3738 if (NULL == g_SendFinishMutex)
3740 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3741 return CA_STATUS_FAILED;
3745 if (NULL == g_scanMutex)
3747 g_scanMutex = ca_mutex_new();
3748 if (NULL == g_scanMutex)
3750 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3751 return CA_STATUS_FAILED;
3755 if (NULL == g_threadWriteCharacteristicMutex)
3757 g_threadWriteCharacteristicMutex = ca_mutex_new();
3758 if (NULL == g_threadWriteCharacteristicMutex)
3760 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3761 return CA_STATUS_FAILED;
3765 if (NULL == g_deviceScanRetryDelayMutex)
3767 g_deviceScanRetryDelayMutex = ca_mutex_new();
3768 if (NULL == g_deviceScanRetryDelayMutex)
3770 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3771 return CA_STATUS_FAILED;
3775 if (NULL == g_threadSendStateMutex)
3777 g_threadSendStateMutex = ca_mutex_new();
3778 if (NULL == g_threadSendStateMutex)
3780 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3781 return CA_STATUS_FAILED;
3785 return CA_STATUS_OK;
3788 void CALEClientTerminateGattMutexVariables()
3790 ca_mutex_free(g_bleReqRespClientCbMutex);
3791 g_bleReqRespClientCbMutex = NULL;
3793 ca_mutex_free(g_bleServerBDAddressMutex);
3794 g_bleServerBDAddressMutex = NULL;
3796 ca_mutex_free(g_threadMutex);
3797 g_threadMutex = NULL;
3799 ca_mutex_free(g_threadSendMutex);
3800 g_threadSendMutex = NULL;
3802 ca_mutex_free(g_deviceListMutex);
3803 g_deviceListMutex = NULL;
3805 ca_mutex_free(g_SendFinishMutex);
3806 g_SendFinishMutex = NULL;
3808 ca_mutex_free(g_scanMutex);
3811 ca_mutex_free(g_threadWriteCharacteristicMutex);
3812 g_threadWriteCharacteristicMutex = NULL;
3814 ca_mutex_free(g_deviceScanRetryDelayMutex);
3815 g_deviceScanRetryDelayMutex = NULL;
3817 ca_mutex_free(g_threadSendStateMutex);
3818 g_threadSendStateMutex = NULL;
3821 void CALEClientSetSendFinishFlag(bool flag)
3823 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3825 ca_mutex_lock(g_SendFinishMutex);
3826 g_isFinishedSendData = flag;
3827 ca_mutex_unlock(g_SendFinishMutex);
3834 CAResult_t CAStartLEGattClient()
3836 // init mutex for send logic
3837 if (!g_deviceDescCond)
3839 g_deviceDescCond = ca_cond_new();
3844 g_threadCond = ca_cond_new();
3847 if (!g_threadWriteCharacteristicCond)
3849 g_threadWriteCharacteristicCond = ca_cond_new();
3852 CAResult_t ret = CALEClientStartScan();
3853 if (CA_STATUS_OK != ret)
3855 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3859 g_isStartedLEClient = true;
3860 return CA_STATUS_OK;
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 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3903 ca_cond_signal(g_threadCond);
3904 CALEClientSetSendFinishFlag(true);
3905 ca_mutex_unlock(g_threadMutex);
3907 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3908 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3909 ca_cond_signal(g_threadWriteCharacteristicCond);
3910 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3912 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3913 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3914 ca_cond_signal(g_deviceScanRetryDelayCond);
3915 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3917 ca_cond_free(g_deviceDescCond);
3918 ca_cond_free(g_threadCond);
3919 ca_cond_free(g_threadWriteCharacteristicCond);
3920 ca_cond_free(g_deviceScanRetryDelayCond);
3922 g_deviceDescCond = NULL;
3923 g_threadCond = NULL;
3924 g_threadWriteCharacteristicCond = NULL;
3925 g_deviceScanRetryDelayCond = NULL;
3929 (*g_jvm)->DetachCurrentThread(g_jvm);
3934 CAResult_t CAInitializeLEGattClient()
3936 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3937 CALEClientInitialize();
3938 return CA_STATUS_OK;
3941 void CATerminateLEGattClient()
3943 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3944 CAStopLEGattClient();
3945 CALEClientTerminate();
3948 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3949 uint32_t dataLen, CALETransferType_t type,
3952 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3953 VERIFY_NON_NULL(data, TAG, "data is null");
3954 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3956 if (LE_UNICAST != type || position < 0)
3958 OIC_LOG(ERROR, TAG, "this request is not unicast");
3959 return CA_STATUS_INVALID_PARAM;
3962 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3965 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3967 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3968 VERIFY_NON_NULL(data, TAG, "data is null");
3970 return CALEClientSendMulticastMessage(data, dataLen);
3973 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3975 ca_mutex_lock(g_bleReqRespClientCbMutex);
3976 g_CABLEClientDataReceivedCallback = callback;
3977 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3980 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3982 g_threadPoolHandle = handle;
3985 CAResult_t CAGetLEAddress(char **local_address)
3987 VERIFY_NON_NULL(local_address, TAG, "local_address");
3988 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3989 return CA_NOT_SUPPORTED;
3992 JNIEXPORT void JNICALL
3993 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3996 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3997 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3998 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3999 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4001 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
4004 JNIEXPORT void JNICALL
4005 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
4008 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
4009 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4010 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4011 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
4013 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
4016 JNIEXPORT void JNICALL
4017 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
4020 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4021 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4022 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
4024 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
4025 if (CA_STATUS_OK != res)
4027 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4031 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4033 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4035 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4036 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4038 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4039 "getDevice", METHODID_BT_DEVICE);
4040 if (!jni_mid_getDevice)
4042 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4046 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4047 if (!jni_obj_device)
4049 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4053 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4056 OIC_LOG(ERROR, TAG, "jni_address is null");
4060 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4065 * Class: org_iotivity_ca_jar_caleinterface
4066 * Method: CALeGattConnectionStateChangeCallback
4067 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4069 JNIEXPORT void JNICALL
4070 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4076 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4078 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4079 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4080 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4082 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4084 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4087 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4091 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4094 OIC_LOG(ERROR, TAG, "address is null");
4097 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4100 if (state_connected == newstate)
4102 OIC_LOG(DEBUG, TAG, "LE is connected");
4103 if (GATT_SUCCESS == status)
4105 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_CONNECTED);
4106 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4107 if (CA_STATUS_OK != res)
4109 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4113 res = CALEClientAddGattobjToList(env, gatt);
4114 if (CA_STATUS_OK != res)
4116 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4120 res = CALEClientDiscoverServices(env, gatt);
4121 if (CA_STATUS_OK != res)
4123 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4129 OIC_LOG(INFO, TAG, "unknown status");
4130 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4133 else // STATE_DISCONNECTED == newstate
4135 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4137 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_DISCONNECTED);
4138 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4139 if (CA_STATUS_OK != res)
4141 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4145 res = CALEClientGattClose(env, gatt);
4146 if (CA_STATUS_OK != res)
4148 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4151 if (CALECheckConnectionStateValue(status))
4153 // this state is unexpected reason to disconnect
4154 // if the reason is suitable, connection logic of the device will be destroyed.
4155 OIC_LOG(INFO, TAG, "connection logic destroy");
4160 // other reason except for gatt_success is expected to running
4161 // background connection in BT platform.
4162 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4163 CALEClientUpdateSendCnt(env);
4169 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4170 g_sendBuffer = NULL;
4177 CALEClientSendFinish(env, gatt);
4182 * Class: org_iotivity_ca_jar_caleinterface
4183 * Method: CALeGattServicesDiscoveredCallback
4184 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4186 JNIEXPORT void JNICALL
4187 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4192 OIC_LOG_V(INFO, TAG, "CALeGattServicesDiscoveredCallback - status %d", status);
4193 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4194 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4195 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4197 if (GATT_SUCCESS != status) // discovery error
4199 CALEClientSendFinish(env, gatt);
4203 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4206 CALEClientSendFinish(env, gatt);
4210 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4213 CALEClientSendFinish(env, gatt);
4217 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4220 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4224 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4225 if (!jni_obj_GattCharacteristic)
4227 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4231 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4232 jni_obj_GattCharacteristic);
4233 if (CA_STATUS_OK != res)
4235 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4239 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4240 if (CA_STATUS_OK != res)
4242 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4244 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
4245 if (CA_STATUS_OK != res)
4247 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4251 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4252 STATE_SERVICE_CONNECTED);
4253 if (CA_STATUS_OK != res)
4255 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4261 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4262 if (CA_STATUS_OK != res)
4264 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4271 res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
4272 if (CA_STATUS_OK != res)
4274 OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
4279 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4280 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4285 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4286 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4287 CALEClientSendFinish(env, gatt);
4292 * Class: org_iotivity_ca_jar_caleinterface
4293 * Method: CALeGattCharacteristicWritjclasseCallback
4294 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4296 JNIEXPORT void JNICALL
4297 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4298 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data, jint status)
4300 OIC_LOG_V(INFO, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4301 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4302 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4303 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4305 // send success & signal
4306 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4312 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4318 if (GATT_SUCCESS != status) // error case
4320 OIC_LOG(ERROR, TAG, "send failure");
4323 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4324 if (CA_STATUS_OK != res)
4326 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4327 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4328 g_isSignalSetFlag = true;
4329 ca_cond_signal(g_threadWriteCharacteristicCond);
4330 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4332 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4334 if (CA_STATUS_OK != res)
4336 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4339 if (g_clientErrorCallback)
4341 jint length = (*env)->GetArrayLength(env, data);
4342 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4345 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4351 OIC_LOG(DEBUG, TAG, "send success");
4352 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4353 STATE_SEND_SUCCESS);
4354 if (CA_STATUS_OK != res)
4356 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4359 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4360 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4361 g_isSignalSetFlag = true;
4362 ca_cond_signal(g_threadWriteCharacteristicCond);
4363 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4365 CALEClientUpdateSendCnt(env);
4368 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4374 CALEClientSendFinish(env, gatt);
4379 * Class: org_iotivity_ca_jar_caleinterface
4380 * Method: CALeGattCharacteristicChangedCallback
4381 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4383 JNIEXPORT void JNICALL
4384 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4385 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4387 OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
4388 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4389 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4390 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4391 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4393 // get Byte Array and convert to uint8_t*
4394 jint length = (*env)->GetArrayLength(env, data);
4397 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4399 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4400 jni_byte_responseData);
4402 uint8_t* receivedData = OICMalloc(length);
4405 OIC_LOG(ERROR, TAG, "receivedData is null");
4409 memcpy(receivedData, jni_byte_responseData, length);
4410 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4412 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4415 OIC_LOG(ERROR, TAG, "jni_address is null");
4416 OICFree(receivedData);
4420 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4423 OIC_LOG(ERROR, TAG, "address is null");
4424 OICFree(receivedData);
4428 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4429 receivedData, length);
4431 uint32_t sentLength = 0;
4432 ca_mutex_lock(g_bleServerBDAddressMutex);
4433 g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
4434 ca_mutex_unlock(g_bleServerBDAddressMutex);
4436 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4440 * Class: org_iotivity_ca_jar_caleinterface
4441 * Method: CALeGattDescriptorWriteCallback
4442 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4444 JNIEXPORT void JNICALL
4445 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4449 OIC_LOG_V(INFO, TAG, "CALeGattDescriptorWriteCallback - status %d", status);
4450 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4451 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4452 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4454 if (GATT_SUCCESS != status) // error
4459 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4465 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4471 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4472 STATE_SERVICE_CONNECTED);
4473 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4474 if (CA_STATUS_OK != res)
4476 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4482 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4483 if (CA_STATUS_OK != res)
4485 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4494 CALEClientSendFinish(env, gatt);