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));
1080 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1081 return CA_STATUS_FAILED;
1086 return CA_STATUS_OK;
1089 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1091 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1092 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1094 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1095 "()Landroid/bluetooth/BluetoothDevice;");
1096 if (!jni_mid_getDevice)
1098 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1102 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1103 if (!jni_obj_device)
1105 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1109 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1112 OIC_LOG(ERROR, TAG, "jni_address is null");
1122 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1125 OIC_LOG(DEBUG, TAG, "Gatt Close");
1126 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1127 VERIFY_NON_NULL(env, TAG, "env is null");
1129 // get BluetoothGatt method
1130 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1131 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1132 if (!jni_mid_closeGatt)
1134 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1135 return CA_STATUS_OK;
1138 // call disconnect gatt method
1139 OIC_LOG(DEBUG, TAG, "request to close GATT");
1140 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1142 if ((*env)->ExceptionCheck(env))
1144 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1145 (*env)->ExceptionDescribe(env);
1146 (*env)->ExceptionClear(env);
1147 return CA_STATUS_FAILED;
1150 return CA_STATUS_OK;
1153 CAResult_t CALEClientStartScan()
1155 if (!g_isStartedLEClient)
1157 OIC_LOG(ERROR, TAG, "LE client is not started");
1158 return CA_STATUS_FAILED;
1163 OIC_LOG(ERROR, TAG, "g_jvm is null");
1164 return CA_STATUS_FAILED;
1167 if (g_isStartedScan)
1169 OIC_LOG(INFO, TAG, "scanning is already started");
1170 return CA_STATUS_OK;
1173 bool isAttached = false;
1175 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1178 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1180 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1183 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1184 return CA_STATUS_FAILED;
1189 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1191 CAResult_t ret = CA_STATUS_OK;
1192 // scan gatt server with UUID
1193 if (g_leScanCallback && g_uuidList)
1196 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1198 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1200 if (CA_STATUS_OK != ret)
1202 if (CA_ADAPTER_NOT_ENABLED == ret)
1204 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1208 OIC_LOG(ERROR, TAG, "start scan has failed");
1215 (*g_jvm)->DetachCurrentThread(g_jvm);
1221 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1223 VERIFY_NON_NULL(callback, TAG, "callback is null");
1224 VERIFY_NON_NULL(env, TAG, "env is null");
1226 if (!CALEIsEnableBTAdapter(env))
1228 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1229 return CA_ADAPTER_NOT_ENABLED;
1232 // get default bt adapter class
1233 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1234 if (!jni_cid_BTAdapter)
1236 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1237 return CA_STATUS_FAILED;
1240 // get remote bt adapter method
1241 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1242 "getDefaultAdapter",
1243 METHODID_OBJECTNONPARAM);
1244 if (!jni_mid_getDefaultAdapter)
1246 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1247 return CA_STATUS_FAILED;
1250 // get start le scan method
1251 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1252 "(Landroid/bluetooth/BluetoothAdapter$"
1253 "LeScanCallback;)Z");
1254 if (!jni_mid_startLeScan)
1256 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1257 return CA_STATUS_FAILED;
1260 // gat bt adapter object
1261 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1262 jni_mid_getDefaultAdapter);
1263 if (!jni_obj_BTAdapter)
1265 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1266 return CA_STATUS_FAILED;
1269 // call start le scan method
1270 OIC_LOG(INFO, TAG, "CALL API - startLeScan");
1271 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1272 jni_mid_startLeScan, callback);
1273 if (!jni_obj_startLeScan)
1275 OIC_LOG(INFO, TAG, "startLeScan has failed");
1279 OIC_LOG(DEBUG, TAG, "LeScan has started");
1280 CALEClientSetScanFlag(true);
1283 return CA_STATUS_OK;
1286 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1288 VERIFY_NON_NULL(callback, TAG, "callback is null");
1289 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1290 VERIFY_NON_NULL(env, TAG, "env is null");
1292 if (!CALEIsEnableBTAdapter(env))
1294 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1295 return CA_ADAPTER_NOT_ENABLED;
1298 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1299 if (!jni_cid_BTAdapter)
1301 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1302 return CA_STATUS_FAILED;
1305 // get remote bt adapter method
1306 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1307 "getDefaultAdapter",
1308 METHODID_OBJECTNONPARAM);
1309 if (!jni_mid_getDefaultAdapter)
1311 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1312 return CA_STATUS_FAILED;
1315 // get start le scan method
1316 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1317 "([Ljava/util/UUID;Landroid/bluetooth/"
1318 "BluetoothAdapter$LeScanCallback;)Z");
1319 if (!jni_mid_startLeScan)
1321 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1322 return CA_STATUS_FAILED;
1325 // get bt adapter object
1326 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1327 jni_mid_getDefaultAdapter);
1328 if (!jni_obj_BTAdapter)
1330 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1331 return CA_STATUS_FAILED;
1334 // call start le scan method
1335 OIC_LOG(INFO, TAG, "CALL API - startLeScan (with UUID)");
1336 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1337 jni_mid_startLeScan, uuids, callback);
1338 if (!jni_obj_startLeScan)
1340 OIC_LOG(INFO, TAG, "startLeScan has failed");
1344 OIC_LOG(DEBUG, TAG, "LeScan has started");
1345 CALEClientSetScanFlag(true);
1348 return CA_STATUS_OK;
1351 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1353 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1354 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1357 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1360 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1364 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1365 "(Ljava/lang/String;)"
1366 "Ljava/util/UUID;");
1367 if (!jni_mid_fromString)
1369 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1373 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1374 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1378 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1382 return jni_obj_uuid;
1385 CAResult_t CALEClientStopScan()
1389 OIC_LOG(ERROR, TAG, "g_jvm is null");
1390 return CA_STATUS_FAILED;
1393 if (!g_isStartedScan)
1395 OIC_LOG(INFO, TAG, "scanning is already stopped");
1396 return CA_STATUS_OK;
1399 bool isAttached = false;
1401 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1404 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1405 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1408 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1409 return CA_STATUS_FAILED;
1414 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1415 if (CA_STATUS_OK != ret)
1417 if (CA_ADAPTER_NOT_ENABLED == ret)
1419 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1423 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1428 CALEClientSetScanFlag(false);
1433 (*g_jvm)->DetachCurrentThread(g_jvm);
1439 void CALEClientSetScanFlag(bool flag)
1441 ca_mutex_lock(g_scanMutex);
1442 g_isStartedScan = flag;
1443 ca_mutex_unlock(g_scanMutex);
1446 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1448 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1449 VERIFY_NON_NULL(callback, TAG, "callback is null");
1450 VERIFY_NON_NULL(env, TAG, "env is null");
1452 if (!CALEIsEnableBTAdapter(env))
1454 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1455 return CA_ADAPTER_NOT_ENABLED;
1458 // get default bt adapter class
1459 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1460 if (!jni_cid_BTAdapter)
1462 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1463 return CA_STATUS_FAILED;
1466 // get remote bt adapter method
1467 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1468 "getDefaultAdapter",
1469 METHODID_OBJECTNONPARAM);
1470 if (!jni_mid_getDefaultAdapter)
1472 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1473 return CA_STATUS_FAILED;
1476 // get start le scan method
1477 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1478 "(Landroid/bluetooth/"
1479 "BluetoothAdapter$LeScanCallback;)V");
1480 if (!jni_mid_stopLeScan)
1482 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1483 return CA_STATUS_FAILED;
1486 // gat bt adapter object
1487 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1488 jni_mid_getDefaultAdapter);
1489 if (!jni_obj_BTAdapter)
1491 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1492 return CA_STATUS_FAILED;
1495 OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
1496 // call start le scan method
1497 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1498 if ((*env)->ExceptionCheck(env))
1500 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1501 (*env)->ExceptionDescribe(env);
1502 (*env)->ExceptionClear(env);
1503 return CA_STATUS_FAILED;
1506 return CA_STATUS_OK;
1509 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
1511 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1512 VERIFY_NON_NULL(env, TAG, "env");
1513 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1515 ca_mutex_lock(g_deviceStateListMutex);
1517 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1520 OIC_LOG(ERROR, TAG, "address is not available");
1521 return CA_STATUS_FAILED;
1524 if (CALEClientIsDeviceInList(address))
1526 CALEState_t* curState = CALEClientGetStateInfo(address);
1529 OIC_LOG(ERROR, TAG, "curState is null");
1530 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1531 ca_mutex_unlock(g_deviceStateListMutex);
1532 return CA_STATUS_FAILED;
1534 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1538 case CA_LE_AUTO_CONNECT_FLAG:
1539 curState->autoConnectFlag = flag;
1541 case CA_LE_DESCRIPTOR_FOUND:
1542 curState->isDescriptorFound = flag;
1549 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1550 ca_mutex_unlock(g_deviceStateListMutex);
1551 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1552 return CA_STATUS_OK;
1555 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1557 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1558 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1559 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1561 ca_mutex_lock(g_deviceStateListMutex);
1563 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1566 OIC_LOG(ERROR, TAG, "address is not available");
1567 ca_mutex_unlock(g_deviceStateListMutex);
1571 CALEState_t* curState = CALEClientGetStateInfo(address);
1572 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1575 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1576 ca_mutex_unlock(g_deviceStateListMutex);
1580 jboolean ret = JNI_FALSE;
1583 case CA_LE_AUTO_CONNECT_FLAG:
1584 ret = curState->autoConnectFlag;
1586 case CA_LE_DESCRIPTOR_FOUND:
1587 ret = curState->isDescriptorFound;
1592 ca_mutex_unlock(g_deviceStateListMutex);
1594 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1595 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1599 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1601 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1602 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1603 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1605 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1606 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1609 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1612 OIC_LOG(ERROR, TAG, "address is not available");
1616 // close the gatt service
1617 jobject gatt = CALEClientGetGattObjInList(env, address);
1620 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1621 if (CA_STATUS_OK != res)
1623 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1624 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1628 // clean previous gatt object after close profile service
1629 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1630 if (CA_STATUS_OK != res)
1632 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1633 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1637 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1640 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1643 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1647 // add new gatt object into g_gattObjectList
1648 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1649 if (CA_STATUS_OK != res)
1651 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1658 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1660 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1661 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1662 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1664 if (!g_leGattCallback)
1666 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1670 if (!CALEIsEnableBTAdapter(env))
1672 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1676 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1679 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1683 // get BluetoothDevice method
1684 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1685 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1687 "(Landroid/content/Context;ZLandroid/"
1688 "bluetooth/BluetoothGattCallback;)"
1689 "Landroid/bluetooth/BluetoothGatt;");
1690 if (!jni_mid_connectGatt)
1692 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1696 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1697 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1698 jni_mid_connectGatt,
1700 autoconnect, g_leGattCallback);
1701 if (!jni_obj_connectGatt)
1703 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1704 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1705 CALEClientUpdateSendCnt(env);
1710 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1712 return jni_obj_connectGatt;
1715 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1717 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1719 VERIFY_NON_NULL(env, TAG, "env is null");
1720 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1722 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1723 if (!jni_cid_BTAdapter)
1725 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1726 return CA_STATUS_FAILED;
1729 // get remote bt adapter method
1730 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1731 "getDefaultAdapter",
1732 METHODID_OBJECTNONPARAM);
1733 if (!jni_mid_getDefaultAdapter)
1735 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1736 return CA_STATUS_FAILED;
1739 // gat bt adapter object
1740 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1741 jni_mid_getDefaultAdapter);
1742 if (!jni_obj_BTAdapter)
1744 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1745 return CA_STATUS_FAILED;
1748 // get closeProfileProxy method
1749 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1750 "closeProfileProxy",
1751 "(ILandroid/bluetooth/"
1752 "BluetoothProfile;)V");
1753 if (!jni_mid_closeProfileProxy)
1755 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1756 return CA_STATUS_FAILED;
1759 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1760 if (!jni_cid_BTProfile)
1762 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1763 return CA_STATUS_FAILED;
1766 // GATT - Constant value : 7 (0x00000007)
1767 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1771 OIC_LOG(ERROR, TAG, "id_gatt is null");
1772 return CA_STATUS_FAILED;
1775 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1777 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1778 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1779 if ((*env)->ExceptionCheck(env))
1781 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1782 (*env)->ExceptionDescribe(env);
1783 (*env)->ExceptionClear(env);
1784 return CA_STATUS_FAILED;
1787 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1788 return CA_STATUS_OK;
1792 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1794 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1795 VERIFY_NON_NULL(env, TAG, "env is null");
1796 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1798 // get BluetoothGatt method
1799 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1800 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1801 "disconnect", "()V");
1802 if (!jni_mid_disconnectGatt)
1804 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1805 return CA_STATUS_FAILED;
1808 // call disconnect gatt method
1809 OIC_LOG(INFO, TAG, "CALL API - disconnect");
1810 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1811 if ((*env)->ExceptionCheck(env))
1813 OIC_LOG(ERROR, TAG, "disconnect has failed");
1814 (*env)->ExceptionDescribe(env);
1815 (*env)->ExceptionClear(env);
1816 return CA_STATUS_FAILED;
1819 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1821 return CA_STATUS_OK;
1824 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1826 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1827 VERIFY_NON_NULL(env, TAG, "env is null");
1829 if (!g_gattObjectList)
1831 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1832 return CA_STATUS_OK;
1835 uint32_t length = u_arraylist_length(g_gattObjectList);
1836 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1837 for (uint32_t index = 0; index < length; index++)
1839 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1840 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1843 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1846 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1847 if (CA_STATUS_OK != res)
1849 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1854 return CA_STATUS_OK;
1857 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1859 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1860 VERIFY_NON_NULL(env, TAG, "env is null");
1862 if (!g_gattObjectList)
1864 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1865 return CA_STATUS_OK;
1868 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1871 OIC_LOG(ERROR, TAG, "address is null");
1872 return CA_STATUS_FAILED;
1875 uint32_t length = u_arraylist_length(g_gattObjectList);
1876 for (uint32_t index = 0; index < length; index++)
1878 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1881 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1885 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1886 if (!jni_setAddress)
1888 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1889 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1890 return CA_STATUS_FAILED;
1893 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1896 OIC_LOG(ERROR, TAG, "setAddress is null");
1897 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1898 return CA_STATUS_FAILED;
1901 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1902 if (!strcmp(address, setAddress))
1904 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1905 if (CA_STATUS_OK != res)
1907 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1908 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1909 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1910 return CA_STATUS_FAILED;
1912 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1913 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1914 return CA_STATUS_OK;
1916 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1918 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1920 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1921 return CA_STATUS_OK;
1924 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1926 VERIFY_NON_NULL(env, TAG, "env is null");
1927 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1929 if (!CALEIsEnableBTAdapter(env))
1931 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1932 return CA_ADAPTER_NOT_ENABLED;
1935 // get BluetoothGatt.discoverServices method
1936 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1937 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1938 "discoverServices", "()Z");
1939 if (!jni_mid_discoverServices)
1941 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1942 return CA_STATUS_FAILED;
1945 // call disconnect gatt method
1946 OIC_LOG(INFO, TAG, "CALL API - discoverServices");
1947 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1950 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1951 return CA_STATUS_FAILED;
1954 return CA_STATUS_OK;
1957 static void CALEWriteCharacteristicThread(void* object)
1959 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1961 bool isAttached = false;
1963 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1966 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1967 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1971 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1977 jobject gatt = (jobject)object;
1978 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1979 if (CA_STATUS_OK != ret)
1981 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1986 (*g_jvm)->DetachCurrentThread(g_jvm);
1990 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1992 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
1994 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1995 VERIFY_NON_NULL(env, TAG, "env is null");
1997 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2000 CALEClientSendFinish(env, gatt);
2001 return CA_STATUS_FAILED;
2004 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2007 CALEClientSendFinish(env, gatt);
2008 return CA_STATUS_FAILED;
2011 ca_mutex_lock(g_threadSendStateMutex);
2013 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2015 OIC_LOG(INFO, TAG, "current state is SENDING");
2016 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2017 ca_mutex_unlock(g_threadSendStateMutex);
2018 return CA_STATUS_OK;
2021 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2024 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2025 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2026 CALEClientSendFinish(env, gatt);
2027 ca_mutex_unlock(g_threadSendStateMutex);
2028 return CA_STATUS_FAILED;
2031 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2033 ca_mutex_unlock(g_threadSendStateMutex);
2036 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2037 if (!jni_obj_character)
2039 CALEClientSendFinish(env, gatt);
2040 return CA_STATUS_FAILED;
2043 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2044 if (CA_STATUS_OK != ret)
2046 CALEClientSendFinish(env, gatt);
2047 return CA_STATUS_FAILED;
2050 // wait for callback for write Characteristic with success to sent data
2051 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2052 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2053 if (!g_isSignalSetFlag)
2055 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2056 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2057 g_threadWriteCharacteristicMutex,
2058 WAIT_TIME_WRITE_CHARACTERISTIC))
2060 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2061 g_isSignalSetFlag = false;
2062 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2063 return CA_STATUS_FAILED;
2066 // reset flag set by writeCharacteristic Callback
2067 g_isSignalSetFlag = false;
2068 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2070 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2071 return CA_STATUS_OK;
2074 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2076 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2077 VERIFY_NON_NULL(env, TAG, "env is null");
2078 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2080 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2081 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2082 CALEWriteCharacteristicThread, (void*)gattParam))
2084 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2085 return CA_STATUS_FAILED;
2088 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2089 return CA_STATUS_OK;
2092 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2093 jobject gattCharacteristic)
2095 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2096 VERIFY_NON_NULL(env, TAG, "env is null");
2097 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2098 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2100 if (!CALEIsEnableBTAdapter(env))
2102 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2103 return CA_STATUS_FAILED;
2106 // get BluetoothGatt.write characteristic method
2107 OIC_LOG(DEBUG, TAG, "write characteristic method");
2108 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2109 "writeCharacteristic",
2110 "(Landroid/bluetooth/"
2111 "BluetoothGattCharacteristic;)Z");
2112 if (!jni_mid_writeCharacteristic)
2114 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2115 return CA_STATUS_FAILED;
2118 // call disconnect gatt method
2119 OIC_LOG(INFO, TAG, "CALL API - writeCharacteristic");
2120 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2121 jni_mid_writeCharacteristic,
2122 gattCharacteristic);
2125 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2129 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2130 return CA_STATUS_FAILED;
2133 return CA_STATUS_OK;
2136 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2138 VERIFY_NON_NULL(env, TAG, "env is null");
2139 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2141 if (!CALEIsEnableBTAdapter(env))
2143 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2144 return CA_STATUS_FAILED;
2147 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2150 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2151 return CA_STATUS_FAILED;
2154 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2155 if (!jni_obj_GattCharacteristic)
2157 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2158 return CA_STATUS_FAILED;
2161 OIC_LOG(DEBUG, TAG, "read characteristic method");
2162 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2163 "readCharacteristic",
2164 "(Landroid/bluetooth/"
2165 "BluetoothGattCharacteristic;)Z");
2166 if (!jni_mid_readCharacteristic)
2168 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2169 return CA_STATUS_FAILED;
2172 // call disconnect gatt method
2173 OIC_LOG(INFO, TAG, "CALL API - readCharacteristic");
2174 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2175 jni_obj_GattCharacteristic);
2178 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2182 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2183 return CA_STATUS_FAILED;
2186 return CA_STATUS_OK;
2189 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2190 jobject characteristic)
2192 VERIFY_NON_NULL(env, TAG, "env is null");
2193 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2194 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2196 if (!CALEIsEnableBTAdapter(env))
2198 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2199 return CA_ADAPTER_NOT_ENABLED;
2202 // get BluetoothGatt.setCharacteristicNotification method
2203 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2204 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2205 "setCharacteristicNotification",
2206 "(Landroid/bluetooth/"
2207 "BluetoothGattCharacteristic;Z)Z");
2208 if (!jni_mid_setNotification)
2210 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2211 return CA_STATUS_FAILED;
2214 OIC_LOG(INFO, TAG, "CALL API - setCharacteristicNotification");
2215 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2216 characteristic, JNI_TRUE);
2217 if (JNI_TRUE == ret)
2219 OIC_LOG(DEBUG, TAG, "setCharacteristicNotification success");
2223 OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
2224 return CA_STATUS_FAILED;
2227 return CA_STATUS_OK;
2230 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2232 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2233 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2234 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2236 if (!CALEIsEnableBTAdapter(env))
2238 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2242 // get BluetoothGatt.getService method
2243 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2244 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2246 "(Ljava/util/UUID;)Landroid/bluetooth/"
2247 "BluetoothGattService;");
2248 if (!jni_mid_getService)
2250 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2254 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2255 if (!jni_obj_service_uuid)
2257 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2261 // get bluetooth gatt service
2262 OIC_LOG(DEBUG, TAG, "request to get service");
2263 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2264 jni_obj_service_uuid);
2265 if (!jni_obj_gattService)
2267 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2271 // get bluetooth gatt service method
2272 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2273 "BluetoothGattService",
2274 "getCharacteristic",
2275 "(Ljava/util/UUID;)"
2276 "Landroid/bluetooth/"
2277 "BluetoothGattCharacteristic;");
2278 if (!jni_mid_getCharacteristic)
2280 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2284 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2287 OIC_LOG(ERROR, TAG, "uuid is null");
2291 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2292 if (!jni_obj_tx_uuid)
2294 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2295 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2299 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2300 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2301 jni_mid_getCharacteristic,
2304 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2305 return jni_obj_GattCharacteristic;
2308 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2310 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2311 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2312 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2313 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2315 if (!CALEIsEnableBTAdapter(env))
2317 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2321 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2324 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2328 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2329 if (!jni_obj_GattCharacteristic)
2331 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2335 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2336 "/BluetoothGattCharacteristic");
2337 if (!jni_cid_BTGattCharacteristic)
2339 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2343 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2344 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2346 if (!jni_mid_setValue)
2348 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2352 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2354 if (JNI_TRUE == ret)
2356 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2360 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2365 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2366 "setWriteType", "(I)V");
2367 if (!jni_mid_setWriteType)
2369 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2373 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2374 "WRITE_TYPE_NO_RESPONSE", "I");
2375 if (!jni_fid_no_response)
2377 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2381 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2382 jni_fid_no_response);
2384 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2386 return jni_obj_GattCharacteristic;
2389 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2391 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2392 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2394 if (!CALEIsEnableBTAdapter(env))
2396 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2400 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2401 "BluetoothGattCharacteristic",
2402 "getValue", "()[B");
2403 if (!jni_mid_getValue)
2405 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2409 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2411 return jni_obj_data_array;
2414 CAResult_t CALEClientCreateUUIDList()
2418 OIC_LOG(ERROR, TAG, "g_jvm is null");
2419 return CA_STATUS_FAILED;
2422 bool isAttached = false;
2424 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2427 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2428 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2432 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2433 return CA_STATUS_FAILED;
2438 // create new object array
2439 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2440 if (!jni_cid_uuid_list)
2442 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2446 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2447 jni_cid_uuid_list, NULL);
2448 if (!jni_obj_uuid_list)
2450 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2455 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2458 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2461 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2463 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2467 (*g_jvm)->DetachCurrentThread(g_jvm);
2470 return CA_STATUS_OK;
2477 (*g_jvm)->DetachCurrentThread(g_jvm);
2479 return CA_STATUS_FAILED;
2482 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2483 jobject characteristic)
2485 VERIFY_NON_NULL(env, TAG, "env is null");
2486 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2487 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2489 if (!CALEIsEnableBTAdapter(env))
2491 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2492 return CA_ADAPTER_NOT_ENABLED;
2495 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2496 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2497 "BluetoothGattCharacteristic",
2499 "(Ljava/util/UUID;)Landroid/bluetooth/"
2500 "BluetoothGattDescriptor;");
2501 if (!jni_mid_getDescriptor)
2503 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2504 return CA_STATUS_FAILED;
2507 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2508 if (!jni_obj_cc_uuid)
2510 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2511 return CA_STATUS_FAILED;
2514 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2515 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2516 jni_mid_getDescriptor, jni_obj_cc_uuid);
2517 if (!jni_obj_descriptor)
2519 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2520 return CA_NOT_SUPPORTED;
2523 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2524 jclass jni_cid_descriptor = (*env)->FindClass(env,
2525 "android/bluetooth/BluetoothGattDescriptor");
2526 if (!jni_cid_descriptor)
2528 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2529 return CA_STATUS_FAILED;
2532 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2533 if (!jni_mid_setValue)
2535 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2536 return CA_STATUS_FAILED;
2539 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2540 "ENABLE_NOTIFICATION_VALUE", "[B");
2541 if (!jni_fid_NotiValue)
2543 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2544 return CA_STATUS_FAILED;
2547 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2549 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2550 env, jni_obj_descriptor, jni_mid_setValue,
2551 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2554 OIC_LOG(DEBUG, TAG, "setValue success");
2558 OIC_LOG(ERROR, TAG, "setValue has failed");
2559 return CA_STATUS_FAILED;
2562 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2564 "(Landroid/bluetooth/"
2565 "BluetoothGattDescriptor;)Z");
2566 if (!jni_mid_writeDescriptor)
2568 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2569 return CA_STATUS_FAILED;
2572 OIC_LOG(INFO, TAG, "CALL API - writeDescriptor");
2573 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2574 jni_obj_descriptor);
2577 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2581 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2582 return CA_STATUS_FAILED;
2585 return CA_STATUS_OK;
2588 void CALEClientCreateScanDeviceList(JNIEnv *env)
2590 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2591 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2593 ca_mutex_lock(g_deviceListMutex);
2594 // create new object array
2595 if (g_deviceList == NULL)
2597 OIC_LOG(DEBUG, TAG, "Create device list");
2599 g_deviceList = u_arraylist_create();
2601 ca_mutex_unlock(g_deviceListMutex);
2604 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2606 VERIFY_NON_NULL(device, TAG, "device is null");
2607 VERIFY_NON_NULL(env, TAG, "env is null");
2609 ca_mutex_lock(g_deviceListMutex);
2613 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2615 CALEClientSetScanFlag(false);
2616 if (CA_STATUS_OK != CALEClientStopScan())
2618 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2621 ca_mutex_unlock(g_deviceListMutex);
2622 return CA_STATUS_FAILED;
2625 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2626 if (!jni_remoteAddress)
2628 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2629 ca_mutex_unlock(g_deviceListMutex);
2630 return CA_STATUS_FAILED;
2633 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2636 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2637 ca_mutex_unlock(g_deviceListMutex);
2638 return CA_STATUS_FAILED;
2641 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2643 jobject gdevice = (*env)->NewGlobalRef(env, device);
2644 u_arraylist_add(g_deviceList, gdevice);
2645 ca_cond_signal(g_deviceDescCond);
2646 OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
2648 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2650 ca_mutex_unlock(g_deviceListMutex);
2652 return CA_STATUS_OK;
2655 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2657 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2658 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2662 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2666 uint32_t length = u_arraylist_length(g_deviceList);
2667 for (uint32_t index = 0; index < length; index++)
2669 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2672 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2676 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2677 if (!jni_setAddress)
2679 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2683 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2686 OIC_LOG(ERROR, TAG, "setAddress is null");
2690 if (!strcmp(remoteAddress, setAddress))
2692 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2696 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2699 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
2704 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2706 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2707 VERIFY_NON_NULL(env, TAG, "env is null");
2709 ca_mutex_lock(g_deviceListMutex);
2713 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2714 ca_mutex_unlock(g_deviceListMutex);
2715 return CA_STATUS_FAILED;
2718 uint32_t length = u_arraylist_length(g_deviceList);
2719 for (uint32_t index = 0; index < length; index++)
2721 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2724 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2727 (*env)->DeleteGlobalRef(env, jarrayObj);
2731 OICFree(g_deviceList);
2732 g_deviceList = NULL;
2734 ca_mutex_unlock(g_deviceListMutex);
2735 return CA_STATUS_OK;
2738 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2740 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2741 VERIFY_NON_NULL(address, TAG, "address is null");
2742 VERIFY_NON_NULL(env, TAG, "env is null");
2744 ca_mutex_lock(g_deviceListMutex);
2748 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2749 ca_mutex_unlock(g_deviceListMutex);
2750 return CA_STATUS_FAILED;
2753 uint32_t length = u_arraylist_length(g_deviceList);
2754 for (uint32_t index = 0; index < length; index++)
2756 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2759 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2760 ca_mutex_unlock(g_deviceListMutex);
2761 return CA_STATUS_FAILED;
2764 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2765 if (!jni_setAddress)
2767 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2768 ca_mutex_unlock(g_deviceListMutex);
2769 return CA_STATUS_FAILED;
2772 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2775 OIC_LOG(ERROR, TAG, "setAddress is null");
2776 ca_mutex_unlock(g_deviceListMutex);
2777 return CA_STATUS_FAILED;
2780 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2783 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2784 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2785 ca_mutex_unlock(g_deviceListMutex);
2786 return CA_STATUS_FAILED;
2789 if (!strcmp(setAddress, remoteAddress))
2791 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2792 (*env)->DeleteGlobalRef(env, jarrayObj);
2794 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2795 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2797 if (NULL == u_arraylist_remove(g_deviceList, index))
2799 OIC_LOG(ERROR, TAG, "List removal failed.");
2800 ca_mutex_unlock(g_deviceListMutex);
2801 return CA_STATUS_FAILED;
2803 ca_mutex_unlock(g_deviceListMutex);
2804 return CA_STATUS_OK;
2806 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2807 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2810 ca_mutex_unlock(g_deviceListMutex);
2811 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2813 return CA_STATUS_OK;
2820 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2822 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2823 VERIFY_NON_NULL(env, TAG, "env is null");
2824 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2826 ca_mutex_lock(g_gattObjectMutex);
2828 if (!g_gattObjectList)
2830 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2831 ca_mutex_unlock(g_gattObjectMutex);
2832 return CA_STATUS_FAILED;
2835 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2836 if (!jni_remoteAddress)
2838 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2839 ca_mutex_unlock(g_gattObjectMutex);
2840 return CA_STATUS_FAILED;
2843 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2846 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2847 ca_mutex_unlock(g_gattObjectMutex);
2848 return CA_STATUS_FAILED;
2851 OIC_LOG_V(DEBUG, TAG, "remote address : %s", remoteAddress);
2852 if (!CALEClientIsGattObjInList(env, remoteAddress))
2854 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2855 u_arraylist_add(g_gattObjectList, newGatt);
2856 OIC_LOG(INFO, TAG, "added a newGatt object to gattObjectList");
2859 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2860 ca_mutex_unlock(g_gattObjectMutex);
2861 return CA_STATUS_OK;
2864 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2866 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2867 VERIFY_NON_NULL(env, TAG, "env is null");
2868 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2870 uint32_t length = u_arraylist_length(g_gattObjectList);
2871 for (uint32_t index = 0; index < length; index++)
2874 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2877 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2881 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2882 if (!jni_setAddress)
2884 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2888 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2891 OIC_LOG(ERROR, TAG, "setAddress is null");
2895 if (!strcmp(remoteAddress, setAddress))
2897 OIC_LOG(DEBUG, TAG, "the device is already set");
2898 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2903 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2908 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2912 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2914 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2915 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2916 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2918 ca_mutex_lock(g_gattObjectMutex);
2919 uint32_t length = u_arraylist_length(g_gattObjectList);
2920 for (uint32_t index = 0; index < length; index++)
2922 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2925 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2926 ca_mutex_unlock(g_gattObjectMutex);
2930 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2931 if (!jni_setAddress)
2933 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2934 ca_mutex_unlock(g_gattObjectMutex);
2938 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2941 OIC_LOG(ERROR, TAG, "setAddress is null");
2942 ca_mutex_unlock(g_gattObjectMutex);
2946 if (!strcmp(remoteAddress, setAddress))
2948 OIC_LOG(DEBUG, TAG, "the device is already set");
2949 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2950 ca_mutex_unlock(g_gattObjectMutex);
2953 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2956 ca_mutex_unlock(g_gattObjectMutex);
2957 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2961 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2963 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2964 VERIFY_NON_NULL(env, TAG, "env is null");
2966 ca_mutex_lock(g_gattObjectMutex);
2967 if (!g_gattObjectList)
2969 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2970 ca_mutex_unlock(g_gattObjectMutex);
2971 return CA_STATUS_OK;
2974 uint32_t length = u_arraylist_length(g_gattObjectList);
2975 for (uint32_t index = 0; index < length; index++)
2977 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2980 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2983 (*env)->DeleteGlobalRef(env, jarrayObj);
2987 OICFree(g_gattObjectList);
2988 g_gattObjectList = NULL;
2989 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2990 ca_mutex_unlock(g_gattObjectMutex);
2991 return CA_STATUS_OK;
2994 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2996 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2997 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2998 VERIFY_NON_NULL(env, TAG, "env is null");
3000 ca_mutex_lock(g_gattObjectMutex);
3001 if (!g_gattObjectList)
3003 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3004 ca_mutex_unlock(g_gattObjectMutex);
3005 return CA_STATUS_OK;
3008 uint32_t length = u_arraylist_length(g_gattObjectList);
3009 for (uint32_t index = 0; index < length; index++)
3011 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3014 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3015 ca_mutex_unlock(g_gattObjectMutex);
3016 return CA_STATUS_FAILED;
3019 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3020 if (!jni_setAddress)
3022 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3023 ca_mutex_unlock(g_gattObjectMutex);
3024 return CA_STATUS_FAILED;
3027 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3030 OIC_LOG(ERROR, TAG, "setAddress is null");
3031 ca_mutex_unlock(g_gattObjectMutex);
3032 return CA_STATUS_FAILED;
3035 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3036 if (!jni_remoteAddress)
3038 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3039 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3040 ca_mutex_unlock(g_gattObjectMutex);
3041 return CA_STATUS_FAILED;
3044 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3047 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3048 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3049 ca_mutex_unlock(g_gattObjectMutex);
3050 return CA_STATUS_FAILED;
3053 if (!strcmp(setAddress, remoteAddress))
3055 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3056 (*env)->DeleteGlobalRef(env, jarrayObj);
3058 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3059 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3061 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3063 OIC_LOG(ERROR, TAG, "List removal failed.");
3064 ca_mutex_unlock(g_gattObjectMutex);
3065 return CA_STATUS_FAILED;
3067 ca_mutex_unlock(g_gattObjectMutex);
3068 return CA_STATUS_OK;
3070 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3071 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3074 ca_mutex_unlock(g_gattObjectMutex);
3075 OIC_LOG(DEBUG, TAG, "there are no target object");
3076 return CA_STATUS_OK;
3079 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3081 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3082 VERIFY_NON_NULL(addr, TAG, "addr is null");
3083 VERIFY_NON_NULL(env, TAG, "env is null");
3085 ca_mutex_lock(g_gattObjectMutex);
3086 if (!g_gattObjectList)
3088 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3089 ca_mutex_unlock(g_gattObjectMutex);
3090 return CA_STATUS_OK;
3093 uint32_t length = u_arraylist_length(g_gattObjectList);
3094 for (uint32_t index = 0; index < length; index++)
3096 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3099 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3100 ca_mutex_unlock(g_gattObjectMutex);
3101 return CA_STATUS_FAILED;
3104 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3105 if (!jni_setAddress)
3107 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3108 ca_mutex_unlock(g_gattObjectMutex);
3109 return CA_STATUS_FAILED;
3112 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3115 OIC_LOG(ERROR, TAG, "setAddress is null");
3116 ca_mutex_unlock(g_gattObjectMutex);
3117 return CA_STATUS_FAILED;
3120 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3123 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3124 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3125 ca_mutex_unlock(g_gattObjectMutex);
3126 return CA_STATUS_FAILED;
3129 if (!strcmp(setAddress, remoteAddress))
3131 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3132 (*env)->DeleteGlobalRef(env, jarrayObj);
3134 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3135 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3136 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3138 OIC_LOG(ERROR, TAG, "List removal failed.");
3139 ca_mutex_unlock(g_gattObjectMutex);
3140 return CA_STATUS_FAILED;
3142 ca_mutex_unlock(g_gattObjectMutex);
3143 return CA_STATUS_OK;
3145 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3146 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3149 ca_mutex_unlock(g_gattObjectMutex);
3150 OIC_LOG(DEBUG, TAG, "there are no target object");
3151 return CA_STATUS_FAILED;
3154 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3156 OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
3158 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3159 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3161 // get Bluetooth Address
3162 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3163 if (!jni_btTargetAddress)
3165 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3169 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3172 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3176 // get method ID of getDevice()
3177 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3178 "getDevice", METHODID_BT_DEVICE);
3179 if (!jni_mid_getDevice)
3181 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3182 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3186 ca_mutex_lock(g_gattObjectMutex);
3188 size_t length = u_arraylist_length(g_gattObjectList);
3189 OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
3190 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3192 for (size_t index = 0; index < length; index++)
3194 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3197 ca_mutex_unlock(g_gattObjectMutex);
3198 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3199 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3203 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3204 if (!jni_obj_device)
3206 ca_mutex_unlock(g_gattObjectMutex);
3207 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3208 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3212 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3215 ca_mutex_unlock(g_gattObjectMutex);
3216 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3217 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3221 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3224 ca_mutex_unlock(g_gattObjectMutex);
3225 OIC_LOG(ERROR, TAG, "btAddress is not available");
3226 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3230 OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
3231 if (!strcmp(targetAddress, btAddress))
3233 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3236 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3239 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3241 ca_mutex_unlock(g_gattObjectMutex);
3242 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3243 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3244 (*env)->DeleteLocalRef(env, jni_btAddress);
3245 (*env)->DeleteLocalRef(env, jni_obj_device);
3246 return jni_LEAddress;
3248 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3249 (*env)->DeleteLocalRef(env, jni_btAddress);
3250 (*env)->DeleteLocalRef(env, jni_obj_device);
3252 ca_mutex_unlock(g_gattObjectMutex);
3254 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3255 OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
3263 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3264 uint16_t target_state)
3266 VERIFY_NON_NULL(address, TAG, "address is null");
3267 VERIFY_NON_NULL(address, TAG, "state_type is null");
3268 VERIFY_NON_NULL(address, TAG, "target_state is null");
3270 if (!g_deviceStateList)
3272 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3273 return CA_STATUS_FAILED;
3276 ca_mutex_lock(g_deviceStateListMutex);
3278 if (CALEClientIsDeviceInList(address))
3280 CALEState_t* curState = CALEClientGetStateInfo(address);
3283 OIC_LOG(ERROR, TAG, "curState is null");
3284 ca_mutex_unlock(g_deviceStateListMutex);
3285 return CA_STATUS_FAILED;
3290 case CA_LE_CONNECTION_STATE:
3291 curState->connectedState = target_state;
3293 case CA_LE_SEND_STATE:
3294 curState->sendState = target_state;
3299 OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
3300 curState->address, curState->connectedState, curState->sendState,
3301 curState->autoConnectFlag);
3303 else /** state is added newly **/
3305 if (strlen(address) > CA_MACADDR_SIZE)
3307 OIC_LOG(ERROR, TAG, "address is not proper");
3308 ca_mutex_unlock(g_deviceStateListMutex);
3309 return CA_STATUS_INVALID_PARAM;
3312 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3315 OIC_LOG(ERROR, TAG, "out of memory");
3316 ca_mutex_unlock(g_deviceStateListMutex);
3317 return CA_MEMORY_ALLOC_FAILED;
3320 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3324 case CA_LE_CONNECTION_STATE:
3325 newstate->connectedState = target_state;
3326 newstate->sendState = STATE_SEND_NONE;
3328 case CA_LE_SEND_STATE:
3329 newstate->connectedState = STATE_DISCONNECTED;
3330 newstate->sendState = target_state;
3335 OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
3336 "conn : %d, send : %d, ACFlag : %d",
3337 newstate->address, newstate->connectedState, newstate->sendState,
3338 newstate->autoConnectFlag);
3339 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);