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);
745 // connect to gatt server
746 ret = CALEClientStopScan();
747 if (CA_STATUS_OK != ret)
749 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
755 (*env)->DeleteGlobalRef(env, g_sendBuffer);
758 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
759 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
760 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
762 // Target device to send message is just one.
765 ret = CALEClientSendData(env, jarrayObj);
766 if (CA_STATUS_OK != ret)
768 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
772 OIC_LOG(INFO, TAG, "wake up");
775 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
779 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
781 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
782 // if there is no connection state.
783 ca_mutex_lock(g_threadMutex);
784 if (!g_isFinishedSendData)
786 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
787 ca_cond_wait(g_threadCond, g_threadMutex);
788 OIC_LOG(DEBUG, TAG, "the data was sent");
790 ca_mutex_unlock(g_threadMutex);
794 (*g_jvm)->DetachCurrentThread(g_jvm);
797 // start LE Scan again
798 ret = CALEClientStartScan();
799 if (CA_STATUS_OK != ret)
801 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
802 ca_mutex_unlock(g_threadSendMutex);
806 ca_mutex_unlock(g_threadSendMutex);
807 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
808 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
815 ret = CA_SEND_FAILED;
819 ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
821 if (CA_STATUS_OK != ret)
823 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
831 // start LE Scan again
832 ret = CALEClientStartScan();
833 if (CA_STATUS_OK != ret)
835 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
836 ca_mutex_unlock(g_threadSendMutex);
839 (*g_jvm)->DetachCurrentThread(g_jvm);
846 (*g_jvm)->DetachCurrentThread(g_jvm);
849 ca_mutex_unlock(g_threadSendMutex);
850 return CA_SEND_FAILED;
853 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
854 const uint32_t dataLen)
856 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
857 VERIFY_NON_NULL(data, TAG, "data is null");
858 VERIFY_NON_NULL(env, TAG, "env is null");
862 OIC_LOG(ERROR, TAG, "g_deviceList is null");
863 return CA_STATUS_FAILED;
866 ca_mutex_lock(g_threadSendMutex);
868 CALEClientSetSendFinishFlag(false);
870 OIC_LOG(DEBUG, TAG, "set byteArray for data");
873 (*env)->DeleteGlobalRef(env, g_sendBuffer);
877 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
878 if (CA_STATUS_OK != res)
880 OIC_LOG(INFO, TAG, "there is no scanned device");
884 // connect to gatt server
885 res = CALEClientStopScan();
886 if (CA_STATUS_OK != res)
888 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
889 ca_mutex_unlock(g_threadSendMutex);
892 uint32_t length = u_arraylist_length(g_deviceList);
893 g_targetCnt = length;
895 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
896 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
897 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
899 for (uint32_t index = 0; index < length; index++)
901 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
904 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
908 res = CALEClientSendData(env, jarrayObj);
909 if (res != CA_STATUS_OK)
911 OIC_LOG(ERROR, TAG, "BT device - send has failed");
914 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
917 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
921 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
924 OIC_LOG(ERROR, TAG, "address is not available");
928 (*env)->ReleaseStringUTFChars(env, jni_address, address);
931 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
933 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
934 ca_mutex_lock(g_threadMutex);
935 if (!g_isFinishedSendData)
937 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
938 ca_cond_wait(g_threadCond, g_threadMutex);
939 OIC_LOG(DEBUG, TAG, "the data was sent");
941 ca_mutex_unlock(g_threadMutex);
943 // start LE Scan again
944 res = CALEClientStartScan();
945 if (CA_STATUS_OK != res)
947 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
948 ca_mutex_unlock(g_threadSendMutex);
952 ca_mutex_unlock(g_threadSendMutex);
953 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
957 res = CALEClientStartScan();
958 if (CA_STATUS_OK != res)
960 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
961 ca_mutex_unlock(g_threadSendMutex);
965 ca_mutex_unlock(g_threadSendMutex);
966 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
967 return CA_SEND_FAILED;
970 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
972 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
973 VERIFY_NON_NULL(device, TAG, "device is null");
974 VERIFY_NON_NULL(env, TAG, "env is null");
976 // get BLE address from bluetooth device object.
977 char* address = NULL;
978 CALEState_t* state = NULL;
979 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
982 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
983 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
986 OIC_LOG(ERROR, TAG, "address is not available");
987 return CA_STATUS_FAILED;
989 ca_mutex_lock(g_deviceStateListMutex);
990 state = CALEClientGetStateInfo(address);
991 ca_mutex_unlock(g_deviceStateListMutex);
996 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
998 // cancel previous connection request before connection
999 // if there is gatt object in g_gattObjectList.
1002 jobject gatt = CALEClientGetGattObjInList(env, address);
1005 CAResult_t res = CALEClientDisconnect(env, gatt);
1006 if (CA_STATUS_OK != res)
1008 OIC_LOG(INFO, TAG, "there is no gatt object");
1011 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1014 // connection request
1015 jobject newGatt = CALEClientConnect(env, device,
1017 if (NULL == newGatt)
1019 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1020 return CA_STATUS_FAILED;
1025 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1026 STATE_SERVICE_CONNECTED))
1028 OIC_LOG(INFO, TAG, "GATT has already connected");
1030 jobject gatt = CALEClientGetGattObjInList(env, address);
1033 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1034 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1035 return CA_STATUS_FAILED;
1038 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1039 if (CA_STATUS_OK != ret)
1041 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1042 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1045 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1047 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1050 OIC_LOG(INFO, TAG, "service connecting...");
1052 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1053 STATE_DISCONNECTED))
1055 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1057 // cancel previous connection request before connection
1058 // if there is gatt object in g_gattObjectList.
1061 jobject gatt = CALEClientGetGattObjInList(env, address);
1064 CAResult_t res = CALEClientDisconnect(env, gatt);
1065 if (CA_STATUS_OK != res)
1067 OIC_LOG(INFO, TAG, "there is no gatt object");
1070 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1073 OIC_LOG(DEBUG, TAG, "start to connect LE");
1074 jobject gatt = CALEClientConnect(env, device,
1075 CALEClientGetFlagFromState(env, jni_address,
1076 CA_LE_AUTO_CONNECT_FLAG));
1079 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1080 return CA_STATUS_FAILED;
1085 return CA_STATUS_OK;
1088 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1090 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1091 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1093 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1094 "()Landroid/bluetooth/BluetoothDevice;");
1095 if (!jni_mid_getDevice)
1097 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1101 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1102 if (!jni_obj_device)
1104 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1108 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1111 OIC_LOG(ERROR, TAG, "jni_address is null");
1121 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1124 OIC_LOG(DEBUG, TAG, "Gatt Close");
1125 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1126 VERIFY_NON_NULL(env, TAG, "env is null");
1128 // get BluetoothGatt method
1129 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1130 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1131 if (!jni_mid_closeGatt)
1133 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1134 return CA_STATUS_OK;
1137 // call disconnect gatt method
1138 OIC_LOG(DEBUG, TAG, "request to close GATT");
1139 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1141 if ((*env)->ExceptionCheck(env))
1143 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1144 (*env)->ExceptionDescribe(env);
1145 (*env)->ExceptionClear(env);
1146 return CA_STATUS_FAILED;
1149 return CA_STATUS_OK;
1152 CAResult_t CALEClientStartScan()
1154 if (!g_isStartedLEClient)
1156 OIC_LOG(ERROR, TAG, "LE client is not started");
1157 return CA_STATUS_FAILED;
1162 OIC_LOG(ERROR, TAG, "g_jvm is null");
1163 return CA_STATUS_FAILED;
1166 if (g_isStartedScan)
1168 OIC_LOG(INFO, TAG, "scanning is already started");
1169 return CA_STATUS_OK;
1172 bool isAttached = false;
1174 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1177 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1179 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1182 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1183 return CA_STATUS_FAILED;
1188 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1190 CAResult_t ret = CA_STATUS_OK;
1191 // scan gatt server with UUID
1192 if (g_leScanCallback && g_uuidList)
1195 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1197 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1199 if (CA_STATUS_OK != ret)
1201 if (CA_ADAPTER_NOT_ENABLED == ret)
1203 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1207 OIC_LOG(ERROR, TAG, "start scan has failed");
1214 (*g_jvm)->DetachCurrentThread(g_jvm);
1220 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1222 VERIFY_NON_NULL(callback, TAG, "callback is null");
1223 VERIFY_NON_NULL(env, TAG, "env is null");
1225 if (!CALEIsEnableBTAdapter(env))
1227 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1228 return CA_ADAPTER_NOT_ENABLED;
1231 // get default bt adapter class
1232 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1233 if (!jni_cid_BTAdapter)
1235 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1236 return CA_STATUS_FAILED;
1239 // get remote bt adapter method
1240 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1241 "getDefaultAdapter",
1242 METHODID_OBJECTNONPARAM);
1243 if (!jni_mid_getDefaultAdapter)
1245 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1246 return CA_STATUS_FAILED;
1249 // get start le scan method
1250 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1251 "(Landroid/bluetooth/BluetoothAdapter$"
1252 "LeScanCallback;)Z");
1253 if (!jni_mid_startLeScan)
1255 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1256 return CA_STATUS_FAILED;
1259 // gat bt adapter object
1260 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1261 jni_mid_getDefaultAdapter);
1262 if (!jni_obj_BTAdapter)
1264 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1265 return CA_STATUS_FAILED;
1268 // call start le scan method
1269 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1270 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1271 jni_mid_startLeScan, callback);
1272 if (!jni_obj_startLeScan)
1274 OIC_LOG(INFO, TAG, "startLeScan has failed");
1278 OIC_LOG(DEBUG, TAG, "LeScan has started");
1279 CALEClientSetScanFlag(true);
1282 return CA_STATUS_OK;
1285 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1287 VERIFY_NON_NULL(callback, TAG, "callback is null");
1288 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1289 VERIFY_NON_NULL(env, TAG, "env is null");
1291 if (!CALEIsEnableBTAdapter(env))
1293 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1294 return CA_ADAPTER_NOT_ENABLED;
1297 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1298 if (!jni_cid_BTAdapter)
1300 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1301 return CA_STATUS_FAILED;
1304 // get remote bt adapter method
1305 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1306 "getDefaultAdapter",
1307 METHODID_OBJECTNONPARAM);
1308 if (!jni_mid_getDefaultAdapter)
1310 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1311 return CA_STATUS_FAILED;
1314 // get start le scan method
1315 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1316 "([Ljava/util/UUID;Landroid/bluetooth/"
1317 "BluetoothAdapter$LeScanCallback;)Z");
1318 if (!jni_mid_startLeScan)
1320 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1321 return CA_STATUS_FAILED;
1324 // get bt adapter object
1325 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1326 jni_mid_getDefaultAdapter);
1327 if (!jni_obj_BTAdapter)
1329 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1330 return CA_STATUS_FAILED;
1333 // call start le scan method
1334 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1335 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1336 jni_mid_startLeScan, uuids, callback);
1337 if (!jni_obj_startLeScan)
1339 OIC_LOG(INFO, TAG, "startLeScan has failed");
1343 OIC_LOG(DEBUG, TAG, "LeScan has started");
1344 CALEClientSetScanFlag(true);
1347 return CA_STATUS_OK;
1350 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1352 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1353 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1356 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1359 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1363 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1364 "(Ljava/lang/String;)"
1365 "Ljava/util/UUID;");
1366 if (!jni_mid_fromString)
1368 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1372 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1373 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1377 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1381 return jni_obj_uuid;
1384 CAResult_t CALEClientStopScan()
1388 OIC_LOG(ERROR, TAG, "g_jvm is null");
1389 return CA_STATUS_FAILED;
1392 if (!g_isStartedScan)
1394 OIC_LOG(INFO, TAG, "scanning is already stopped");
1395 return CA_STATUS_OK;
1398 bool isAttached = false;
1400 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1403 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1404 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1407 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1408 return CA_STATUS_FAILED;
1413 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1414 if (CA_STATUS_OK != ret)
1416 if (CA_ADAPTER_NOT_ENABLED == ret)
1418 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1422 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1427 CALEClientSetScanFlag(false);
1432 (*g_jvm)->DetachCurrentThread(g_jvm);
1438 void CALEClientSetScanFlag(bool flag)
1440 ca_mutex_lock(g_scanMutex);
1441 g_isStartedScan = flag;
1442 ca_mutex_unlock(g_scanMutex);
1445 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1447 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1448 VERIFY_NON_NULL(callback, TAG, "callback is null");
1449 VERIFY_NON_NULL(env, TAG, "env is null");
1451 if (!CALEIsEnableBTAdapter(env))
1453 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1454 return CA_ADAPTER_NOT_ENABLED;
1457 // get default bt adapter class
1458 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1459 if (!jni_cid_BTAdapter)
1461 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1462 return CA_STATUS_FAILED;
1465 // get remote bt adapter method
1466 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1467 "getDefaultAdapter",
1468 METHODID_OBJECTNONPARAM);
1469 if (!jni_mid_getDefaultAdapter)
1471 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1472 return CA_STATUS_FAILED;
1475 // get start le scan method
1476 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1477 "(Landroid/bluetooth/"
1478 "BluetoothAdapter$LeScanCallback;)V");
1479 if (!jni_mid_stopLeScan)
1481 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1482 return CA_STATUS_FAILED;
1485 // gat bt adapter object
1486 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1487 jni_mid_getDefaultAdapter);
1488 if (!jni_obj_BTAdapter)
1490 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1491 return CA_STATUS_FAILED;
1494 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1495 // call start le scan method
1496 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1497 if ((*env)->ExceptionCheck(env))
1499 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1500 (*env)->ExceptionDescribe(env);
1501 (*env)->ExceptionClear(env);
1502 return CA_STATUS_FAILED;
1505 return CA_STATUS_OK;
1508 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1510 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1511 VERIFY_NON_NULL(env, TAG, "env");
1512 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1514 ca_mutex_lock(g_deviceStateListMutex);
1516 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1519 OIC_LOG(ERROR, TAG, "address is not available");
1520 return CA_STATUS_FAILED;
1523 if (CALEClientIsDeviceInList(address))
1525 CALEState_t* curState = CALEClientGetStateInfo(address);
1528 OIC_LOG(ERROR, TAG, "curState is null");
1529 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1530 ca_mutex_unlock(g_deviceStateListMutex);
1531 return CA_STATUS_FAILED;
1533 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1537 case CA_LE_AUTO_CONNECT_FLAG:
1538 curState->autoConnectFlag = flag;
1540 case CA_LE_DESCRIPTOR_FOUND:
1541 curState->isDescriptorFound = flag;
1548 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1549 ca_mutex_unlock(g_deviceStateListMutex);
1550 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1551 return CA_STATUS_OK;
1554 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1556 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1557 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1558 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1560 ca_mutex_lock(g_deviceStateListMutex);
1562 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1565 OIC_LOG(ERROR, TAG, "address is not available");
1566 ca_mutex_unlock(g_deviceStateListMutex);
1570 CALEState_t* curState = CALEClientGetStateInfo(address);
1571 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1574 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1575 ca_mutex_unlock(g_deviceStateListMutex);
1579 jboolean ret = JNI_FALSE;
1582 case CA_LE_AUTO_CONNECT_FLAG:
1583 ret = curState->autoConnectFlag;
1585 case CA_LE_DESCRIPTOR_FOUND:
1586 ret = curState->isDescriptorFound;
1591 ca_mutex_unlock(g_deviceStateListMutex);
1593 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1594 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1598 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1600 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1601 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1602 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1604 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1605 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1608 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1611 OIC_LOG(ERROR, TAG, "address is not available");
1615 // close the gatt service
1616 jobject gatt = CALEClientGetGattObjInList(env, address);
1619 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1620 if (CA_STATUS_OK != res)
1622 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1623 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1627 // clean previous gatt object after close profile service
1628 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1629 if (CA_STATUS_OK != res)
1631 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1632 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1636 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1639 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1642 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1646 // add new gatt object into g_gattObjectList
1647 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1648 if (CA_STATUS_OK != res)
1650 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1657 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1659 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1660 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1661 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1663 if (!g_leGattCallback)
1665 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1669 if (!CALEIsEnableBTAdapter(env))
1671 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1675 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1678 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1682 // get BluetoothDevice method
1683 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1684 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1686 "(Landroid/content/Context;ZLandroid/"
1687 "bluetooth/BluetoothGattCallback;)"
1688 "Landroid/bluetooth/BluetoothGatt;");
1689 if (!jni_mid_connectGatt)
1691 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1695 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1696 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1697 jni_mid_connectGatt,
1699 autoconnect, g_leGattCallback);
1700 if (!jni_obj_connectGatt)
1702 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1703 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1704 CALEClientUpdateSendCnt(env);
1709 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1711 return jni_obj_connectGatt;
1714 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1716 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1718 VERIFY_NON_NULL(env, TAG, "env is null");
1719 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1721 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1722 if (!jni_cid_BTAdapter)
1724 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1725 return CA_STATUS_FAILED;
1728 // get remote bt adapter method
1729 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1730 "getDefaultAdapter",
1731 METHODID_OBJECTNONPARAM);
1732 if (!jni_mid_getDefaultAdapter)
1734 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1735 return CA_STATUS_FAILED;
1738 // gat bt adapter object
1739 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1740 jni_mid_getDefaultAdapter);
1741 if (!jni_obj_BTAdapter)
1743 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1744 return CA_STATUS_FAILED;
1747 // get closeProfileProxy method
1748 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1749 "closeProfileProxy",
1750 "(ILandroid/bluetooth/"
1751 "BluetoothProfile;)V");
1752 if (!jni_mid_closeProfileProxy)
1754 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1755 return CA_STATUS_FAILED;
1758 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1759 if (!jni_cid_BTProfile)
1761 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1762 return CA_STATUS_FAILED;
1765 // GATT - Constant value : 7 (0x00000007)
1766 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1770 OIC_LOG(ERROR, TAG, "id_gatt is null");
1771 return CA_STATUS_FAILED;
1774 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1776 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1777 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1778 if ((*env)->ExceptionCheck(env))
1780 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1781 (*env)->ExceptionDescribe(env);
1782 (*env)->ExceptionClear(env);
1783 return CA_STATUS_FAILED;
1786 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1787 return CA_STATUS_OK;
1791 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1793 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1794 VERIFY_NON_NULL(env, TAG, "env is null");
1795 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1797 // get BluetoothGatt method
1798 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1799 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1800 "disconnect", "()V");
1801 if (!jni_mid_disconnectGatt)
1803 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1804 return CA_STATUS_FAILED;
1807 // call disconnect gatt method
1808 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1809 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1810 if ((*env)->ExceptionCheck(env))
1812 OIC_LOG(ERROR, TAG, "disconnect has failed");
1813 (*env)->ExceptionDescribe(env);
1814 (*env)->ExceptionClear(env);
1815 return CA_STATUS_FAILED;
1818 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1820 return CA_STATUS_OK;
1823 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1825 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1826 VERIFY_NON_NULL(env, TAG, "env is null");
1828 if (!g_gattObjectList)
1830 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1831 return CA_STATUS_OK;
1834 uint32_t length = u_arraylist_length(g_gattObjectList);
1835 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1836 for (uint32_t index = 0; index < length; index++)
1838 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1839 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1842 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1845 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1846 if (CA_STATUS_OK != res)
1848 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1853 return CA_STATUS_OK;
1856 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1858 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1859 VERIFY_NON_NULL(env, TAG, "env is null");
1861 if (!g_gattObjectList)
1863 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1864 return CA_STATUS_OK;
1867 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1870 OIC_LOG(ERROR, TAG, "address is null");
1871 return CA_STATUS_FAILED;
1874 uint32_t length = u_arraylist_length(g_gattObjectList);
1875 for (uint32_t index = 0; index < length; index++)
1877 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1880 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1884 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1885 if (!jni_setAddress)
1887 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1888 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1889 return CA_STATUS_FAILED;
1892 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1895 OIC_LOG(ERROR, TAG, "setAddress is null");
1896 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1897 return CA_STATUS_FAILED;
1900 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1901 if (!strcmp(address, setAddress))
1903 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1904 if (CA_STATUS_OK != res)
1906 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1907 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1908 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1909 return CA_STATUS_FAILED;
1911 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1912 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1913 return CA_STATUS_OK;
1915 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1917 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1919 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1920 return CA_STATUS_OK;
1923 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1925 VERIFY_NON_NULL(env, TAG, "env is null");
1926 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1928 if (!CALEIsEnableBTAdapter(env))
1930 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1931 return CA_ADAPTER_NOT_ENABLED;
1934 // get BluetoothGatt.discoverServices method
1935 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1936 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1937 "discoverServices", "()Z");
1938 if (!jni_mid_discoverServices)
1940 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1941 return CA_STATUS_FAILED;
1944 // call disconnect gatt method
1945 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
1946 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1949 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1950 return CA_STATUS_FAILED;
1953 return CA_STATUS_OK;
1956 static void CALEWriteCharacteristicThread(void* object)
1958 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1960 bool isAttached = false;
1962 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1965 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1966 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1970 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1976 jobject gatt = (jobject)object;
1977 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1978 if (CA_STATUS_OK != ret)
1980 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1985 (*g_jvm)->DetachCurrentThread(g_jvm);
1989 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1991 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
1993 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1994 VERIFY_NON_NULL(env, TAG, "env is null");
1996 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
1999 CALEClientSendFinish(env, gatt);
2000 return CA_STATUS_FAILED;
2003 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2006 CALEClientSendFinish(env, gatt);
2007 return CA_STATUS_FAILED;
2010 ca_mutex_lock(g_threadSendStateMutex);
2012 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2014 OIC_LOG(INFO, TAG, "current state is SENDING");
2015 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2016 ca_mutex_unlock(g_threadSendStateMutex);
2017 return CA_STATUS_OK;
2020 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2023 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2024 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2025 CALEClientSendFinish(env, gatt);
2026 ca_mutex_unlock(g_threadSendStateMutex);
2027 return CA_STATUS_FAILED;
2030 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2032 ca_mutex_unlock(g_threadSendStateMutex);
2035 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2036 if (!jni_obj_character)
2038 CALEClientSendFinish(env, gatt);
2039 return CA_STATUS_FAILED;
2042 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2043 if (CA_STATUS_OK != ret)
2045 CALEClientSendFinish(env, gatt);
2046 return CA_STATUS_FAILED;
2049 // wait for callback for write Characteristic with success to sent data
2050 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2051 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2052 if (!g_isSignalSetFlag)
2054 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2055 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2056 g_threadWriteCharacteristicMutex,
2057 WAIT_TIME_WRITE_CHARACTERISTIC))
2059 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2060 g_isSignalSetFlag = false;
2061 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2062 return CA_STATUS_FAILED;
2065 // reset flag set by writeCharacteristic Callback
2066 g_isSignalSetFlag = false;
2067 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2069 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2070 return CA_STATUS_OK;
2073 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2075 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2076 VERIFY_NON_NULL(env, TAG, "env is null");
2077 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2079 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2080 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2081 CALEWriteCharacteristicThread, (void*)gattParam))
2083 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2084 return CA_STATUS_FAILED;
2087 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2088 return CA_STATUS_OK;
2091 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2092 jobject gattCharacteristic)
2094 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2095 VERIFY_NON_NULL(env, TAG, "env is null");
2096 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2097 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2099 if (!CALEIsEnableBTAdapter(env))
2101 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2102 return CA_STATUS_FAILED;
2105 // get BluetoothGatt.write characteristic method
2106 OIC_LOG(DEBUG, TAG, "write characteristic method");
2107 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2108 "writeCharacteristic",
2109 "(Landroid/bluetooth/"
2110 "BluetoothGattCharacteristic;)Z");
2111 if (!jni_mid_writeCharacteristic)
2113 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2114 return CA_STATUS_FAILED;
2117 // call disconnect gatt method
2118 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2119 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2120 jni_mid_writeCharacteristic,
2121 gattCharacteristic);
2124 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2128 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2129 return CA_STATUS_FAILED;
2132 return CA_STATUS_OK;
2135 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2137 VERIFY_NON_NULL(env, TAG, "env is null");
2138 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2140 if (!CALEIsEnableBTAdapter(env))
2142 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2143 return CA_STATUS_FAILED;
2146 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2149 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2150 return CA_STATUS_FAILED;
2153 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2154 if (!jni_obj_GattCharacteristic)
2156 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2157 return CA_STATUS_FAILED;
2160 OIC_LOG(DEBUG, TAG, "read characteristic method");
2161 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2162 "readCharacteristic",
2163 "(Landroid/bluetooth/"
2164 "BluetoothGattCharacteristic;)Z");
2165 if (!jni_mid_readCharacteristic)
2167 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2168 return CA_STATUS_FAILED;
2171 // call disconnect gatt method
2172 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2173 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2174 jni_obj_GattCharacteristic);
2177 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2181 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2182 return CA_STATUS_FAILED;
2185 return CA_STATUS_OK;
2188 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2189 jobject characteristic)
2191 VERIFY_NON_NULL(env, TAG, "env is null");
2192 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2193 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2195 if (!CALEIsEnableBTAdapter(env))
2197 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2198 return CA_ADAPTER_NOT_ENABLED;
2201 // get BluetoothGatt.setCharacteristicNotification method
2202 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2203 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2204 "setCharacteristicNotification",
2205 "(Landroid/bluetooth/"
2206 "BluetoothGattCharacteristic;Z)Z");
2207 if (!jni_mid_setNotification)
2209 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2210 return CA_STATUS_FAILED;
2213 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2214 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2215 characteristic, JNI_TRUE);
2216 if (JNI_TRUE == ret)
2218 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2222 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2223 return CA_STATUS_FAILED;
2226 return CA_STATUS_OK;
2229 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2231 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2232 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2233 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2235 if (!CALEIsEnableBTAdapter(env))
2237 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2241 // get BluetoothGatt.getService method
2242 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2243 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2245 "(Ljava/util/UUID;)Landroid/bluetooth/"
2246 "BluetoothGattService;");
2247 if (!jni_mid_getService)
2249 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2253 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2254 if (!jni_obj_service_uuid)
2256 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2260 // get bluetooth gatt service
2261 OIC_LOG(DEBUG, TAG, "request to get service");
2262 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2263 jni_obj_service_uuid);
2264 if (!jni_obj_gattService)
2266 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2270 // get bluetooth gatt service method
2271 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2272 "BluetoothGattService",
2273 "getCharacteristic",
2274 "(Ljava/util/UUID;)"
2275 "Landroid/bluetooth/"
2276 "BluetoothGattCharacteristic;");
2277 if (!jni_mid_getCharacteristic)
2279 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2283 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2286 OIC_LOG(ERROR, TAG, "uuid is null");
2290 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2291 if (!jni_obj_tx_uuid)
2293 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2294 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2298 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2299 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2300 jni_mid_getCharacteristic,
2303 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2304 return jni_obj_GattCharacteristic;
2307 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2309 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2310 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2311 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2312 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2314 if (!CALEIsEnableBTAdapter(env))
2316 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2320 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2323 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2327 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2328 if (!jni_obj_GattCharacteristic)
2330 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2334 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2335 "/BluetoothGattCharacteristic");
2336 if (!jni_cid_BTGattCharacteristic)
2338 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2342 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2343 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2345 if (!jni_mid_setValue)
2347 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2351 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2353 if (JNI_TRUE == ret)
2355 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2359 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2364 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2365 "setWriteType", "(I)V");
2366 if (!jni_mid_setWriteType)
2368 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2372 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2373 "WRITE_TYPE_NO_RESPONSE", "I");
2374 if (!jni_fid_no_response)
2376 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2380 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2381 jni_fid_no_response);
2383 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2385 return jni_obj_GattCharacteristic;
2388 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2390 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2391 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2393 if (!CALEIsEnableBTAdapter(env))
2395 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2399 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2400 "BluetoothGattCharacteristic",
2401 "getValue", "()[B");
2402 if (!jni_mid_getValue)
2404 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2408 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2410 return jni_obj_data_array;
2413 CAResult_t CALEClientCreateUUIDList()
2417 OIC_LOG(ERROR, TAG, "g_jvm is null");
2418 return CA_STATUS_FAILED;
2421 bool isAttached = false;
2423 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2426 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2427 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2431 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2432 return CA_STATUS_FAILED;
2437 // create new object array
2438 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2439 if (!jni_cid_uuid_list)
2441 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2445 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2446 jni_cid_uuid_list, NULL);
2447 if (!jni_obj_uuid_list)
2449 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2454 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2457 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2460 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2462 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2466 (*g_jvm)->DetachCurrentThread(g_jvm);
2469 return CA_STATUS_OK;
2476 (*g_jvm)->DetachCurrentThread(g_jvm);
2478 return CA_STATUS_FAILED;
2481 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2482 jobject characteristic)
2484 VERIFY_NON_NULL(env, TAG, "env is null");
2485 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2486 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2488 if (!CALEIsEnableBTAdapter(env))
2490 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2491 return CA_ADAPTER_NOT_ENABLED;
2494 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2495 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2496 "BluetoothGattCharacteristic",
2498 "(Ljava/util/UUID;)Landroid/bluetooth/"
2499 "BluetoothGattDescriptor;");
2500 if (!jni_mid_getDescriptor)
2502 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2503 return CA_STATUS_FAILED;
2506 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2507 if (!jni_obj_cc_uuid)
2509 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2510 return CA_STATUS_FAILED;
2513 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2514 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2515 jni_mid_getDescriptor, jni_obj_cc_uuid);
2516 if (!jni_obj_descriptor)
2518 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2519 return CA_NOT_SUPPORTED;
2522 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2523 jclass jni_cid_descriptor = (*env)->FindClass(env,
2524 "android/bluetooth/BluetoothGattDescriptor");
2525 if (!jni_cid_descriptor)
2527 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2528 return CA_STATUS_FAILED;
2531 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2532 if (!jni_mid_setValue)
2534 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2535 return CA_STATUS_FAILED;
2538 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2539 "ENABLE_NOTIFICATION_VALUE", "[B");
2540 if (!jni_fid_NotiValue)
2542 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2543 return CA_STATUS_FAILED;
2546 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2548 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2549 env, jni_obj_descriptor, jni_mid_setValue,
2550 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2553 OIC_LOG(DEBUG, TAG, "setValue success");
2557 OIC_LOG(ERROR, TAG, "setValue has failed");
2558 return CA_STATUS_FAILED;
2561 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2563 "(Landroid/bluetooth/"
2564 "BluetoothGattDescriptor;)Z");
2565 if (!jni_mid_writeDescriptor)
2567 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2568 return CA_STATUS_FAILED;
2571 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2572 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2573 jni_obj_descriptor);
2576 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2580 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2581 return CA_STATUS_FAILED;
2584 return CA_STATUS_OK;
2587 void CALEClientCreateScanDeviceList(JNIEnv *env)
2589 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2590 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2592 ca_mutex_lock(g_deviceListMutex);
2593 // create new object array
2594 if (g_deviceList == NULL)
2596 OIC_LOG(DEBUG, TAG, "Create device list");
2598 g_deviceList = u_arraylist_create();
2600 ca_mutex_unlock(g_deviceListMutex);
2603 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2605 VERIFY_NON_NULL(device, TAG, "device is null");
2606 VERIFY_NON_NULL(env, TAG, "env is null");
2608 ca_mutex_lock(g_deviceListMutex);
2612 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2614 CALEClientSetScanFlag(false);
2615 if (CA_STATUS_OK != CALEClientStopScan())
2617 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2620 ca_mutex_unlock(g_deviceListMutex);
2621 return CA_STATUS_FAILED;
2624 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2625 if (!jni_remoteAddress)
2627 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2628 ca_mutex_unlock(g_deviceListMutex);
2629 return CA_STATUS_FAILED;
2632 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2635 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2636 ca_mutex_unlock(g_deviceListMutex);
2637 return CA_STATUS_FAILED;
2640 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2642 jobject gdevice = (*env)->NewGlobalRef(env, device);
2643 u_arraylist_add(g_deviceList, gdevice);
2644 ca_cond_signal(g_deviceDescCond);
2645 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2647 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2649 ca_mutex_unlock(g_deviceListMutex);
2651 return CA_STATUS_OK;
2654 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2656 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2657 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2661 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2665 uint32_t length = u_arraylist_length(g_deviceList);
2666 for (uint32_t index = 0; index < length; index++)
2668 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2671 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2675 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2676 if (!jni_setAddress)
2678 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2682 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2685 OIC_LOG(ERROR, TAG, "setAddress is null");
2689 if (!strcmp(remoteAddress, setAddress))
2691 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2695 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2698 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2703 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2705 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2706 VERIFY_NON_NULL(env, TAG, "env is null");
2708 ca_mutex_lock(g_deviceListMutex);
2712 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2713 ca_mutex_unlock(g_deviceListMutex);
2714 return CA_STATUS_FAILED;
2717 uint32_t length = u_arraylist_length(g_deviceList);
2718 for (uint32_t index = 0; index < length; index++)
2720 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2723 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2726 (*env)->DeleteGlobalRef(env, jarrayObj);
2730 OICFree(g_deviceList);
2731 g_deviceList = NULL;
2733 ca_mutex_unlock(g_deviceListMutex);
2734 return CA_STATUS_OK;
2737 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2739 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2740 VERIFY_NON_NULL(address, TAG, "address is null");
2741 VERIFY_NON_NULL(env, TAG, "env is null");
2743 ca_mutex_lock(g_deviceListMutex);
2747 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2748 ca_mutex_unlock(g_deviceListMutex);
2749 return CA_STATUS_FAILED;
2752 uint32_t length = u_arraylist_length(g_deviceList);
2753 for (uint32_t index = 0; index < length; index++)
2755 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2758 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2759 ca_mutex_unlock(g_deviceListMutex);
2760 return CA_STATUS_FAILED;
2763 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2764 if (!jni_setAddress)
2766 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2767 ca_mutex_unlock(g_deviceListMutex);
2768 return CA_STATUS_FAILED;
2771 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2774 OIC_LOG(ERROR, TAG, "setAddress is null");
2775 ca_mutex_unlock(g_deviceListMutex);
2776 return CA_STATUS_FAILED;
2779 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2782 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2783 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2784 ca_mutex_unlock(g_deviceListMutex);
2785 return CA_STATUS_FAILED;
2788 if (!strcmp(setAddress, remoteAddress))
2790 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2791 (*env)->DeleteGlobalRef(env, jarrayObj);
2793 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2794 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2796 if (NULL == u_arraylist_remove(g_deviceList, index))
2798 OIC_LOG(ERROR, TAG, "List removal failed.");
2799 ca_mutex_unlock(g_deviceListMutex);
2800 return CA_STATUS_FAILED;
2802 ca_mutex_unlock(g_deviceListMutex);
2803 return CA_STATUS_OK;
2805 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2806 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2809 ca_mutex_unlock(g_deviceListMutex);
2810 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2812 return CA_STATUS_OK;
2819 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2821 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2822 VERIFY_NON_NULL(env, TAG, "env is null");
2823 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2825 ca_mutex_lock(g_gattObjectMutex);
2827 if (!g_gattObjectList)
2829 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2830 ca_mutex_unlock(g_gattObjectMutex);
2831 return CA_STATUS_FAILED;
2834 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2835 if (!jni_remoteAddress)
2837 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2838 ca_mutex_unlock(g_gattObjectMutex);
2839 return CA_STATUS_FAILED;
2842 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2845 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2846 ca_mutex_unlock(g_gattObjectMutex);
2847 return CA_STATUS_FAILED;
2850 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
2851 if (!CALEClientIsGattObjInList(env, remoteAddress))
2853 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2854 u_arraylist_add(g_gattObjectList, newGatt);
2855 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
2858 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2859 ca_mutex_unlock(g_gattObjectMutex);
2860 return CA_STATUS_OK;
2863 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2865 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2866 VERIFY_NON_NULL(env, TAG, "env is null");
2867 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2869 uint32_t length = u_arraylist_length(g_gattObjectList);
2870 for (uint32_t index = 0; index < length; index++)
2873 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2876 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2880 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2881 if (!jni_setAddress)
2883 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2887 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2890 OIC_LOG(ERROR, TAG, "setAddress is null");
2894 if (!strcmp(remoteAddress, setAddress))
2896 OIC_LOG(DEBUG, TAG, "the device is already set");
2897 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2902 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2907 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2911 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2913 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2914 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2915 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2917 ca_mutex_lock(g_gattObjectMutex);
2918 uint32_t length = u_arraylist_length(g_gattObjectList);
2919 for (uint32_t index = 0; index < length; index++)
2921 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2924 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2925 ca_mutex_unlock(g_gattObjectMutex);
2929 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2930 if (!jni_setAddress)
2932 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2933 ca_mutex_unlock(g_gattObjectMutex);
2937 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2940 OIC_LOG(ERROR, TAG, "setAddress is null");
2941 ca_mutex_unlock(g_gattObjectMutex);
2945 if (!strcmp(remoteAddress, setAddress))
2947 OIC_LOG(DEBUG, TAG, "the device is already set");
2948 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2949 ca_mutex_unlock(g_gattObjectMutex);
2952 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2955 ca_mutex_unlock(g_gattObjectMutex);
2956 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2960 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2962 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2963 VERIFY_NON_NULL(env, TAG, "env is null");
2965 ca_mutex_lock(g_gattObjectMutex);
2966 if (!g_gattObjectList)
2968 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2969 ca_mutex_unlock(g_gattObjectMutex);
2970 return CA_STATUS_OK;
2973 uint32_t length = u_arraylist_length(g_gattObjectList);
2974 for (uint32_t index = 0; index < length; index++)
2976 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2979 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2982 (*env)->DeleteGlobalRef(env, jarrayObj);
2986 OICFree(g_gattObjectList);
2987 g_gattObjectList = NULL;
2988 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2989 ca_mutex_unlock(g_gattObjectMutex);
2990 return CA_STATUS_OK;
2993 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2995 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2996 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2997 VERIFY_NON_NULL(env, TAG, "env is null");
2999 ca_mutex_lock(g_gattObjectMutex);
3000 if (!g_gattObjectList)
3002 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3003 ca_mutex_unlock(g_gattObjectMutex);
3004 return CA_STATUS_OK;
3007 uint32_t length = u_arraylist_length(g_gattObjectList);
3008 for (uint32_t index = 0; index < length; index++)
3010 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3013 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3014 ca_mutex_unlock(g_gattObjectMutex);
3015 return CA_STATUS_FAILED;
3018 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3019 if (!jni_setAddress)
3021 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3022 ca_mutex_unlock(g_gattObjectMutex);
3023 return CA_STATUS_FAILED;
3026 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3029 OIC_LOG(ERROR, TAG, "setAddress is null");
3030 ca_mutex_unlock(g_gattObjectMutex);
3031 return CA_STATUS_FAILED;
3034 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3035 if (!jni_remoteAddress)
3037 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3038 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3039 ca_mutex_unlock(g_gattObjectMutex);
3040 return CA_STATUS_FAILED;
3043 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3046 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3047 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3048 ca_mutex_unlock(g_gattObjectMutex);
3049 return CA_STATUS_FAILED;
3052 if (!strcmp(setAddress, remoteAddress))
3054 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3055 (*env)->DeleteGlobalRef(env, jarrayObj);
3057 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3058 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3060 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3062 OIC_LOG(ERROR, TAG, "List removal failed.");
3063 ca_mutex_unlock(g_gattObjectMutex);
3064 return CA_STATUS_FAILED;
3066 ca_mutex_unlock(g_gattObjectMutex);
3067 return CA_STATUS_OK;
3069 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3070 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3073 ca_mutex_unlock(g_gattObjectMutex);
3074 OIC_LOG(DEBUG, TAG, "there are no target object");
3075 return CA_STATUS_OK;
3078 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3080 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3081 VERIFY_NON_NULL(addr, TAG, "addr is null");
3082 VERIFY_NON_NULL(env, TAG, "env is null");
3084 ca_mutex_lock(g_gattObjectMutex);
3085 if (!g_gattObjectList)
3087 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3088 ca_mutex_unlock(g_gattObjectMutex);
3089 return CA_STATUS_OK;
3092 uint32_t length = u_arraylist_length(g_gattObjectList);
3093 for (uint32_t index = 0; index < length; index++)
3095 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3098 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3099 ca_mutex_unlock(g_gattObjectMutex);
3100 return CA_STATUS_FAILED;
3103 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3104 if (!jni_setAddress)
3106 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3107 ca_mutex_unlock(g_gattObjectMutex);
3108 return CA_STATUS_FAILED;
3111 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3114 OIC_LOG(ERROR, TAG, "setAddress is null");
3115 ca_mutex_unlock(g_gattObjectMutex);
3116 return CA_STATUS_FAILED;
3119 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3122 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3123 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3124 ca_mutex_unlock(g_gattObjectMutex);
3125 return CA_STATUS_FAILED;
3128 if (!strcmp(setAddress, remoteAddress))
3130 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3131 (*env)->DeleteGlobalRef(env, jarrayObj);
3133 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3134 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3135 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3137 OIC_LOG(ERROR, TAG, "List removal failed.");
3138 ca_mutex_unlock(g_gattObjectMutex);
3139 return CA_STATUS_FAILED;
3141 ca_mutex_unlock(g_gattObjectMutex);
3142 return CA_STATUS_OK;
3144 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3145 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3148 ca_mutex_unlock(g_gattObjectMutex);
3149 OIC_LOG(DEBUG, TAG, "there are no target object");
3150 return CA_STATUS_FAILED;
3153 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3155 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3157 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3158 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3160 // get Bluetooth Address
3161 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3162 if (!jni_btTargetAddress)
3164 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3168 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3171 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3175 // get method ID of getDevice()
3176 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3177 "getDevice", METHODID_BT_DEVICE);
3178 if (!jni_mid_getDevice)
3180 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3181 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3185 ca_mutex_lock(g_gattObjectMutex);
3187 size_t length = u_arraylist_length(g_gattObjectList);
3188 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3189 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3191 for (size_t index = 0; index < length; index++)
3193 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3196 ca_mutex_unlock(g_gattObjectMutex);
3197 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3198 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3202 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3203 if (!jni_obj_device)
3205 ca_mutex_unlock(g_gattObjectMutex);
3206 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3207 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3211 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3214 ca_mutex_unlock(g_gattObjectMutex);
3215 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3216 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3220 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3223 ca_mutex_unlock(g_gattObjectMutex);
3224 OIC_LOG(ERROR, TAG, "btAddress is not available");
3225 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3229 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3230 if (!strcmp(targetAddress, btAddress))
3232 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3235 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3238 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3240 ca_mutex_unlock(g_gattObjectMutex);
3241 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3242 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3243 (*env)->DeleteLocalRef(env, jni_btAddress);
3244 (*env)->DeleteLocalRef(env, jni_obj_device);
3245 return jni_LEAddress;
3247 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3248 (*env)->DeleteLocalRef(env, jni_btAddress);
3249 (*env)->DeleteLocalRef(env, jni_obj_device);
3251 ca_mutex_unlock(g_gattObjectMutex);
3253 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3254 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3262 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3263 uint16_t target_state)
3265 VERIFY_NON_NULL(address, TAG, "address is null");
3266 VERIFY_NON_NULL(address, TAG, "state_type is null");
3267 VERIFY_NON_NULL(address, TAG, "target_state is null");
3269 if (!g_deviceStateList)
3271 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3272 return CA_STATUS_FAILED;
3275 ca_mutex_lock(g_deviceStateListMutex);
3277 if (CALEClientIsDeviceInList(address))
3279 CALEState_t* curState = CALEClientGetStateInfo(address);
3282 OIC_LOG(ERROR, TAG, "curState is null");
3283 ca_mutex_unlock(g_deviceStateListMutex);
3284 return CA_STATUS_FAILED;
3289 case CA_LE_CONNECTION_STATE:
3290 curState->connectedState = target_state;
3292 case CA_LE_SEND_STATE:
3293 curState->sendState = target_state;
3298 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3299 curState->address, curState->connectedState, curState->sendState,
3300 curState->autoConnectFlag);
3302 else /** state is added newly **/
3304 if (strlen(address) > CA_MACADDR_SIZE)
3306 OIC_LOG(ERROR, TAG, "address is not proper");
3307 ca_mutex_unlock(g_deviceStateListMutex);
3308 return CA_STATUS_INVALID_PARAM;
3311 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3314 OIC_LOG(ERROR, TAG, "out of memory");
3315 ca_mutex_unlock(g_deviceStateListMutex);
3316 return CA_MEMORY_ALLOC_FAILED;
3319 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3323 case CA_LE_CONNECTION_STATE:
3324 newstate->connectedState = target_state;
3325 newstate->sendState = STATE_SEND_NONE;
3327 case CA_LE_SEND_STATE:
3328 newstate->connectedState = STATE_DISCONNECTED;
3329 newstate->sendState = target_state;
3334 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3335 "conn : %d, send : %d, ACFlag : %d",
3336 newstate->address, newstate->connectedState, newstate->sendState,
3337 newstate->autoConnectFlag);
3338 u_arraylist_add(g_deviceStateList, newstate); // update new state
3341 ca_mutex_unlock(g_deviceStateListMutex);
3343 return CA_STATUS_OK;
3346 bool CALEClientIsDeviceInList(const char* remoteAddress)
3348 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3350 if (!g_deviceStateList)
3352 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3356 uint32_t length = u_arraylist_length(g_deviceStateList);
3357 for (uint32_t index = 0; index < length; index++)
3359 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3362 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3366 if (!strcmp(remoteAddress, state->address))
3368 OIC_LOG(DEBUG, TAG, "the device is already set");
3377 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3381 CAResult_t CALEClientRemoveAllDeviceState()
3383 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3385 ca_mutex_lock(g_deviceStateListMutex);
3386 if (!g_deviceStateList)
3388 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3389 ca_mutex_unlock(g_deviceStateListMutex);
3390 return CA_STATUS_FAILED;
3393 uint32_t length = u_arraylist_length(g_deviceStateList);
3394 for (uint32_t index = 0; index < length; index++)
3396 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3399 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3405 OICFree(g_deviceStateList);
3406 g_deviceStateList = NULL;
3407 ca_mutex_unlock(g_deviceStateListMutex);
3409 return CA_STATUS_OK;
3412 CAResult_t CALEClientResetDeviceStateForAll()
3414 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
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 size_t length = u_arraylist_length(g_deviceStateList);
3425 for (size_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");
3434 // autoConnectFlag value will be not changed,
3435 // since it has reset only termination case.
3436 state->connectedState = STATE_DISCONNECTED;
3437 state->sendState = STATE_SEND_NONE;
3439 ca_mutex_unlock(g_deviceStateListMutex);
3441 return CA_STATUS_OK;
3444 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3446 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3447 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3449 if (!g_deviceStateList)
3451 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3452 return CA_STATUS_FAILED;
3455 uint32_t length = u_arraylist_length(g_deviceStateList);
3456 for (uint32_t index = 0; index < length; index++)
3458 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3461 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3465 if (!strcmp(state->address, remoteAddress))
3467 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3469 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3471 if (NULL == targetState)
3473 OIC_LOG(ERROR, TAG, "List removal failed.");
3474 return CA_STATUS_FAILED;
3477 OICFree(targetState);
3478 return CA_STATUS_OK;
3482 return CA_STATUS_OK;
3485 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3487 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3489 if (!g_deviceStateList)
3491 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3495 uint32_t length = u_arraylist_length(g_deviceStateList);
3496 OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
3497 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3499 for (uint32_t index = 0; index < length; index++)
3501 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3504 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3508 OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
3510 if (!strcmp(state->address, remoteAddress))
3512 OIC_LOG(DEBUG, TAG, "found state");
3517 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
3521 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3522 uint16_t target_state)
3524 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3525 state_type, target_state);
3526 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3528 ca_mutex_lock(g_deviceStateListMutex);
3529 if (!g_deviceStateList)
3531 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3532 ca_mutex_unlock(g_deviceStateListMutex);
3536 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3539 OIC_LOG(ERROR, TAG, "state is null");
3540 ca_mutex_unlock(g_deviceStateListMutex);
3544 uint16_t curValue = 0;
3547 case CA_LE_CONNECTION_STATE:
3548 curValue = state->connectedState;
3550 case CA_LE_SEND_STATE:
3551 curValue = state->sendState;
3557 if (target_state == curValue)
3559 ca_mutex_unlock(g_deviceStateListMutex);
3564 ca_mutex_unlock(g_deviceStateListMutex);
3568 ca_mutex_unlock(g_deviceStateListMutex);
3572 void CALEClientCreateDeviceList()
3574 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3576 // create new object array
3577 if (!g_gattObjectList)
3579 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3581 g_gattObjectList = u_arraylist_create();
3584 if (!g_deviceStateList)
3586 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3588 g_deviceStateList = u_arraylist_create();
3593 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3595 g_deviceList = u_arraylist_create();
3600 * Check Sent Count for remove g_sendBuffer
3602 void CALEClientUpdateSendCnt(JNIEnv *env)
3604 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3606 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3608 ca_mutex_lock(g_threadMutex);
3612 if (g_targetCnt <= g_currentSentCnt)
3615 g_currentSentCnt = 0;
3619 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3620 g_sendBuffer = NULL;
3622 // notity the thread
3623 ca_cond_signal(g_threadCond);
3625 CALEClientSetSendFinishFlag(true);
3626 OIC_LOG(DEBUG, TAG, "set signal for send data");
3629 ca_mutex_unlock(g_threadMutex);
3632 CAResult_t CALEClientInitGattMutexVaraibles()
3634 if (NULL == g_bleReqRespClientCbMutex)
3636 g_bleReqRespClientCbMutex = ca_mutex_new();
3637 if (NULL == g_bleReqRespClientCbMutex)
3639 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3640 return CA_STATUS_FAILED;
3644 if (NULL == g_bleServerBDAddressMutex)
3646 g_bleServerBDAddressMutex = ca_mutex_new();
3647 if (NULL == g_bleServerBDAddressMutex)
3649 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3650 return CA_STATUS_FAILED;
3654 if (NULL == g_threadMutex)
3656 g_threadMutex = ca_mutex_new();
3657 if (NULL == g_threadMutex)
3659 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3660 return CA_STATUS_FAILED;
3664 if (NULL == g_threadSendMutex)
3666 g_threadSendMutex = ca_mutex_new();
3667 if (NULL == g_threadSendMutex)
3669 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3670 return CA_STATUS_FAILED;
3674 if (NULL == g_deviceListMutex)
3676 g_deviceListMutex = ca_mutex_new();
3677 if (NULL == g_deviceListMutex)
3679 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3680 return CA_STATUS_FAILED;
3684 if (NULL == g_gattObjectMutex)
3686 g_gattObjectMutex = ca_mutex_new();
3687 if (NULL == g_gattObjectMutex)
3689 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3690 return CA_STATUS_FAILED;
3694 if (NULL == g_deviceStateListMutex)
3696 g_deviceStateListMutex = ca_mutex_new();
3697 if (NULL == g_deviceStateListMutex)
3699 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3700 return CA_STATUS_FAILED;
3704 if (NULL == g_SendFinishMutex)
3706 g_SendFinishMutex = ca_mutex_new();
3707 if (NULL == g_SendFinishMutex)
3709 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3710 return CA_STATUS_FAILED;
3714 if (NULL == g_scanMutex)
3716 g_scanMutex = ca_mutex_new();
3717 if (NULL == g_scanMutex)
3719 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3720 return CA_STATUS_FAILED;
3724 if (NULL == g_threadWriteCharacteristicMutex)
3726 g_threadWriteCharacteristicMutex = ca_mutex_new();
3727 if (NULL == g_threadWriteCharacteristicMutex)
3729 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3730 return CA_STATUS_FAILED;
3734 if (NULL == g_deviceScanRetryDelayMutex)
3736 g_deviceScanRetryDelayMutex = ca_mutex_new();
3737 if (NULL == g_deviceScanRetryDelayMutex)
3739 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3740 return CA_STATUS_FAILED;
3744 if (NULL == g_threadSendStateMutex)
3746 g_threadSendStateMutex = ca_mutex_new();
3747 if (NULL == g_threadSendStateMutex)
3749 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3750 return CA_STATUS_FAILED;
3754 return CA_STATUS_OK;
3757 void CALEClientTerminateGattMutexVariables()
3759 ca_mutex_free(g_bleReqRespClientCbMutex);
3760 g_bleReqRespClientCbMutex = NULL;
3762 ca_mutex_free(g_bleServerBDAddressMutex);
3763 g_bleServerBDAddressMutex = NULL;
3765 ca_mutex_free(g_threadMutex);
3766 g_threadMutex = NULL;
3768 ca_mutex_free(g_threadSendMutex);
3769 g_threadSendMutex = NULL;
3771 ca_mutex_free(g_deviceListMutex);
3772 g_deviceListMutex = NULL;
3774 ca_mutex_free(g_SendFinishMutex);
3775 g_SendFinishMutex = NULL;
3777 ca_mutex_free(g_scanMutex);
3780 ca_mutex_free(g_threadWriteCharacteristicMutex);
3781 g_threadWriteCharacteristicMutex = NULL;
3783 ca_mutex_free(g_deviceScanRetryDelayMutex);
3784 g_deviceScanRetryDelayMutex = NULL;
3786 ca_mutex_free(g_threadSendStateMutex);
3787 g_threadSendStateMutex = NULL;
3790 void CALEClientSetSendFinishFlag(bool flag)
3792 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3794 ca_mutex_lock(g_SendFinishMutex);
3795 g_isFinishedSendData = flag;
3796 ca_mutex_unlock(g_SendFinishMutex);
3803 CAResult_t CAStartLEGattClient()
3805 // init mutex for send logic
3806 if (!g_deviceDescCond)
3808 g_deviceDescCond = ca_cond_new();
3813 g_threadCond = ca_cond_new();
3816 if (!g_threadWriteCharacteristicCond)
3818 g_threadWriteCharacteristicCond = ca_cond_new();
3821 CAResult_t ret = CALEClientStartScan();
3822 if (CA_STATUS_OK != ret)
3824 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3828 g_isStartedLEClient = true;
3829 return CA_STATUS_OK;
3832 void CAStopLEGattClient()
3834 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3838 OIC_LOG(ERROR, TAG, "g_jvm is null");
3842 bool isAttached = false;
3844 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3847 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3848 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3852 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3858 CAResult_t ret = CALEClientDisconnectAll(env);
3859 if (CA_STATUS_OK != ret)
3861 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3864 ret = CALEClientStopScan();
3865 if(CA_STATUS_OK != ret)
3867 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3870 ca_mutex_lock(g_threadMutex);
3871 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3872 ca_cond_signal(g_threadCond);
3873 CALEClientSetSendFinishFlag(true);
3874 ca_mutex_unlock(g_threadMutex);
3876 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3877 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3878 ca_cond_signal(g_threadWriteCharacteristicCond);
3879 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3881 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3882 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3883 ca_cond_signal(g_deviceScanRetryDelayCond);
3884 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3886 ca_cond_free(g_deviceDescCond);
3887 ca_cond_free(g_threadCond);
3888 ca_cond_free(g_threadWriteCharacteristicCond);
3889 ca_cond_free(g_deviceScanRetryDelayCond);
3891 g_deviceDescCond = NULL;
3892 g_threadCond = NULL;
3893 g_threadWriteCharacteristicCond = NULL;
3894 g_deviceScanRetryDelayCond = NULL;
3898 (*g_jvm)->DetachCurrentThread(g_jvm);
3903 CAResult_t CAInitializeLEGattClient()
3905 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3906 CALEClientInitialize();
3907 return CA_STATUS_OK;
3910 void CATerminateLEGattClient()
3912 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3913 CAStopLEGattClient();
3914 CALEClientTerminate();
3917 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3918 uint32_t dataLen, CALETransferType_t type,
3921 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3922 VERIFY_NON_NULL(data, TAG, "data is null");
3923 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3925 if (LE_UNICAST != type || position < 0)
3927 OIC_LOG(ERROR, TAG, "this request is not unicast");
3928 return CA_STATUS_INVALID_PARAM;
3931 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3934 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3936 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3937 VERIFY_NON_NULL(data, TAG, "data is null");
3939 return CALEClientSendMulticastMessage(data, dataLen);
3942 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3944 ca_mutex_lock(g_bleReqRespClientCbMutex);
3945 g_CABLEClientDataReceivedCallback = callback;
3946 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3949 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3951 g_threadPoolHandle = handle;
3954 CAResult_t CAGetLEAddress(char **local_address)
3956 VERIFY_NON_NULL(local_address, TAG, "local_address");
3957 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3958 return CA_NOT_SUPPORTED;
3961 JNIEXPORT void JNICALL
3962 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3965 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3966 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3967 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3968 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3970 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3973 JNIEXPORT void JNICALL
3974 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3977 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3978 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3979 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3980 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3982 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3985 JNIEXPORT void JNICALL
3986 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3989 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3990 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3991 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3993 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3994 if (CA_STATUS_OK != res)
3996 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4000 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4002 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4004 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4005 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4007 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
4008 "getDevice", METHODID_BT_DEVICE);
4009 if (!jni_mid_getDevice)
4011 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4015 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4016 if (!jni_obj_device)
4018 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4022 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4025 OIC_LOG(ERROR, TAG, "jni_address is null");
4029 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4034 * Class: org_iotivity_ca_jar_caleinterface
4035 * Method: CALeGattConnectionStateChangeCallback
4036 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4038 JNIEXPORT void JNICALL
4039 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4045 OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4047 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4048 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4049 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4051 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4053 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4056 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4060 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4063 OIC_LOG(ERROR, TAG, "address is null");
4066 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
4069 if (state_connected == newstate)
4071 OIC_LOG(DEBUG, TAG, "LE is connected");
4072 if (GATT_SUCCESS == status)
4074 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_CONNECTED);
4075 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4076 if (CA_STATUS_OK != res)
4078 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4082 res = CALEClientAddGattobjToList(env, gatt);
4083 if (CA_STATUS_OK != res)
4085 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4089 res = CALEClientDiscoverServices(env, gatt);
4090 if (CA_STATUS_OK != res)
4092 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4098 OIC_LOG(INFO, TAG, "unknown status");
4099 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4102 else // STATE_DISCONNECTED == newstate
4104 OIC_LOG(DEBUG, TAG, "LE is disconnected");
4106 res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE, STATE_DISCONNECTED);
4107 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4108 if (CA_STATUS_OK != res)
4110 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4114 res = CALEClientGattClose(env, gatt);
4115 if (CA_STATUS_OK != res)
4117 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4120 if (GATT_ERROR == status)
4122 // when we get GATT ERROR(0x85), gatt connection can be called again.
4123 OIC_LOG(INFO, TAG, "retry gatt connect");
4125 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4128 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4132 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4135 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4139 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4142 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4150 if (CALECheckConnectionStateValue(status))
4152 // this state is unexpected reason to disconnect
4153 // if the reason is suitable, connection logic of the device will be destroyed.
4154 OIC_LOG(INFO, TAG, "connection logic destroy");
4159 // other reason except for gatt_success is expected to running
4160 // background connection in BT platform.
4161 OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
4162 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);