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 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
174 if (!jni_LEInterface)
176 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
180 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
181 "(Landroid/content/Context;)V");
182 if (!LeInterfaceConstructorMethod)
184 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
188 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
189 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
193 (*g_jvm)->DetachCurrentThread(g_jvm);
202 (*g_jvm)->DetachCurrentThread(g_jvm);
205 return CA_STATUS_FAILED;
208 CAResult_t CALEClientInitialize()
210 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
216 OIC_LOG(ERROR, TAG, "g_jvm is null");
217 return CA_STATUS_FAILED;
220 bool isAttached = false;
222 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
225 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
226 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
230 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
231 return CA_STATUS_FAILED;
236 CAResult_t ret = CALECheckPlatformVersion(env, 18);
237 if (CA_STATUS_OK != ret)
239 OIC_LOG(ERROR, TAG, "it is not supported");
243 (*g_jvm)->DetachCurrentThread(g_jvm);
249 ret = CALEClientInitGattMutexVaraibles();
250 if (CA_STATUS_OK != ret)
252 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
253 CALEClientTerminateGattMutexVariables();
257 (*g_jvm)->DetachCurrentThread(g_jvm);
263 g_deviceDescCond = ca_cond_new();
265 // init mutex for send logic
266 g_threadCond = ca_cond_new();
267 g_threadWriteCharacteristicCond = ca_cond_new();
268 g_deviceScanRetryDelayCond = ca_cond_new();
270 CALEClientCreateDeviceList();
271 CALEClientJNISetContext();
273 ret = CALEClientCreateUUIDList();
274 if (CA_STATUS_OK != ret)
276 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
280 (*g_jvm)->DetachCurrentThread(g_jvm);
286 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
287 if (CA_STATUS_OK != ret)
289 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
293 (*g_jvm)->DetachCurrentThread(g_jvm);
298 g_isStartedLEClient = true;
302 (*g_jvm)->DetachCurrentThread(g_jvm);
308 void CALEClientTerminate()
310 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
314 OIC_LOG(ERROR, TAG, "g_jvm is null");
318 bool isAttached = false;
320 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
323 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
324 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
328 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
334 if (g_leScanCallback)
336 (*env)->DeleteGlobalRef(env, g_leScanCallback);
337 g_leScanCallback = NULL;
340 if (g_leGattCallback)
342 (*env)->DeleteGlobalRef(env, g_leGattCallback);
343 g_leGattCallback = NULL;
348 (*env)->DeleteGlobalRef(env, g_sendBuffer);
354 (*env)->DeleteGlobalRef(env, g_uuidList);
358 CAResult_t ret = CALEClientRemoveAllDeviceState();
359 if (CA_STATUS_OK != ret)
361 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
364 ret = CALEClientRemoveAllScanDevices(env);
365 if (CA_STATUS_OK != ret)
367 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
370 ret = CALEClientRemoveAllGattObjs(env);
371 if (CA_STATUS_OK != ret)
373 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
376 CALEClientSetScanFlag(false);
377 CALEClientSetSendFinishFlag(true);
379 CALEClientTerminateGattMutexVariables();
380 CALEClientDestroyJniInterface();
382 ca_cond_free(g_deviceDescCond);
383 ca_cond_free(g_threadCond);
384 ca_cond_free(g_threadWriteCharacteristicCond);
385 ca_cond_free(g_deviceScanRetryDelayCond);
387 g_deviceDescCond = NULL;
389 g_threadWriteCharacteristicCond = NULL;
390 g_deviceScanRetryDelayCond = NULL;
392 g_isSignalSetFlag = false;
396 (*g_jvm)->DetachCurrentThread(g_jvm);
400 CAResult_t CALEClientDestroyJniInterface()
402 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
406 OIC_LOG(ERROR, TAG, "g_jvm is null");
407 return CA_STATUS_FAILED;
410 bool isAttached = false;
412 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
415 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
416 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
420 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
421 return CA_STATUS_FAILED;
426 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
427 if (!jni_LeInterface)
429 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
433 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
434 "destroyLeInterface",
436 if (!jni_InterfaceDestroyMethod)
438 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
442 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
444 if ((*env)->ExceptionCheck(env))
446 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
447 (*env)->ExceptionDescribe(env);
448 (*env)->ExceptionClear(env);
452 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
456 (*g_jvm)->DetachCurrentThread(g_jvm);
465 (*g_jvm)->DetachCurrentThread(g_jvm);
468 return CA_STATUS_FAILED;
471 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
473 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
474 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
478 CAResult_t res = CALEClientDisconnect(env, gatt);
479 if (CA_STATUS_OK != res)
481 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
484 CALEClientUpdateSendCnt(env);
487 CAResult_t CALEClientSendUnicastMessage(const char* address,
489 const uint32_t dataLen)
491 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
492 VERIFY_NON_NULL(address, TAG, "address is null");
493 VERIFY_NON_NULL(data, TAG, "data is null");
495 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
498 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
499 const uint32_t dataLen)
501 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
502 VERIFY_NON_NULL(data, TAG, "data is null");
506 OIC_LOG(ERROR, TAG, "g_jvm is null");
507 return CA_STATUS_FAILED;
510 bool isAttached = false;
512 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
515 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
516 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
520 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
521 return CA_STATUS_FAILED;
526 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
527 if (CA_STATUS_OK != ret)
529 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
534 (*g_jvm)->DetachCurrentThread(g_jvm);
540 CAResult_t CALEClientStartUnicastServer(const char* address)
542 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
544 return CA_NOT_SUPPORTED;
547 CAResult_t CALEClientStartMulticastServer()
549 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
551 return CA_NOT_SUPPORTED;
554 void CALEClientStopUnicastServer()
556 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
559 void CALEClientStopMulticastServer()
561 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
564 void CALEClientSetCallback(CAPacketReceiveCallback callback)
566 g_packetReceiveCallback = callback;
569 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
571 g_clientErrorCallback = callback;
574 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
576 VERIFY_NON_NULL(env, TAG, "env");
580 return CA_STATUS_FAILED;
583 if (0 == u_arraylist_length(g_deviceList) // multicast
584 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
586 // Wait for LE peripherals to be discovered.
588 // Number of times to wait for discovery to complete.
589 static size_t const RETRIES = 5;
591 static uint64_t const TIMEOUT =
592 2 * MICROSECS_PER_SEC; // Microseconds
594 bool devicesDiscovered = false;
595 for (size_t i = 0; i < RETRIES; ++i)
597 OIC_LOG(DEBUG, TAG, "waiting for target device");
598 if (ca_cond_wait_for(g_deviceDescCond,
600 TIMEOUT) == CA_WAIT_SUCCESS)
602 ca_mutex_lock(g_deviceListMutex);
603 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
604 ca_mutex_unlock(g_deviceListMutex);
606 if (0 < scannedDeviceLen)
608 if (!address // multicast
609 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
611 devicesDiscovered = true;
618 OIC_LOG(INFO, TAG, "waiting..");
620 ca_mutex_lock(g_deviceScanRetryDelayMutex);
621 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
622 g_deviceScanRetryDelayMutex,
623 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
625 OIC_LOG(INFO, TAG, "finish to waiting for target device");
626 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
629 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
632 // checking whether a target device is found while waiting for time-out.
633 if (CALEClientIsDeviceInScanDeviceList(env, address))
635 devicesDiscovered = true;
644 // time out for scanning devices
645 if (!devicesDiscovered)
647 return CA_STATUS_FAILED;
655 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
656 const uint32_t dataLen)
658 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
660 VERIFY_NON_NULL(address, TAG, "address is null");
661 VERIFY_NON_NULL(data, TAG, "data is null");
665 OIC_LOG(ERROR, TAG, "g_jvm is null");
666 return CA_STATUS_FAILED;
669 bool isAttached = false;
671 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
674 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
675 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
678 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
679 return CA_STATUS_FAILED;
684 ca_mutex_lock(g_threadSendMutex);
686 CALEClientSetSendFinishFlag(false);
688 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
689 if (CA_STATUS_OK != ret)
691 OIC_LOG(INFO, TAG, "there is no scanned device");
695 if (g_context && g_deviceList)
697 uint32_t length = u_arraylist_length(g_deviceList);
698 for (uint32_t index = 0; index < length; index++)
700 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
703 OIC_LOG(ERROR, TAG, "jarrayObj is null");
707 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
710 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
714 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
717 OIC_LOG(ERROR, TAG, "setAddress is null");
721 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
723 if (!strcmp(setAddress, address))
725 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
727 // connect to gatt server
728 ret = CALEClientStopScan();
729 if (CA_STATUS_OK != ret)
731 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
737 (*env)->DeleteGlobalRef(env, g_sendBuffer);
740 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
741 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
742 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
744 // Target device to send message is just one.
747 ret = CALEClientSendData(env, jarrayObj);
748 if (CA_STATUS_OK != ret)
750 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
754 OIC_LOG(INFO, TAG, "wake up");
757 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
761 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
763 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
764 // if there is no connection state.
765 ca_mutex_lock(g_threadMutex);
766 if (!g_isFinishedSendData)
768 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
769 ca_cond_wait(g_threadCond, g_threadMutex);
770 OIC_LOG(DEBUG, TAG, "the data was sent");
772 ca_mutex_unlock(g_threadMutex);
776 (*g_jvm)->DetachCurrentThread(g_jvm);
779 // start LE Scan again
780 ret = CALEClientStartScan();
781 if (CA_STATUS_OK != ret)
783 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
784 ca_mutex_unlock(g_threadSendMutex);
788 ca_mutex_unlock(g_threadSendMutex);
789 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
790 if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
797 ret = CA_SEND_FAILED;
801 ret = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
803 if (CA_STATUS_OK != ret)
805 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
813 // start LE Scan again
814 ret = CALEClientStartScan();
815 if (CA_STATUS_OK != ret)
817 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
818 ca_mutex_unlock(g_threadSendMutex);
821 (*g_jvm)->DetachCurrentThread(g_jvm);
828 (*g_jvm)->DetachCurrentThread(g_jvm);
831 ca_mutex_unlock(g_threadSendMutex);
832 return CA_SEND_FAILED;
835 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
836 const uint32_t dataLen)
838 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
839 VERIFY_NON_NULL(data, TAG, "data is null");
840 VERIFY_NON_NULL(env, TAG, "env is null");
844 OIC_LOG(ERROR, TAG, "g_deviceList is null");
845 return CA_STATUS_FAILED;
848 ca_mutex_lock(g_threadSendMutex);
850 CALEClientSetSendFinishFlag(false);
852 OIC_LOG(DEBUG, TAG, "set byteArray for data");
855 (*env)->DeleteGlobalRef(env, g_sendBuffer);
859 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
860 if (CA_STATUS_OK != res)
862 OIC_LOG(INFO, TAG, "there is no scanned device");
866 // connect to gatt server
867 res = CALEClientStopScan();
868 if (CA_STATUS_OK != res)
870 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
871 ca_mutex_unlock(g_threadSendMutex);
874 uint32_t length = u_arraylist_length(g_deviceList);
875 g_targetCnt = length;
877 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
878 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
879 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
881 for (uint32_t index = 0; index < length; index++)
883 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
886 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
890 res = CALEClientSendData(env, jarrayObj);
891 if (res != CA_STATUS_OK)
893 OIC_LOG(ERROR, TAG, "BT device - send has failed");
896 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
899 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
903 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
906 OIC_LOG(ERROR, TAG, "address is not available");
910 (*env)->ReleaseStringUTFChars(env, jni_address, address);
913 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
915 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
916 ca_mutex_lock(g_threadMutex);
917 if (!g_isFinishedSendData)
919 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
920 ca_cond_wait(g_threadCond, g_threadMutex);
921 OIC_LOG(DEBUG, TAG, "the data was sent");
923 ca_mutex_unlock(g_threadMutex);
925 // start LE Scan again
926 res = CALEClientStartScan();
927 if (CA_STATUS_OK != res)
929 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
930 ca_mutex_unlock(g_threadSendMutex);
934 ca_mutex_unlock(g_threadSendMutex);
935 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
939 res = CALEClientStartScan();
940 if (CA_STATUS_OK != res)
942 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
943 ca_mutex_unlock(g_threadSendMutex);
947 ca_mutex_unlock(g_threadSendMutex);
948 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
949 return CA_SEND_FAILED;
952 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
954 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
955 VERIFY_NON_NULL(device, TAG, "device is null");
956 VERIFY_NON_NULL(env, TAG, "env is null");
958 // get BLE address from bluetooth device object.
959 char* address = NULL;
960 CALEState_t* state = NULL;
961 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
964 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
965 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
968 OIC_LOG(ERROR, TAG, "address is not available");
969 return CA_STATUS_FAILED;
971 ca_mutex_lock(g_deviceStateListMutex);
972 state = CALEClientGetStateInfo(address);
973 ca_mutex_unlock(g_deviceStateListMutex);
978 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
980 // cancel previous connection request before connection
981 // if there is gatt object in g_gattObjectList.
984 jobject gatt = CALEClientGetGattObjInList(env, address);
987 CAResult_t res = CALEClientDisconnect(env, gatt);
988 if (CA_STATUS_OK != res)
990 OIC_LOG(INFO, TAG, "there is no gatt object");
993 (*env)->ReleaseStringUTFChars(env, jni_address, address);
996 // connection request
997 jobject newGatt = CALEClientConnect(env, device,
1001 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1002 return CA_STATUS_FAILED;
1007 if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1008 STATE_SERVICE_CONNECTED))
1010 OIC_LOG(INFO, TAG, "GATT has already connected");
1012 jobject gatt = CALEClientGetGattObjInList(env, address);
1015 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1016 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1017 return CA_STATUS_FAILED;
1020 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1021 if (CA_STATUS_OK != ret)
1023 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1024 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1027 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1029 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1032 OIC_LOG(INFO, TAG, "service connecting...");
1034 else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1035 STATE_DISCONNECTED))
1037 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1039 // cancel previous connection request before connection
1040 // if there is gatt object in g_gattObjectList.
1043 jobject gatt = CALEClientGetGattObjInList(env, address);
1046 CAResult_t res = CALEClientDisconnect(env, gatt);
1047 if (CA_STATUS_OK != res)
1049 OIC_LOG(INFO, TAG, "there is no gatt object");
1052 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1055 OIC_LOG(DEBUG, TAG, "start to connect LE");
1056 jobject gatt = CALEClientConnect(env, device,
1057 CALEClientGetFlagFromState(env, jni_address,
1058 CA_LE_AUTO_CONNECT_FLAG));
1061 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1062 return CA_STATUS_FAILED;
1067 return CA_STATUS_OK;
1070 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1072 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1073 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1075 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1076 "()Landroid/bluetooth/BluetoothDevice;");
1077 if (!jni_mid_getDevice)
1079 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1083 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1084 if (!jni_obj_device)
1086 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1090 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1093 OIC_LOG(ERROR, TAG, "jni_address is null");
1103 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1106 OIC_LOG(DEBUG, TAG, "Gatt Close");
1107 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1108 VERIFY_NON_NULL(env, TAG, "env is null");
1110 // get BluetoothGatt method
1111 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1112 jmethodID jni_mid_closeGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1113 if (!jni_mid_closeGatt)
1115 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1116 return CA_STATUS_OK;
1119 // call disconnect gatt method
1120 OIC_LOG(DEBUG, TAG, "request to close GATT");
1121 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1123 if ((*env)->ExceptionCheck(env))
1125 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1126 (*env)->ExceptionDescribe(env);
1127 (*env)->ExceptionClear(env);
1128 return CA_STATUS_FAILED;
1131 return CA_STATUS_OK;
1134 CAResult_t CALEClientStartScan()
1136 if (!g_isStartedLEClient)
1138 OIC_LOG(ERROR, TAG, "LE client is not started");
1139 return CA_STATUS_FAILED;
1144 OIC_LOG(ERROR, TAG, "g_jvm is null");
1145 return CA_STATUS_FAILED;
1148 if (g_isStartedScan)
1150 OIC_LOG(INFO, TAG, "scanning is already started");
1151 return CA_STATUS_OK;
1154 bool isAttached = false;
1156 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1159 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1161 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1164 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1165 return CA_STATUS_FAILED;
1170 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1172 CAResult_t ret = CA_STATUS_OK;
1173 // scan gatt server with UUID
1174 if (g_leScanCallback && g_uuidList)
1177 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1179 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1181 if (CA_STATUS_OK != ret)
1183 if (CA_ADAPTER_NOT_ENABLED == ret)
1185 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1189 OIC_LOG(ERROR, TAG, "start scan has failed");
1196 (*g_jvm)->DetachCurrentThread(g_jvm);
1202 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1204 VERIFY_NON_NULL(callback, TAG, "callback is null");
1205 VERIFY_NON_NULL(env, TAG, "env is null");
1207 if (!CALEIsEnableBTAdapter(env))
1209 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1210 return CA_ADAPTER_NOT_ENABLED;
1213 // get default bt adapter class
1214 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1215 if (!jni_cid_BTAdapter)
1217 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1218 return CA_STATUS_FAILED;
1221 // get remote bt adapter method
1222 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1223 "getDefaultAdapter",
1224 METHODID_OBJECTNONPARAM);
1225 if (!jni_mid_getDefaultAdapter)
1227 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1228 return CA_STATUS_FAILED;
1231 // get start le scan method
1232 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1233 "(Landroid/bluetooth/BluetoothAdapter$"
1234 "LeScanCallback;)Z");
1235 if (!jni_mid_startLeScan)
1237 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1238 return CA_STATUS_FAILED;
1241 // gat bt adapter object
1242 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1243 jni_mid_getDefaultAdapter);
1244 if (!jni_obj_BTAdapter)
1246 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1247 return CA_STATUS_FAILED;
1250 // call start le scan method
1251 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1252 jni_mid_startLeScan, callback);
1253 if (!jni_obj_startLeScan)
1255 OIC_LOG(INFO, TAG, "startLeScan is failed");
1259 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1260 CALEClientSetScanFlag(true);
1263 return CA_STATUS_OK;
1266 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1268 VERIFY_NON_NULL(callback, TAG, "callback is null");
1269 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1270 VERIFY_NON_NULL(env, TAG, "env is null");
1272 if (!CALEIsEnableBTAdapter(env))
1274 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1275 return CA_ADAPTER_NOT_ENABLED;
1278 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1279 if (!jni_cid_BTAdapter)
1281 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1282 return CA_STATUS_FAILED;
1285 // get remote bt adapter method
1286 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1287 "getDefaultAdapter",
1288 METHODID_OBJECTNONPARAM);
1289 if (!jni_mid_getDefaultAdapter)
1291 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1292 return CA_STATUS_FAILED;
1295 // get start le scan method
1296 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1297 "([Ljava/util/UUID;Landroid/bluetooth/"
1298 "BluetoothAdapter$LeScanCallback;)Z");
1299 if (!jni_mid_startLeScan)
1301 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1302 return CA_STATUS_FAILED;
1305 // get bt adapter object
1306 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1307 jni_mid_getDefaultAdapter);
1308 if (!jni_obj_BTAdapter)
1310 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1311 return CA_STATUS_FAILED;
1314 // call start le scan method
1315 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1316 jni_mid_startLeScan, uuids, callback);
1317 if (!jni_obj_startLeScan)
1319 OIC_LOG(INFO, TAG, "startLeScan With UUID is failed");
1323 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1324 CALEClientSetScanFlag(true);
1327 return CA_STATUS_OK;
1330 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1332 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1333 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1336 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1339 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1343 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1344 "(Ljava/lang/String;)"
1345 "Ljava/util/UUID;");
1346 if (!jni_mid_fromString)
1348 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1352 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1353 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1357 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1361 return jni_obj_uuid;
1364 CAResult_t CALEClientStopScan()
1368 OIC_LOG(ERROR, TAG, "g_jvm is null");
1369 return CA_STATUS_FAILED;
1372 if (!g_isStartedScan)
1374 OIC_LOG(INFO, TAG, "scanning is already stopped");
1375 return CA_STATUS_OK;
1378 bool isAttached = false;
1380 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1383 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1384 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1387 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1388 return CA_STATUS_FAILED;
1393 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1394 if (CA_STATUS_OK != ret)
1396 if (CA_ADAPTER_NOT_ENABLED == ret)
1398 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1402 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1407 CALEClientSetScanFlag(false);
1412 (*g_jvm)->DetachCurrentThread(g_jvm);
1418 void CALEClientSetScanFlag(bool flag)
1420 ca_mutex_lock(g_scanMutex);
1421 g_isStartedScan = flag;
1422 ca_mutex_unlock(g_scanMutex);
1425 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1427 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1428 VERIFY_NON_NULL(callback, TAG, "callback is null");
1429 VERIFY_NON_NULL(env, TAG, "env is null");
1431 if (!CALEIsEnableBTAdapter(env))
1433 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1434 return CA_ADAPTER_NOT_ENABLED;
1437 // get default bt adapter class
1438 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1439 if (!jni_cid_BTAdapter)
1441 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1442 return CA_STATUS_FAILED;
1445 // get remote bt adapter method
1446 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1447 "getDefaultAdapter",
1448 METHODID_OBJECTNONPARAM);
1449 if (!jni_mid_getDefaultAdapter)
1451 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1452 return CA_STATUS_FAILED;
1455 // get start le scan method
1456 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1457 "(Landroid/bluetooth/"
1458 "BluetoothAdapter$LeScanCallback;)V");
1459 if (!jni_mid_stopLeScan)
1461 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1462 return CA_STATUS_FAILED;
1465 // gat bt adapter object
1466 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1467 jni_mid_getDefaultAdapter);
1468 if (!jni_obj_BTAdapter)
1470 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1471 return CA_STATUS_FAILED;
1474 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1475 // call start le scan method
1476 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1477 if ((*env)->ExceptionCheck(env))
1479 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1480 (*env)->ExceptionDescribe(env);
1481 (*env)->ExceptionClear(env);
1482 return CA_STATUS_FAILED;
1485 return CA_STATUS_OK;
1488 CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
1489 jint state_idx, jboolean flag)
1491 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
1492 VERIFY_NON_NULL(env, TAG, "env");
1493 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1495 ca_mutex_lock(g_deviceStateListMutex);
1497 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1500 OIC_LOG(ERROR, TAG, "address is not available");
1501 return CA_STATUS_FAILED;
1504 if (CALEClientIsDeviceInList(address))
1506 CALEState_t* curState = CALEClientGetStateInfo(address);
1509 OIC_LOG(ERROR, TAG, "curState is null");
1510 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1511 ca_mutex_unlock(g_deviceStateListMutex);
1512 return CA_STATUS_FAILED;
1514 OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
1518 case CA_LE_AUTO_CONNECT_FLAG:
1519 curState->autoConnectFlag = flag;
1526 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1527 ca_mutex_unlock(g_deviceStateListMutex);
1528 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
1529 return CA_STATUS_OK;
1532 jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
1534 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
1535 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1536 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1538 ca_mutex_lock(g_deviceStateListMutex);
1540 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1543 OIC_LOG(ERROR, TAG, "address is not available");
1547 CALEState_t* curState = CALEClientGetStateInfo(address);
1550 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1551 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1552 ca_mutex_unlock(g_deviceStateListMutex);
1556 jboolean ret = JNI_FALSE;
1559 case CA_LE_AUTO_CONNECT_FLAG:
1560 ret = curState->autoConnectFlag;
1565 OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
1567 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1568 ca_mutex_unlock(g_deviceStateListMutex);
1570 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
1574 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1576 OIC_LOG(DEBUG, TAG, "CALEClientDirectConnect");
1577 VERIFY_NON_NULL(env, TAG, "env is null");
1578 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1580 ca_mutex_lock(g_threadSendMutex);
1582 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1585 OIC_LOG(ERROR, TAG, "jni_address is not available");
1586 ca_mutex_unlock(g_threadSendMutex);
1587 return CA_STATUS_FAILED;
1590 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1593 OIC_LOG(ERROR, TAG, "address is not available");
1594 ca_mutex_unlock(g_threadSendMutex);
1595 return CA_STATUS_FAILED;
1598 CAResult_t res = CA_STATUS_OK;
1599 if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
1600 STATE_DISCONNECTED))
1602 jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
1603 if (NULL == newGatt)
1605 OIC_LOG(INFO, TAG, "newGatt is not available");
1606 res = CA_STATUS_FAILED;
1609 ca_mutex_unlock(g_threadSendMutex);
1614 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1616 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1617 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1618 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1620 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1621 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1624 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1627 OIC_LOG(ERROR, TAG, "address is not available");
1631 // close the gatt service
1632 jobject gatt = CALEClientGetGattObjInList(env, address);
1635 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1636 if (CA_STATUS_OK != res)
1638 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1639 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1643 // clean previous gatt object after close profile service
1644 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1645 if (CA_STATUS_OK != res)
1647 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1648 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1652 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1655 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1658 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1662 // add new gatt object into g_gattObjectList
1663 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1664 if (CA_STATUS_OK != res)
1666 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1673 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1675 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1676 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1677 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1679 if (!g_leGattCallback)
1681 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1685 if (!CALEIsEnableBTAdapter(env))
1687 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1691 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1694 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1698 // get BluetoothDevice method
1699 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1700 jmethodID jni_mid_connectGatt = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1702 "(Landroid/content/Context;ZLandroid/"
1703 "bluetooth/BluetoothGattCallback;)"
1704 "Landroid/bluetooth/BluetoothGatt;");
1705 if (!jni_mid_connectGatt)
1707 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1711 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1712 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1713 jni_mid_connectGatt,
1715 autoconnect, g_leGattCallback);
1716 if (!jni_obj_connectGatt)
1718 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1719 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1720 CALEClientUpdateSendCnt(env);
1725 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1727 return jni_obj_connectGatt;
1730 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1732 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1734 VERIFY_NON_NULL(env, TAG, "env is null");
1735 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1737 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1738 if (!jni_cid_BTAdapter)
1740 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1741 return CA_STATUS_FAILED;
1744 // get remote bt adapter method
1745 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1746 "getDefaultAdapter",
1747 METHODID_OBJECTNONPARAM);
1748 if (!jni_mid_getDefaultAdapter)
1750 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1751 return CA_STATUS_FAILED;
1754 // gat bt adapter object
1755 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1756 jni_mid_getDefaultAdapter);
1757 if (!jni_obj_BTAdapter)
1759 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1760 return CA_STATUS_FAILED;
1763 // get closeProfileProxy method
1764 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1765 "closeProfileProxy",
1766 "(ILandroid/bluetooth/"
1767 "BluetoothProfile;)V");
1768 if (!jni_mid_closeProfileProxy)
1770 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1771 return CA_STATUS_FAILED;
1774 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1775 if (!jni_cid_BTProfile)
1777 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1778 return CA_STATUS_FAILED;
1781 // GATT - Constant value : 7 (0x00000007)
1782 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1786 OIC_LOG(ERROR, TAG, "id_gatt is null");
1787 return CA_STATUS_FAILED;
1790 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1792 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1793 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1794 if ((*env)->ExceptionCheck(env))
1796 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1797 (*env)->ExceptionDescribe(env);
1798 (*env)->ExceptionClear(env);
1799 return CA_STATUS_FAILED;
1802 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1803 return CA_STATUS_OK;
1807 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1809 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1810 VERIFY_NON_NULL(env, TAG, "env is null");
1811 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1813 // get BluetoothGatt method
1814 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1815 jmethodID jni_mid_disconnectGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
1816 "disconnect", "()V");
1817 if (!jni_mid_disconnectGatt)
1819 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1820 return CA_STATUS_FAILED;
1823 // call disconnect gatt method
1824 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1825 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1826 if ((*env)->ExceptionCheck(env))
1828 OIC_LOG(ERROR, TAG, "disconnect has failed");
1829 (*env)->ExceptionDescribe(env);
1830 (*env)->ExceptionClear(env);
1831 return CA_STATUS_FAILED;
1834 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1836 return CA_STATUS_OK;
1839 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1841 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1842 VERIFY_NON_NULL(env, TAG, "env is null");
1844 if (!g_gattObjectList)
1846 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1847 return CA_STATUS_OK;
1850 uint32_t length = u_arraylist_length(g_gattObjectList);
1851 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1852 for (uint32_t index = 0; index < length; index++)
1854 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1855 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1858 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1861 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1862 if (CA_STATUS_OK != res)
1864 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1869 return CA_STATUS_OK;
1872 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1874 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1875 VERIFY_NON_NULL(env, TAG, "env is null");
1877 if (!g_gattObjectList)
1879 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1880 return CA_STATUS_OK;
1883 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1886 OIC_LOG(ERROR, TAG, "address is null");
1887 return CA_STATUS_FAILED;
1890 uint32_t length = u_arraylist_length(g_gattObjectList);
1891 for (uint32_t index = 0; index < length; index++)
1893 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1896 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1900 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1901 if (!jni_setAddress)
1903 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1904 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1905 return CA_STATUS_FAILED;
1908 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1911 OIC_LOG(ERROR, TAG, "setAddress is null");
1912 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1913 return CA_STATUS_FAILED;
1916 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1917 if (!strcmp(address, setAddress))
1919 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1920 if (CA_STATUS_OK != res)
1922 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1923 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1924 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1925 return CA_STATUS_FAILED;
1927 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1928 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1929 return CA_STATUS_OK;
1931 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1933 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1935 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1936 return CA_STATUS_OK;
1939 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1941 VERIFY_NON_NULL(env, TAG, "env is null");
1942 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1944 if (!CALEIsEnableBTAdapter(env))
1946 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1947 return CA_ADAPTER_NOT_ENABLED;
1950 // get BluetoothGatt.discoverServices method
1951 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1952 jmethodID jni_mid_discoverServices = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
1953 "discoverServices", "()Z");
1954 if (!jni_mid_discoverServices)
1956 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1957 return CA_STATUS_FAILED;
1960 // call disconnect gatt method
1961 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1962 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1965 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1966 return CA_STATUS_FAILED;
1969 return CA_STATUS_OK;
1972 static void CALEWriteCharacteristicThread(void* object)
1974 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1976 bool isAttached = false;
1978 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1981 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1982 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1986 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1992 jobject gatt = (jobject)object;
1993 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1994 if (CA_STATUS_OK != ret)
1996 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2001 (*g_jvm)->DetachCurrentThread(g_jvm);
2005 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2007 OIC_LOG(DEBUG, TAG, "CALESetValueAndWriteCharacteristic");
2009 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2010 VERIFY_NON_NULL(env, TAG, "env is null");
2012 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
2015 CALEClientSendFinish(env, gatt);
2016 return CA_STATUS_FAILED;
2019 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2022 CALEClientSendFinish(env, gatt);
2023 return CA_STATUS_FAILED;
2026 ca_mutex_lock(g_threadSendStateMutex);
2028 if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
2030 OIC_LOG(INFO, TAG, "current state is SENDING");
2031 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2032 ca_mutex_unlock(g_threadSendStateMutex);
2033 return CA_STATUS_OK;
2036 if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
2039 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
2040 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2041 CALEClientSendFinish(env, gatt);
2042 ca_mutex_unlock(g_threadSendStateMutex);
2043 return CA_STATUS_FAILED;
2046 (*env)->ReleaseStringUTFChars(env, jni_address, address);
2048 ca_mutex_unlock(g_threadSendStateMutex);
2051 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2052 if (!jni_obj_character)
2054 CALEClientSendFinish(env, gatt);
2055 return CA_STATUS_FAILED;
2058 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2059 if (CA_STATUS_OK != ret)
2061 CALEClientSendFinish(env, gatt);
2062 return CA_STATUS_FAILED;
2065 // wait for callback for write Characteristic with success to sent data
2066 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2067 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2068 if (!g_isSignalSetFlag)
2070 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2071 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2072 g_threadWriteCharacteristicMutex,
2073 WAIT_TIME_WRITE_CHARACTERISTIC))
2075 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2076 g_isSignalSetFlag = false;
2077 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2078 return CA_STATUS_FAILED;
2081 // reset flag set by writeCharacteristic Callback
2082 g_isSignalSetFlag = false;
2083 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2085 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2086 return CA_STATUS_OK;
2089 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2091 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2092 VERIFY_NON_NULL(env, TAG, "env is null");
2093 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2095 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2096 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2097 CALEWriteCharacteristicThread, (void*)gattParam))
2099 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2100 return CA_STATUS_FAILED;
2103 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2104 return CA_STATUS_OK;
2107 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2108 jobject gattCharacteristic)
2110 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2111 VERIFY_NON_NULL(env, TAG, "env is null");
2112 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2113 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2115 if (!CALEIsEnableBTAdapter(env))
2117 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2118 return CA_STATUS_FAILED;
2121 // get BluetoothGatt.write characteristic method
2122 OIC_LOG(DEBUG, TAG, "write characteristic method");
2123 jmethodID jni_mid_writeCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2124 "writeCharacteristic",
2125 "(Landroid/bluetooth/"
2126 "BluetoothGattCharacteristic;)Z");
2127 if (!jni_mid_writeCharacteristic)
2129 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2130 return CA_STATUS_FAILED;
2133 // call disconnect gatt method
2134 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2135 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2136 jni_mid_writeCharacteristic,
2137 gattCharacteristic);
2140 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2144 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2145 return CA_STATUS_FAILED;
2148 return CA_STATUS_OK;
2151 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2153 VERIFY_NON_NULL(env, TAG, "env is null");
2154 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2156 if (!CALEIsEnableBTAdapter(env))
2158 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2159 return CA_STATUS_FAILED;
2162 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2165 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2166 return CA_STATUS_FAILED;
2169 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2170 if (!jni_obj_GattCharacteristic)
2172 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2173 return CA_STATUS_FAILED;
2176 OIC_LOG(DEBUG, TAG, "read characteristic method");
2177 jmethodID jni_mid_readCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2178 "readCharacteristic",
2179 "(Landroid/bluetooth/"
2180 "BluetoothGattCharacteristic;)Z");
2181 if (!jni_mid_readCharacteristic)
2183 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2184 return CA_STATUS_FAILED;
2187 // call disconnect gatt method
2188 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2189 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2190 jni_obj_GattCharacteristic);
2193 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2197 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2198 return CA_STATUS_FAILED;
2201 return CA_STATUS_OK;
2204 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2205 jobject characteristic)
2207 VERIFY_NON_NULL(env, TAG, "env is null");
2208 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2209 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2211 if (!CALEIsEnableBTAdapter(env))
2213 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2214 return CA_ADAPTER_NOT_ENABLED;
2217 // get BluetoothGatt.setCharacteristicNotification method
2218 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2219 jmethodID jni_mid_setNotification = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2220 "setCharacteristicNotification",
2221 "(Landroid/bluetooth/"
2222 "BluetoothGattCharacteristic;Z)Z");
2223 if (!jni_mid_setNotification)
2225 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2226 return CA_STATUS_FAILED;
2229 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2230 characteristic, JNI_TRUE);
2231 if (JNI_TRUE == ret)
2233 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2237 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2238 return CA_STATUS_FAILED;
2241 return CA_STATUS_OK;
2244 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2246 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2247 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2248 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2250 if (!CALEIsEnableBTAdapter(env))
2252 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2256 // get BluetoothGatt.getService method
2257 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2258 jmethodID jni_mid_getService = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2260 "(Ljava/util/UUID;)Landroid/bluetooth/"
2261 "BluetoothGattService;");
2262 if (!jni_mid_getService)
2264 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2268 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2269 if (!jni_obj_service_uuid)
2271 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2275 // get bluetooth gatt service
2276 OIC_LOG(DEBUG, TAG, "request to get service");
2277 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2278 jni_obj_service_uuid);
2279 if (!jni_obj_gattService)
2281 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2285 // get bluetooth gatt service method
2286 jmethodID jni_mid_getCharacteristic = CALEGetJNIMethodID(env, "android/bluetooth/"
2287 "BluetoothGattService",
2288 "getCharacteristic",
2289 "(Ljava/util/UUID;)"
2290 "Landroid/bluetooth/"
2291 "BluetoothGattCharacteristic;");
2292 if (!jni_mid_getCharacteristic)
2294 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2298 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2301 OIC_LOG(ERROR, TAG, "uuid is null");
2305 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2306 if (!jni_obj_tx_uuid)
2308 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2309 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2313 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2314 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2315 jni_mid_getCharacteristic,
2318 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2319 return jni_obj_GattCharacteristic;
2322 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2324 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2325 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2326 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2327 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2329 if (!CALEIsEnableBTAdapter(env))
2331 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2335 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2338 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2342 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2343 if (!jni_obj_GattCharacteristic)
2345 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2349 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2350 "/BluetoothGattCharacteristic");
2351 if (!jni_cid_BTGattCharacteristic)
2353 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2357 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2358 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2360 if (!jni_mid_setValue)
2362 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2366 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2368 if (JNI_TRUE == ret)
2370 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2374 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2379 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2380 "setWriteType", "(I)V");
2381 if (!jni_mid_setWriteType)
2383 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2387 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2388 "WRITE_TYPE_NO_RESPONSE", "I");
2389 if (!jni_fid_no_response)
2391 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2395 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2396 jni_fid_no_response);
2398 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2400 return jni_obj_GattCharacteristic;
2403 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2405 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2406 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2408 if (!CALEIsEnableBTAdapter(env))
2410 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2414 jmethodID jni_mid_getValue = CALEGetJNIMethodID(env, "android/bluetooth/"
2415 "BluetoothGattCharacteristic",
2416 "getValue", "()[B");
2417 if (!jni_mid_getValue)
2419 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2423 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2425 return jni_obj_data_array;
2428 CAResult_t CALEClientCreateUUIDList()
2432 OIC_LOG(ERROR, TAG, "g_jvm is null");
2433 return CA_STATUS_FAILED;
2436 bool isAttached = false;
2438 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2441 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2442 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2446 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2447 return CA_STATUS_FAILED;
2452 // create new object array
2453 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2454 if (!jni_cid_uuid_list)
2456 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2460 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2461 jni_cid_uuid_list, NULL);
2462 if (!jni_obj_uuid_list)
2464 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2469 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2472 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2475 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2477 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2481 (*g_jvm)->DetachCurrentThread(g_jvm);
2484 return CA_STATUS_OK;
2491 (*g_jvm)->DetachCurrentThread(g_jvm);
2493 return CA_STATUS_FAILED;
2496 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2497 jobject characteristic)
2499 VERIFY_NON_NULL(env, TAG, "env is null");
2500 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2501 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2503 if (!CALEIsEnableBTAdapter(env))
2505 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2506 return CA_ADAPTER_NOT_ENABLED;
2509 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2510 jmethodID jni_mid_getDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/"
2511 "BluetoothGattCharacteristic",
2513 "(Ljava/util/UUID;)Landroid/bluetooth/"
2514 "BluetoothGattDescriptor;");
2515 if (!jni_mid_getDescriptor)
2517 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2518 return CA_STATUS_FAILED;
2521 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2522 if (!jni_obj_cc_uuid)
2524 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2525 return CA_STATUS_FAILED;
2528 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2529 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2530 jni_mid_getDescriptor, jni_obj_cc_uuid);
2531 if (!jni_obj_descriptor)
2533 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2534 return CA_NOT_SUPPORTED;
2537 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2538 jclass jni_cid_descriptor = (*env)->FindClass(env,
2539 "android/bluetooth/BluetoothGattDescriptor");
2540 if (!jni_cid_descriptor)
2542 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2543 return CA_STATUS_FAILED;
2546 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2547 if (!jni_mid_setValue)
2549 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2550 return CA_STATUS_FAILED;
2553 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2554 "ENABLE_NOTIFICATION_VALUE", "[B");
2555 if (!jni_fid_NotiValue)
2557 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2558 return CA_STATUS_FAILED;
2561 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2563 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2564 env, jni_obj_descriptor, jni_mid_setValue,
2565 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2568 OIC_LOG(DEBUG, TAG, "setValue success");
2572 OIC_LOG(ERROR, TAG, "setValue has failed");
2573 return CA_STATUS_FAILED;
2576 jmethodID jni_mid_writeDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2578 "(Landroid/bluetooth/"
2579 "BluetoothGattDescriptor;)Z");
2580 if (!jni_mid_writeDescriptor)
2582 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2583 return CA_STATUS_FAILED;
2586 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2587 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2588 jni_obj_descriptor);
2591 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2595 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2596 return CA_STATUS_FAILED;
2599 return CA_STATUS_OK;
2602 void CALEClientCreateScanDeviceList(JNIEnv *env)
2604 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2605 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2607 ca_mutex_lock(g_deviceListMutex);
2608 // create new object array
2609 if (g_deviceList == NULL)
2611 OIC_LOG(DEBUG, TAG, "Create device list");
2613 g_deviceList = u_arraylist_create();
2615 ca_mutex_unlock(g_deviceListMutex);
2618 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2620 VERIFY_NON_NULL(device, TAG, "device is null");
2621 VERIFY_NON_NULL(env, TAG, "env is null");
2623 ca_mutex_lock(g_deviceListMutex);
2627 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2629 CALEClientSetScanFlag(false);
2630 if(CA_STATUS_OK != CALEClientStopScan())
2632 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2635 ca_mutex_unlock(g_deviceListMutex);
2636 return CA_STATUS_FAILED;
2639 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2640 if (!jni_remoteAddress)
2642 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2643 ca_mutex_unlock(g_deviceListMutex);
2644 return CA_STATUS_FAILED;
2647 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2650 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2651 ca_mutex_unlock(g_deviceListMutex);
2652 return CA_STATUS_FAILED;
2655 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2657 jobject gdevice = (*env)->NewGlobalRef(env, device);
2658 u_arraylist_add(g_deviceList, gdevice);
2659 ca_cond_signal(g_deviceDescCond);
2660 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2662 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2664 ca_mutex_unlock(g_deviceListMutex);
2666 return CA_STATUS_OK;
2669 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2671 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2672 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2676 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2680 uint32_t length = u_arraylist_length(g_deviceList);
2681 for (uint32_t index = 0; index < length; index++)
2683 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2686 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2690 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2691 if (!jni_setAddress)
2693 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2697 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2700 OIC_LOG(ERROR, TAG, "setAddress is null");
2704 if (!strcmp(remoteAddress, setAddress))
2706 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2710 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2713 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2718 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2720 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2721 VERIFY_NON_NULL(env, TAG, "env is null");
2723 ca_mutex_lock(g_deviceListMutex);
2727 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2728 ca_mutex_unlock(g_deviceListMutex);
2729 return CA_STATUS_FAILED;
2732 uint32_t length = u_arraylist_length(g_deviceList);
2733 for (uint32_t index = 0; index < length; index++)
2735 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2738 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2741 (*env)->DeleteGlobalRef(env, jarrayObj);
2745 OICFree(g_deviceList);
2746 g_deviceList = NULL;
2748 ca_mutex_unlock(g_deviceListMutex);
2749 return CA_STATUS_OK;
2752 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2754 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2755 VERIFY_NON_NULL(address, TAG, "address is null");
2756 VERIFY_NON_NULL(env, TAG, "env is null");
2758 ca_mutex_lock(g_deviceListMutex);
2762 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2763 ca_mutex_unlock(g_deviceListMutex);
2764 return CA_STATUS_FAILED;
2767 uint32_t length = u_arraylist_length(g_deviceList);
2768 for (uint32_t index = 0; index < length; index++)
2770 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2773 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2774 ca_mutex_unlock(g_deviceListMutex);
2775 return CA_STATUS_FAILED;
2778 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2779 if (!jni_setAddress)
2781 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2782 ca_mutex_unlock(g_deviceListMutex);
2783 return CA_STATUS_FAILED;
2786 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2789 OIC_LOG(ERROR, TAG, "setAddress is null");
2790 ca_mutex_unlock(g_deviceListMutex);
2791 return CA_STATUS_FAILED;
2794 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2797 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2798 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2799 ca_mutex_unlock(g_deviceListMutex);
2800 return CA_STATUS_FAILED;
2803 if (!strcmp(setAddress, remoteAddress))
2805 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2806 (*env)->DeleteGlobalRef(env, jarrayObj);
2808 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2809 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2811 if (NULL == u_arraylist_remove(g_deviceList, index))
2813 OIC_LOG(ERROR, TAG, "List removal failed.");
2814 ca_mutex_unlock(g_deviceListMutex);
2815 return CA_STATUS_FAILED;
2817 ca_mutex_unlock(g_deviceListMutex);
2818 return CA_STATUS_OK;
2820 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2821 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2824 ca_mutex_unlock(g_deviceListMutex);
2825 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2827 return CA_STATUS_OK;
2834 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2836 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2837 VERIFY_NON_NULL(env, TAG, "env is null");
2838 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2840 ca_mutex_lock(g_gattObjectMutex);
2842 if (!g_gattObjectList)
2844 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2845 ca_mutex_unlock(g_gattObjectMutex);
2846 return CA_STATUS_FAILED;
2849 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2850 if (!jni_remoteAddress)
2852 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2853 ca_mutex_unlock(g_gattObjectMutex);
2854 return CA_STATUS_FAILED;
2857 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2860 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2861 ca_mutex_unlock(g_gattObjectMutex);
2862 return CA_STATUS_FAILED;
2865 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2866 if (!CALEClientIsGattObjInList(env, remoteAddress))
2868 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2869 u_arraylist_add(g_gattObjectList, newGatt);
2870 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2873 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2874 ca_mutex_unlock(g_gattObjectMutex);
2875 return CA_STATUS_OK;
2878 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2880 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2881 VERIFY_NON_NULL(env, TAG, "env is null");
2882 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2884 uint32_t length = u_arraylist_length(g_gattObjectList);
2885 for (uint32_t index = 0; index < length; index++)
2888 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2891 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2895 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2896 if (!jni_setAddress)
2898 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2902 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2905 OIC_LOG(ERROR, TAG, "setAddress is null");
2909 if (!strcmp(remoteAddress, setAddress))
2911 OIC_LOG(DEBUG, TAG, "the device is already set");
2912 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2917 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2922 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2926 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2928 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2929 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2930 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2932 ca_mutex_lock(g_gattObjectMutex);
2933 uint32_t length = u_arraylist_length(g_gattObjectList);
2934 for (uint32_t index = 0; index < length; index++)
2936 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2939 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2940 ca_mutex_unlock(g_gattObjectMutex);
2944 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2945 if (!jni_setAddress)
2947 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2948 ca_mutex_unlock(g_gattObjectMutex);
2952 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2955 OIC_LOG(ERROR, TAG, "setAddress is null");
2956 ca_mutex_unlock(g_gattObjectMutex);
2960 if (!strcmp(remoteAddress, setAddress))
2962 OIC_LOG(DEBUG, TAG, "the device is already set");
2963 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2964 ca_mutex_unlock(g_gattObjectMutex);
2967 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2970 ca_mutex_unlock(g_gattObjectMutex);
2971 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2975 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2977 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2978 VERIFY_NON_NULL(env, TAG, "env is null");
2980 ca_mutex_lock(g_gattObjectMutex);
2981 if (!g_gattObjectList)
2983 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2984 ca_mutex_unlock(g_gattObjectMutex);
2985 return CA_STATUS_OK;
2988 uint32_t length = u_arraylist_length(g_gattObjectList);
2989 for (uint32_t index = 0; index < length; index++)
2991 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2994 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2997 (*env)->DeleteGlobalRef(env, jarrayObj);
3001 OICFree(g_gattObjectList);
3002 g_gattObjectList = NULL;
3003 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
3004 ca_mutex_unlock(g_gattObjectMutex);
3005 return CA_STATUS_OK;
3008 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
3010 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
3011 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
3012 VERIFY_NON_NULL(env, TAG, "env is null");
3014 ca_mutex_lock(g_gattObjectMutex);
3015 if (!g_gattObjectList)
3017 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3018 ca_mutex_unlock(g_gattObjectMutex);
3019 return CA_STATUS_OK;
3022 uint32_t length = u_arraylist_length(g_gattObjectList);
3023 for (uint32_t index = 0; index < length; index++)
3025 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3028 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3029 ca_mutex_unlock(g_gattObjectMutex);
3030 return CA_STATUS_FAILED;
3033 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3034 if (!jni_setAddress)
3036 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3037 ca_mutex_unlock(g_gattObjectMutex);
3038 return CA_STATUS_FAILED;
3041 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3044 OIC_LOG(ERROR, TAG, "setAddress is null");
3045 ca_mutex_unlock(g_gattObjectMutex);
3046 return CA_STATUS_FAILED;
3049 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3050 if (!jni_remoteAddress)
3052 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3053 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3054 ca_mutex_unlock(g_gattObjectMutex);
3055 return CA_STATUS_FAILED;
3058 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3061 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3062 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3063 ca_mutex_unlock(g_gattObjectMutex);
3064 return CA_STATUS_FAILED;
3067 if (!strcmp(setAddress, remoteAddress))
3069 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3070 (*env)->DeleteGlobalRef(env, jarrayObj);
3072 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3073 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3075 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3077 OIC_LOG(ERROR, TAG, "List removal failed.");
3078 ca_mutex_unlock(g_gattObjectMutex);
3079 return CA_STATUS_FAILED;
3081 ca_mutex_unlock(g_gattObjectMutex);
3082 return CA_STATUS_OK;
3084 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3085 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3088 ca_mutex_unlock(g_gattObjectMutex);
3089 OIC_LOG(DEBUG, TAG, "there are no target object");
3090 return CA_STATUS_OK;
3093 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3095 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3096 VERIFY_NON_NULL(addr, TAG, "addr is null");
3097 VERIFY_NON_NULL(env, TAG, "env is null");
3099 ca_mutex_lock(g_gattObjectMutex);
3100 if (!g_gattObjectList)
3102 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3103 ca_mutex_unlock(g_gattObjectMutex);
3104 return CA_STATUS_OK;
3107 uint32_t length = u_arraylist_length(g_gattObjectList);
3108 for (uint32_t index = 0; index < length; index++)
3110 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3113 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3114 ca_mutex_unlock(g_gattObjectMutex);
3115 return CA_STATUS_FAILED;
3118 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3119 if (!jni_setAddress)
3121 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3122 ca_mutex_unlock(g_gattObjectMutex);
3123 return CA_STATUS_FAILED;
3126 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3129 OIC_LOG(ERROR, TAG, "setAddress is null");
3130 ca_mutex_unlock(g_gattObjectMutex);
3131 return CA_STATUS_FAILED;
3134 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3137 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3138 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3139 ca_mutex_unlock(g_gattObjectMutex);
3140 return CA_STATUS_FAILED;
3143 if (!strcmp(setAddress, remoteAddress))
3145 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3146 (*env)->DeleteGlobalRef(env, jarrayObj);
3148 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3149 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3150 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3152 OIC_LOG(ERROR, TAG, "List removal failed.");
3153 ca_mutex_unlock(g_gattObjectMutex);
3154 return CA_STATUS_FAILED;
3156 ca_mutex_unlock(g_gattObjectMutex);
3157 return CA_STATUS_OK;
3159 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3160 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3163 ca_mutex_unlock(g_gattObjectMutex);
3164 OIC_LOG(DEBUG, TAG, "there are no target object");
3165 return CA_STATUS_FAILED;
3168 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3170 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3172 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3173 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3175 // get Bluetooth Address
3176 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3177 if (!jni_btTargetAddress)
3179 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3183 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3186 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3190 // get method ID of getDevice()
3191 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
3192 "getDevice", METHODID_BT_DEVICE);
3193 if (!jni_mid_getDevice)
3195 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3196 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3200 size_t length = u_arraylist_length(g_gattObjectList);
3201 for (size_t index = 0; index < length; index++)
3203 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3206 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3207 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3211 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3212 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3213 if (!jni_obj_device)
3215 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3216 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3220 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3223 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3224 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3228 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3231 OIC_LOG(ERROR, TAG, "btAddress is not available");
3232 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3236 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3237 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3238 if (!strcmp(targetAddress, btAddress))
3240 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3243 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3246 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3248 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3249 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3250 (*env)->DeleteLocalRef(env, jni_btAddress);
3251 (*env)->DeleteLocalRef(env, jni_obj_device);
3252 return jni_LEAddress;
3254 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3255 (*env)->DeleteLocalRef(env, jni_btAddress);
3256 (*env)->DeleteLocalRef(env, jni_obj_device);
3259 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3267 CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
3268 uint16_t target_state)
3270 VERIFY_NON_NULL(address, TAG, "address is null");
3272 if (!g_deviceStateList)
3274 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3275 return CA_STATUS_FAILED;
3278 ca_mutex_lock(g_deviceStateListMutex);
3280 if (CALEClientIsDeviceInList(address))
3282 CALEState_t* curState = CALEClientGetStateInfo(address);
3285 OIC_LOG(ERROR, TAG, "curState is null");
3286 ca_mutex_unlock(g_deviceStateListMutex);
3287 return CA_STATUS_FAILED;
3292 case CA_LE_CONNECTION_STATE:
3293 curState->connectedState = target_state;
3295 case CA_LE_SEND_STATE:
3296 curState->sendState = target_state;
3301 OIC_LOG_V(INFO, TAG, "update state : - addr : %s, "
3302 "conn : %d, send : %d, ACFlag : %d",
3303 curState->address, curState->connectedState,
3304 curState->sendState, curState->autoConnectFlag);
3306 else /** state is added newly **/
3308 if (strlen(address) > CA_MACADDR_SIZE)
3310 OIC_LOG(ERROR, TAG, "address is not proper");
3311 ca_mutex_unlock(g_deviceStateListMutex);
3312 return CA_STATUS_INVALID_PARAM;
3315 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3318 OIC_LOG(ERROR, TAG, "out of memory");
3319 ca_mutex_unlock(g_deviceStateListMutex);
3320 return CA_MEMORY_ALLOC_FAILED;
3323 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3327 case CA_LE_CONNECTION_STATE:
3328 newstate->connectedState = target_state;
3329 newstate->sendState = STATE_SEND_NONE;
3331 case CA_LE_SEND_STATE:
3332 newstate->connectedState = STATE_DISCONNECTED;
3333 newstate->sendState = target_state;
3338 OIC_LOG_V(INFO, TAG, "Set newState to List - addr : %s, "
3339 "conn : %d, send : %d, ACFlag : %d",
3340 newstate->address, newstate->connectedState,
3341 newstate->sendState, newstate->autoConnectFlag);
3342 u_arraylist_add(g_deviceStateList, newstate); // update new state
3345 ca_mutex_unlock(g_deviceStateListMutex);
3347 return CA_STATUS_OK;
3350 bool CALEClientIsDeviceInList(const char* remoteAddress)
3352 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3354 if (!g_deviceStateList)
3356 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3360 uint32_t length = u_arraylist_length(g_deviceStateList);
3361 for (uint32_t index = 0; index < length; index++)
3363 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3366 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3370 if (!strcmp(remoteAddress, state->address))
3372 OIC_LOG(DEBUG, TAG, "the device is already set");
3381 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3385 CAResult_t CALEClientRemoveAllDeviceState()
3387 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3389 ca_mutex_lock(g_deviceStateListMutex);
3390 if (!g_deviceStateList)
3392 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3393 ca_mutex_unlock(g_deviceStateListMutex);
3394 return CA_STATUS_FAILED;
3397 uint32_t length = u_arraylist_length(g_deviceStateList);
3398 for (uint32_t index = 0; index < length; index++)
3400 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3403 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3409 OICFree(g_deviceStateList);
3410 g_deviceStateList = NULL;
3411 ca_mutex_unlock(g_deviceStateListMutex);
3413 return CA_STATUS_OK;
3416 CAResult_t CALEClientResetDeviceStateForAll()
3418 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3420 ca_mutex_lock(g_deviceStateListMutex);
3421 if (!g_deviceStateList)
3423 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3424 ca_mutex_unlock(g_deviceStateListMutex);
3425 return CA_STATUS_FAILED;
3428 size_t length = u_arraylist_length(g_deviceStateList);
3429 for (size_t index = 0; index < length; index++)
3431 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3434 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3438 // autoConnectFlag value will be not changed,
3439 // since it has reset only termination case.
3440 state->connectedState = STATE_DISCONNECTED;
3441 state->sendState = STATE_SEND_NONE;
3443 ca_mutex_unlock(g_deviceStateListMutex);
3445 return CA_STATUS_OK;
3448 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3450 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3451 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3453 if (!g_deviceStateList)
3455 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3456 return CA_STATUS_FAILED;
3459 uint32_t length = u_arraylist_length(g_deviceStateList);
3460 for (uint32_t index = 0; index < length; index++)
3462 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3465 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3469 if (!strcmp(state->address, remoteAddress))
3471 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3473 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3475 if (NULL == targetState)
3477 OIC_LOG(ERROR, TAG, "List removal failed.");
3478 return CA_STATUS_FAILED;
3481 OICFree(targetState);
3482 return CA_STATUS_OK;
3486 return CA_STATUS_OK;
3489 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3491 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3493 if (!g_deviceStateList)
3495 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3499 uint32_t length = u_arraylist_length(g_deviceStateList);
3500 OIC_LOG_V(DEBUG, TAG, "size of deviceStateList is %d", length);
3502 for (uint32_t index = 0; index < length; index++)
3504 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3507 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3511 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3512 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3514 if (!strcmp(state->address, remoteAddress))
3516 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3523 bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
3524 uint16_t target_state)
3526 OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
3527 state_type, target_state);
3528 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3530 ca_mutex_lock(g_deviceStateListMutex);
3531 if (!g_deviceStateList)
3533 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3534 ca_mutex_unlock(g_deviceStateListMutex);
3538 CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
3541 OIC_LOG(ERROR, TAG, "state is null");
3542 ca_mutex_unlock(g_deviceStateListMutex);
3546 uint16_t curValue = 0;
3549 case CA_LE_CONNECTION_STATE:
3550 curValue = state->connectedState;
3552 case CA_LE_SEND_STATE:
3553 curValue = state->sendState;
3559 if (target_state == curValue)
3561 ca_mutex_unlock(g_deviceStateListMutex);
3566 ca_mutex_unlock(g_deviceStateListMutex);
3570 ca_mutex_unlock(g_deviceStateListMutex);
3574 void CALEClientCreateDeviceList()
3576 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3578 // create new object array
3579 if (!g_gattObjectList)
3581 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3583 g_gattObjectList = u_arraylist_create();
3586 if (!g_deviceStateList)
3588 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3590 g_deviceStateList = u_arraylist_create();
3595 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3597 g_deviceList = u_arraylist_create();
3602 * Check Sent Count for remove g_sendBuffer
3604 void CALEClientUpdateSendCnt(JNIEnv *env)
3606 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3608 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3610 ca_mutex_lock(g_threadMutex);
3614 if (g_targetCnt <= g_currentSentCnt)
3617 g_currentSentCnt = 0;
3621 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3622 g_sendBuffer = NULL;
3624 // notity the thread
3625 ca_cond_signal(g_threadCond);
3627 CALEClientSetSendFinishFlag(true);
3628 OIC_LOG(DEBUG, TAG, "set signal for send data");
3631 ca_mutex_unlock(g_threadMutex);
3634 CAResult_t CALEClientInitGattMutexVaraibles()
3636 if (NULL == g_bleReqRespClientCbMutex)
3638 g_bleReqRespClientCbMutex = ca_mutex_new();
3639 if (NULL == g_bleReqRespClientCbMutex)
3641 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3642 return CA_STATUS_FAILED;
3646 if (NULL == g_bleServerBDAddressMutex)
3648 g_bleServerBDAddressMutex = ca_mutex_new();
3649 if (NULL == g_bleServerBDAddressMutex)
3651 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3652 return CA_STATUS_FAILED;
3656 if (NULL == g_threadMutex)
3658 g_threadMutex = ca_mutex_new();
3659 if (NULL == g_threadMutex)
3661 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3662 return CA_STATUS_FAILED;
3666 if (NULL == g_threadSendMutex)
3668 g_threadSendMutex = ca_mutex_new();
3669 if (NULL == g_threadSendMutex)
3671 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3672 return CA_STATUS_FAILED;
3676 if (NULL == g_deviceListMutex)
3678 g_deviceListMutex = ca_mutex_new();
3679 if (NULL == g_deviceListMutex)
3681 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3682 return CA_STATUS_FAILED;
3686 if (NULL == g_gattObjectMutex)
3688 g_gattObjectMutex = ca_mutex_new();
3689 if (NULL == g_gattObjectMutex)
3691 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3692 return CA_STATUS_FAILED;
3696 if (NULL == g_deviceStateListMutex)
3698 g_deviceStateListMutex = ca_mutex_new();
3699 if (NULL == g_deviceStateListMutex)
3701 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3702 return CA_STATUS_FAILED;
3706 if (NULL == g_SendFinishMutex)
3708 g_SendFinishMutex = ca_mutex_new();
3709 if (NULL == g_SendFinishMutex)
3711 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3712 return CA_STATUS_FAILED;
3716 if (NULL == g_scanMutex)
3718 g_scanMutex = ca_mutex_new();
3719 if (NULL == g_scanMutex)
3721 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3722 return CA_STATUS_FAILED;
3726 if (NULL == g_threadWriteCharacteristicMutex)
3728 g_threadWriteCharacteristicMutex = ca_mutex_new();
3729 if (NULL == g_threadWriteCharacteristicMutex)
3731 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3732 return CA_STATUS_FAILED;
3736 if (NULL == g_deviceScanRetryDelayMutex)
3738 g_deviceScanRetryDelayMutex = ca_mutex_new();
3739 if (NULL == g_deviceScanRetryDelayMutex)
3741 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3742 return CA_STATUS_FAILED;
3746 if (NULL == g_threadSendStateMutex)
3748 g_threadSendStateMutex = ca_mutex_new();
3749 if (NULL == g_threadSendStateMutex)
3751 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3752 return CA_STATUS_FAILED;
3756 return CA_STATUS_OK;
3759 void CALEClientTerminateGattMutexVariables()
3761 ca_mutex_free(g_bleReqRespClientCbMutex);
3762 g_bleReqRespClientCbMutex = NULL;
3764 ca_mutex_free(g_bleServerBDAddressMutex);
3765 g_bleServerBDAddressMutex = NULL;
3767 ca_mutex_free(g_threadMutex);
3768 g_threadMutex = NULL;
3770 ca_mutex_free(g_threadSendMutex);
3771 g_threadSendMutex = NULL;
3773 ca_mutex_free(g_deviceListMutex);
3774 g_deviceListMutex = NULL;
3776 ca_mutex_free(g_SendFinishMutex);
3777 g_SendFinishMutex = NULL;
3779 ca_mutex_free(g_scanMutex);
3782 ca_mutex_free(g_threadWriteCharacteristicMutex);
3783 g_threadWriteCharacteristicMutex = NULL;
3785 ca_mutex_free(g_deviceScanRetryDelayMutex);
3786 g_deviceScanRetryDelayMutex = NULL;
3788 ca_mutex_free(g_threadSendStateMutex);
3789 g_threadSendStateMutex = NULL;
3792 void CALEClientSetSendFinishFlag(bool flag)
3794 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3796 ca_mutex_lock(g_SendFinishMutex);
3797 g_isFinishedSendData = flag;
3798 ca_mutex_unlock(g_SendFinishMutex);
3805 CAResult_t CAStartLEGattClient()
3807 // init mutex for send logic
3808 if (!g_deviceDescCond)
3810 g_deviceDescCond = ca_cond_new();
3815 g_threadCond = ca_cond_new();
3818 if (!g_threadWriteCharacteristicCond)
3820 g_threadWriteCharacteristicCond = ca_cond_new();
3823 CAResult_t ret = CALEClientStartScan();
3824 if (CA_STATUS_OK != ret)
3826 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3830 g_isStartedLEClient = true;
3831 return CA_STATUS_OK;
3834 void CAStopLEGattClient()
3836 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3840 OIC_LOG(ERROR, TAG, "g_jvm is null");
3844 bool isAttached = false;
3846 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3849 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3850 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3854 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3860 CAResult_t ret = CALEClientDisconnectAll(env);
3861 if (CA_STATUS_OK != ret)
3863 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3866 ret = CALEClientStopScan();
3867 if(CA_STATUS_OK != ret)
3869 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3872 ca_mutex_lock(g_threadMutex);
3873 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3874 ca_cond_signal(g_threadCond);
3875 CALEClientSetSendFinishFlag(true);
3876 ca_mutex_unlock(g_threadMutex);
3878 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3879 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3880 ca_cond_signal(g_threadWriteCharacteristicCond);
3881 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3883 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3884 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3885 ca_cond_signal(g_deviceScanRetryDelayCond);
3886 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3888 ca_cond_free(g_deviceDescCond);
3889 ca_cond_free(g_threadCond);
3890 ca_cond_free(g_threadWriteCharacteristicCond);
3891 ca_cond_free(g_deviceScanRetryDelayCond);
3893 g_deviceDescCond = NULL;
3894 g_threadCond = NULL;
3895 g_threadWriteCharacteristicCond = NULL;
3896 g_deviceScanRetryDelayCond = NULL;
3900 (*g_jvm)->DetachCurrentThread(g_jvm);
3905 CAResult_t CAInitializeLEGattClient()
3907 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3908 CALEClientInitialize();
3909 return CA_STATUS_OK;
3912 void CATerminateLEGattClient()
3914 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3915 CAStopLEGattClient();
3916 CALEClientTerminate();
3919 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3920 uint32_t dataLen, CALETransferType_t type,
3923 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3924 VERIFY_NON_NULL(data, TAG, "data is null");
3925 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3927 if (LE_UNICAST != type || position < 0)
3929 OIC_LOG(ERROR, TAG, "this request is not unicast");
3930 return CA_STATUS_INVALID_PARAM;
3933 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3936 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3938 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3939 VERIFY_NON_NULL(data, TAG, "data is null");
3941 return CALEClientSendMulticastMessage(data, dataLen);
3944 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3946 ca_mutex_lock(g_bleReqRespClientCbMutex);
3947 g_CABLEClientDataReceivedCallback = callback;
3948 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3951 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3953 g_threadPoolHandle = handle;
3956 CAResult_t CAGetLEAddress(char **local_address)
3958 VERIFY_NON_NULL(local_address, TAG, "local_address");
3959 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3960 return CA_NOT_SUPPORTED;
3963 JNIEXPORT void JNICALL
3964 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3967 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3968 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3969 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3970 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3972 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3975 JNIEXPORT void JNICALL
3976 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3979 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3980 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3981 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3982 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3984 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3987 JNIEXPORT void JNICALL
3988 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3991 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3992 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3993 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3995 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3996 if (CA_STATUS_OK != res)
3998 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
4002 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
4004 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
4006 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4007 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4009 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
4010 "getDevice", METHODID_BT_DEVICE);
4011 if (!jni_mid_getDevice)
4013 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4017 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4018 if (!jni_obj_device)
4020 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4024 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4027 OIC_LOG(ERROR, TAG, "jni_address is null");
4031 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4036 * Class: org_iotivity_ca_jar_caleinterface
4037 * Method: CALeGattConnectionStateChangeCallback
4038 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4040 JNIEXPORT void JNICALL
4041 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4047 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4049 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4050 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4051 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4053 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4054 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4055 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4057 if (gatt_success == status && state_connected == newstate) // le connected
4059 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4065 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4068 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4070 if (CA_STATUS_OK != res)
4072 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4073 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4076 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4078 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4081 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4082 if (CA_STATUS_OK != res)
4084 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4088 res = CALEClientDiscoverServices(env, gatt);
4089 if (CA_STATUS_OK != res)
4091 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4095 else if (state_disconnected == newstate) // le disconnected
4097 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4100 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4104 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4107 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4108 STATE_DISCONNECTED);
4109 if (CA_STATUS_OK != res)
4111 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4112 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4115 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4117 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4120 CAResult_t res = CALEClientGattClose(env, gatt);
4121 if (CA_STATUS_OK != res)
4123 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4126 if (GATT_ERROR == status)
4128 // when we get GATT ERROR(0x85), gatt connection can be called again.
4129 OIC_LOG(INFO, TAG, "retry gatt connect");
4131 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4134 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4138 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4141 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4145 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4148 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4156 if (CALECheckConnectionStateValue(status))
4158 // this state is unexpected reason to disconnect
4159 // if the reason is suitable, connection logic of the device will be destroyed.
4160 OIC_LOG(INFO, TAG, "connection logic destroy");
4165 // other reason except for gatt_success is expected to running
4166 // background connection in BT platform.
4167 OIC_LOG(INFO, TAG, "unknown state or manual disconnected state");
4168 CALEClientUpdateSendCnt(env);
4175 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4176 g_sendBuffer = NULL;
4184 CALEClientSendFinish(env, gatt);
4189 * Class: org_iotivity_ca_jar_caleinterface
4190 * Method: CALeGattServicesDiscoveredCallback
4191 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4193 JNIEXPORT void JNICALL
4194 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4199 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4200 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4201 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4202 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4204 if (0 != status) // discovery error
4206 CALEClientSendFinish(env, gatt);
4210 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4213 CALEClientSendFinish(env, gatt);
4217 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4220 CALEClientSendFinish(env, gatt);
4224 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4227 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4231 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4232 if (!jni_obj_GattCharacteristic)
4234 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4238 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4239 jni_obj_GattCharacteristic);
4240 if (CA_STATUS_OK != res)
4242 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4246 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4247 if (CA_STATUS_OK != res)
4249 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
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");
4270 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4271 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4276 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4277 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4278 CALEClientSendFinish(env, gatt);
4283 * Class: org_iotivity_ca_jar_caleinterface
4284 * Method: CALeGattCharacteristicWritjclasseCallback
4285 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4287 JNIEXPORT void JNICALL
4288 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4289 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4292 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4293 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4294 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4295 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4297 // send success & signal
4298 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4304 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4310 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4311 if (gatt_success != status) // error case
4313 OIC_LOG(ERROR, TAG, "send failure");
4316 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4317 if (CA_STATUS_OK != res)
4319 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4320 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4321 g_isSignalSetFlag = true;
4322 ca_cond_signal(g_threadWriteCharacteristicCond);
4323 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4325 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4327 if (CA_STATUS_OK != res)
4329 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4332 if (g_clientErrorCallback)
4334 jint length = (*env)->GetArrayLength(env, data);
4335 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4338 CALEClientSendFinish(env, gatt);
4344 OIC_LOG(DEBUG, TAG, "send success");
4345 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
4346 STATE_SEND_SUCCESS);
4347 if (CA_STATUS_OK != res)
4349 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4352 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4353 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4354 g_isSignalSetFlag = true;
4355 ca_cond_signal(g_threadWriteCharacteristicCond);
4356 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4358 CALEClientUpdateSendCnt(env);
4361 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4367 CALEClientSendFinish(env, gatt);
4372 * Class: org_iotivity_ca_jar_caleinterface
4373 * Method: CALeGattCharacteristicChangedCallback
4374 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4376 JNIEXPORT void JNICALL
4377 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4378 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4380 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4381 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4382 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4383 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4384 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4386 // get Byte Array and convert to uint8_t*
4387 jint length = (*env)->GetArrayLength(env, data);
4390 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4392 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4393 jni_byte_responseData);
4395 uint8_t* receivedData = OICMalloc(length);
4398 OIC_LOG(ERROR, TAG, "receivedData is null");
4402 memcpy(receivedData, jni_byte_responseData, length);
4403 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4405 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4408 OIC_LOG(ERROR, TAG, "jni_address is null");
4409 OICFree(receivedData);
4413 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4416 OIC_LOG(ERROR, TAG, "address is null");
4417 OICFree(receivedData);
4421 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4422 receivedData, length);
4424 ca_mutex_lock(g_bleServerBDAddressMutex);
4425 uint32_t sentLength = 0;
4426 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4428 ca_mutex_unlock(g_bleServerBDAddressMutex);
4430 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4434 * Class: org_iotivity_ca_jar_caleinterface
4435 * Method: CALeGattDescriptorWriteCallback
4436 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4438 JNIEXPORT void JNICALL
4439 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4443 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4444 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4445 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4446 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4448 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4449 if (gatt_success != status) // error
4454 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4460 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4463 CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
4464 STATE_SERVICE_CONNECTED);
4465 if (CA_STATUS_OK != res)
4467 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4468 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4472 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4476 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4477 if (CA_STATUS_OK != res)
4479 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4488 CALEClientSendFinish(env, gatt);