1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define GATT_CONNECTION_PRIORITY_BALANCED 0
46 #define GATT_FAILURE 257
47 #define GATT_INSUFFICIENT_AUTHENTICATION 5
48 #define GATT_INSUFFICIENT_ENCRYPTION 15
49 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
50 #define GATT_INVALID_OFFSET 7
51 #define GATT_READ_NOT_PERMITTED 2
52 #define GATT_REQUEST_NOT_SUPPORTED 6
53 #define GATT_WRITE_NOT_PERMITTED 3
55 static ca_thread_pool_t g_threadPoolHandle = NULL;
58 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
59 static u_arraylist_t *g_gattObjectList = NULL;
60 static u_arraylist_t *g_deviceStateList = NULL;
62 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
63 static CABLEErrorHandleCallback g_clientErrorCallback;
64 static jobject g_leScanCallback = NULL;
65 static jobject g_leGattCallback = NULL;
66 static jobject g_context = NULL;
67 static jobjectArray g_uuidList = NULL;
69 // it will be prevent to start send logic when adapter has stopped.
70 static bool g_isStartedLEClient = false;
71 static bool g_isStartedMulticastServer = false;
72 static bool g_isStartedScan = false;
74 static jbyteArray g_sendBuffer = NULL;
75 static uint32_t g_targetCnt = 0;
76 static uint32_t g_currentSentCnt = 0;
77 static bool g_isFinishedSendData = false;
78 static ca_mutex g_SendFinishMutex = NULL;
79 static ca_mutex g_threadMutex = NULL;
80 static ca_cond g_threadCond = NULL;
81 static ca_cond g_deviceDescCond = NULL;
83 static ca_mutex g_threadSendMutex = NULL;
84 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
85 static ca_cond g_threadWriteCharacteristicCond = NULL;
86 static bool g_isSignalSetFlag = false;
88 static ca_mutex g_bleReqRespClientCbMutex = NULL;
89 static ca_mutex g_bleServerBDAddressMutex = NULL;
91 static ca_mutex g_deviceListMutex = NULL;
92 static ca_mutex g_gattObjectMutex = NULL;
93 static ca_mutex g_deviceStateListMutex = NULL;
95 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
96 static ca_cond g_deviceScanRetryDelayCond = NULL;
98 static ca_mutex g_scanMutex = 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);
339 if (g_leGattCallback)
341 (*env)->DeleteGlobalRef(env, g_leGattCallback);
346 (*env)->DeleteGlobalRef(env, g_sendBuffer);
351 (*env)->DeleteGlobalRef(env, g_uuidList);
354 CAResult_t ret = CALEClientRemoveAllDeviceState();
355 if (CA_STATUS_OK != ret)
357 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
360 ret = CALEClientRemoveAllScanDevices(env);
361 if (CA_STATUS_OK != ret)
363 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
366 ret = CALEClientRemoveAllGattObjs(env);
367 if (CA_STATUS_OK != ret)
369 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
372 g_isStartedMulticastServer = false;
373 CALEClientSetScanFlag(false);
374 CALEClientSetSendFinishFlag(false);
376 CALEClientTerminateGattMutexVariables();
377 CALEClientDestroyJniInterface();
379 ca_cond_free(g_deviceDescCond);
380 ca_cond_free(g_threadCond);
381 ca_cond_free(g_threadWriteCharacteristicCond);
382 ca_cond_free(g_deviceScanRetryDelayCond);
384 g_deviceDescCond = NULL;
386 g_threadWriteCharacteristicCond = NULL;
387 g_deviceScanRetryDelayCond = NULL;
389 g_isSignalSetFlag = false;
393 (*g_jvm)->DetachCurrentThread(g_jvm);
397 CAResult_t CALEClientDestroyJniInterface()
399 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
403 OIC_LOG(ERROR, TAG, "g_jvm is null");
404 return CA_STATUS_FAILED;
407 bool isAttached = false;
409 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
412 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
413 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
417 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
418 return CA_STATUS_FAILED;
423 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
424 if (!jni_LeInterface)
426 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
430 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
431 "destroyLeInterface",
433 if (!jni_InterfaceDestroyMethod)
435 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
439 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
441 if ((*env)->ExceptionCheck(env))
443 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
444 (*env)->ExceptionDescribe(env);
445 (*env)->ExceptionClear(env);
449 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
453 (*g_jvm)->DetachCurrentThread(g_jvm);
462 (*g_jvm)->DetachCurrentThread(g_jvm);
465 return CA_STATUS_FAILED;
468 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
470 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
471 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
475 CAResult_t res = CALEClientDisconnect(env, gatt);
476 if (CA_STATUS_OK != res)
478 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
481 CALEClientUpdateSendCnt(env);
484 CAResult_t CALEClientSendUnicastMessage(const char* address,
486 const uint32_t dataLen)
488 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
489 VERIFY_NON_NULL(address, TAG, "address is null");
490 VERIFY_NON_NULL(data, TAG, "data is null");
492 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
495 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
496 const uint32_t dataLen)
498 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
499 VERIFY_NON_NULL(data, TAG, "data is null");
503 OIC_LOG(ERROR, TAG, "g_jvm is null");
504 return CA_STATUS_FAILED;
507 bool isAttached = false;
509 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
512 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
513 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
517 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
518 return CA_STATUS_FAILED;
523 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
524 if (CA_STATUS_OK != ret)
526 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
531 (*g_jvm)->DetachCurrentThread(g_jvm);
537 CAResult_t CALEClientStartUnicastServer(const char* address)
539 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
541 return CA_NOT_SUPPORTED;
544 CAResult_t CALEClientStartMulticastServer()
546 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
548 if (g_isStartedMulticastServer)
550 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
551 return CA_STATUS_FAILED;
556 OIC_LOG(ERROR, TAG, "g_jvm is null");
557 return CA_STATUS_FAILED;
560 bool isAttached = false;
562 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
565 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
566 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
570 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
571 return CA_STATUS_FAILED;
576 g_isStartedMulticastServer = true;
577 CAResult_t ret = CALEClientStartScan();
578 if (CA_STATUS_OK != ret)
580 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
585 (*g_jvm)->DetachCurrentThread(g_jvm);
591 void CALEClientStopUnicastServer()
593 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
596 void CALEClientStopMulticastServer()
598 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
599 g_isStartedMulticastServer = false;
600 CAResult_t res = CALEClientStopScan();
601 if (CA_STATUS_OK != res)
603 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
608 void CALEClientSetCallback(CAPacketReceiveCallback callback)
610 g_packetReceiveCallback = callback;
613 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
615 g_clientErrorCallback = callback;
618 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
620 VERIFY_NON_NULL(env, TAG, "env");
624 return CA_STATUS_FAILED;
627 if (0 == u_arraylist_length(g_deviceList) // multicast
628 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
630 // Wait for LE peripherals to be discovered.
632 // Number of times to wait for discovery to complete.
633 static size_t const RETRIES = 5;
635 static uint64_t const TIMEOUT =
636 2 * MICROSECS_PER_SEC; // Microseconds
638 bool devicesDiscovered = false;
639 for (size_t i = 0; i < RETRIES; ++i)
641 OIC_LOG(DEBUG, TAG, "waiting for target device");
642 if (ca_cond_wait_for(g_deviceDescCond,
644 TIMEOUT) == CA_WAIT_SUCCESS)
646 ca_mutex_lock(g_deviceListMutex);
647 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
648 ca_mutex_unlock(g_deviceListMutex);
650 if (0 < scannedDeviceLen)
652 if (!address // multicast
653 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
655 devicesDiscovered = true;
662 OIC_LOG(INFO, TAG, "waiting..");
664 ca_mutex_lock(g_deviceScanRetryDelayMutex);
665 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
666 g_deviceScanRetryDelayMutex,
667 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
669 OIC_LOG(INFO, TAG, "finish to waiting for target device");
670 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
673 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
676 // checking whether a target device is found while waiting for time-out.
677 if (CALEClientIsDeviceInScanDeviceList(env, address))
679 devicesDiscovered = true;
688 // time out for scanning devices
689 if (!devicesDiscovered)
691 return CA_STATUS_FAILED;
699 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
700 const uint32_t dataLen)
702 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
704 VERIFY_NON_NULL(address, TAG, "address is null");
705 VERIFY_NON_NULL(data, TAG, "data is null");
709 OIC_LOG(ERROR, TAG, "g_jvm is null");
710 return CA_STATUS_FAILED;
713 bool isAttached = false;
715 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
718 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
719 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
722 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
723 return CA_STATUS_FAILED;
728 ca_mutex_lock(g_threadSendMutex);
730 CALEClientSetSendFinishFlag(false);
732 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
733 if (CA_STATUS_OK != ret)
735 OIC_LOG(INFO, TAG, "there is no scanned device");
739 if (g_context && g_deviceList)
741 uint32_t length = u_arraylist_length(g_deviceList);
742 for (uint32_t index = 0; index < length; index++)
744 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
747 OIC_LOG(ERROR, TAG, "jarrayObj is null");
751 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
754 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
758 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
761 OIC_LOG(ERROR, TAG, "setAddress is null");
765 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
767 if (!strcmp(setAddress, address))
769 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
771 // connect to gatt server
772 ret = CALEClientStopScan();
773 if (CA_STATUS_OK != ret)
775 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
781 (*env)->DeleteGlobalRef(env, g_sendBuffer);
784 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
785 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
786 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
788 // Target device to send message is just one.
791 ret = CALEClientSendData(env, jarrayObj);
792 if (CA_STATUS_OK != ret)
794 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
798 OIC_LOG(INFO, TAG, "wake up");
801 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
805 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
807 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
808 // if there is no connection state.
809 ca_mutex_lock(g_threadMutex);
810 if (!g_isFinishedSendData)
812 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
813 ca_cond_wait(g_threadCond, g_threadMutex);
814 OIC_LOG(DEBUG, TAG, "the data was sent");
816 ca_mutex_unlock(g_threadMutex);
820 (*g_jvm)->DetachCurrentThread(g_jvm);
823 // start LE Scan again
824 ret = CALEClientStartScan();
825 if (CA_STATUS_OK != ret)
827 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
828 ca_mutex_unlock(g_threadSendMutex);
832 ca_mutex_unlock(g_threadSendMutex);
833 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
834 return CALECheckSendState(address);
839 // start LE Scan again
840 ret = CALEClientStartScan();
841 if (CA_STATUS_OK != ret)
843 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
844 ca_mutex_unlock(g_threadSendMutex);
847 (*g_jvm)->DetachCurrentThread(g_jvm);
854 (*g_jvm)->DetachCurrentThread(g_jvm);
857 if (g_clientErrorCallback)
859 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
861 ca_mutex_unlock(g_threadSendMutex);
862 return CA_SEND_FAILED;
865 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
866 const uint32_t dataLen)
868 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
869 VERIFY_NON_NULL(data, TAG, "data is null");
870 VERIFY_NON_NULL(env, TAG, "env is null");
874 OIC_LOG(ERROR, TAG, "g_deviceList is null");
875 return CA_STATUS_FAILED;
878 ca_mutex_lock(g_threadSendMutex);
880 CALEClientSetSendFinishFlag(false);
882 OIC_LOG(DEBUG, TAG, "set byteArray for data");
885 (*env)->DeleteGlobalRef(env, g_sendBuffer);
889 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
890 if (CA_STATUS_OK != res)
892 OIC_LOG(INFO, TAG, "there is no scanned device");
896 // connect to gatt server
897 res = CALEClientStopScan();
898 if (CA_STATUS_OK != res)
900 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
901 ca_mutex_unlock(g_threadSendMutex);
904 uint32_t length = u_arraylist_length(g_deviceList);
905 g_targetCnt = length;
907 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
908 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
909 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
911 for (uint32_t index = 0; index < length; index++)
913 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
916 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
920 res = CALEClientSendData(env, jarrayObj);
921 if (res != CA_STATUS_OK)
923 OIC_LOG(ERROR, TAG, "BT device - send has failed");
926 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
929 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
933 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
936 OIC_LOG(ERROR, TAG, "address is not available");
940 (*env)->ReleaseStringUTFChars(env, jni_address, address);
943 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
945 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
946 ca_mutex_lock(g_threadMutex);
947 if (!g_isFinishedSendData)
949 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
950 ca_cond_wait(g_threadCond, g_threadMutex);
951 OIC_LOG(DEBUG, TAG, "the data was sent");
953 ca_mutex_unlock(g_threadMutex);
955 // start LE Scan again
956 res = CALEClientStartScan();
957 if (CA_STATUS_OK != res)
959 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
960 ca_mutex_unlock(g_threadSendMutex);
964 ca_mutex_unlock(g_threadSendMutex);
965 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
969 res = CALEClientStartScan();
970 if (CA_STATUS_OK != res)
972 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
973 ca_mutex_unlock(g_threadSendMutex);
977 ca_mutex_unlock(g_threadSendMutex);
978 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
979 return CA_SEND_FAILED;
982 CAResult_t CALECheckSendState(const char* address)
984 VERIFY_NON_NULL(address, TAG, "address is null");
986 ca_mutex_lock(g_deviceStateListMutex);
987 CALEState_t* state = CALEClientGetStateInfo(address);
990 OIC_LOG(ERROR, TAG, "state is null");
991 ca_mutex_unlock(g_deviceStateListMutex);
992 return CA_SEND_FAILED;
995 if (STATE_SEND_SUCCESS != state->sendState)
997 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
998 ca_mutex_unlock(g_deviceStateListMutex);
999 return CA_SEND_FAILED;
1002 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
1003 ca_mutex_unlock(g_deviceStateListMutex);
1004 return CA_STATUS_OK;
1007 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
1009 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1010 VERIFY_NON_NULL(device, TAG, "device is null");
1011 VERIFY_NON_NULL(env, TAG, "env is null");
1013 // get BLE address from bluetooth device object.
1014 char* address = NULL;
1015 CALEState_t* state = NULL;
1016 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
1019 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
1020 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1023 OIC_LOG(ERROR, TAG, "address is not available");
1024 return CA_STATUS_FAILED;
1026 ca_mutex_lock(g_deviceStateListMutex);
1027 state = CALEClientGetStateInfo(address);
1028 ca_mutex_unlock(g_deviceStateListMutex);
1029 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1034 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1036 // cancel previous connection request before connection
1037 // if there is gatt object in g_gattObjectList.
1040 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1043 OIC_LOG(ERROR, TAG, "address is not available");
1044 return CA_STATUS_FAILED;
1047 jobject gatt = CALEClientGetGattObjInList(env, address);
1050 CAResult_t res = CALEClientDisconnect(env, gatt);
1051 if (CA_STATUS_OK != res)
1053 OIC_LOG(INFO, TAG, "there is no gatt object");
1056 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1059 // connection request
1060 jobject newGatt = CALEClientConnect(env, device,
1062 if (NULL == newGatt)
1064 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1065 return CA_STATUS_FAILED;
1070 if (STATE_CONNECTED == state->connectedState)
1072 OIC_LOG(INFO, TAG, "GATT has already connected");
1075 OIC_LOG(ERROR, TAG, "jni_address is not available");
1076 return CA_STATUS_FAILED;
1079 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1082 OIC_LOG(ERROR, TAG, "address is not available");
1083 return CA_STATUS_FAILED;
1086 jobject gatt = CALEClientGetGattObjInList(env, address);
1089 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1090 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1091 return CA_STATUS_FAILED;
1094 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1095 if (CA_STATUS_OK != ret)
1097 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1098 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1101 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1105 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1107 // cancel previous connection request before connection
1108 // if there is gatt object in g_gattObjectList.
1111 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1114 OIC_LOG(ERROR, TAG, "address is not available");
1115 return CA_STATUS_FAILED;
1118 jobject gatt = CALEClientGetGattObjInList(env, address);
1121 CAResult_t res = CALEClientDisconnect(env, gatt);
1122 if (CA_STATUS_OK != res)
1124 OIC_LOG(INFO, TAG, "there is no gatt object");
1127 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1130 OIC_LOG(DEBUG, TAG, "start to connect LE");
1131 jobject gatt = CALEClientConnect(env, device,
1132 CALEClientGetAutoConnectFlag(env, jni_address));
1135 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1136 return CA_STATUS_FAILED;
1141 return CA_STATUS_OK;
1144 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1146 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1147 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1149 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1150 "()Landroid/bluetooth/BluetoothDevice;");
1151 if (!jni_mid_getDevice)
1153 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1157 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1158 if (!jni_obj_device)
1160 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1164 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1167 OIC_LOG(ERROR, TAG, "jni_address is null");
1177 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1180 OIC_LOG(DEBUG, TAG, "Gatt Close");
1181 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1182 VERIFY_NON_NULL(env, TAG, "env is null");
1184 // get BluetoothGatt method
1185 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1186 jmethodID jni_mid_closeGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1187 if (!jni_mid_closeGatt)
1189 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1190 return CA_STATUS_OK;
1193 // call disconnect gatt method
1194 OIC_LOG(DEBUG, TAG, "request to close GATT");
1195 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1197 if ((*env)->ExceptionCheck(env))
1199 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1200 (*env)->ExceptionDescribe(env);
1201 (*env)->ExceptionClear(env);
1202 return CA_STATUS_FAILED;
1205 return CA_STATUS_OK;
1208 CAResult_t CALEClientStartScan()
1210 if (!g_isStartedMulticastServer)
1212 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1213 return CA_STATUS_FAILED;
1216 if (!g_isStartedLEClient)
1218 OIC_LOG(ERROR, TAG, "LE client is not started");
1219 return CA_STATUS_FAILED;
1224 OIC_LOG(ERROR, TAG, "g_jvm is null");
1225 return CA_STATUS_FAILED;
1228 if (g_isStartedScan)
1230 OIC_LOG(INFO, TAG, "scanning is already started");
1231 return CA_STATUS_OK;
1234 bool isAttached = false;
1236 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1239 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1241 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1244 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1245 return CA_STATUS_FAILED;
1250 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1252 CAResult_t ret = CA_STATUS_OK;
1253 // scan gatt server with UUID
1254 if (g_leScanCallback && g_uuidList)
1257 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1259 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1261 if (CA_STATUS_OK != ret)
1263 if (CA_ADAPTER_NOT_ENABLED == ret)
1265 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1269 OIC_LOG(ERROR, TAG, "start scan has failed");
1276 (*g_jvm)->DetachCurrentThread(g_jvm);
1282 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1284 VERIFY_NON_NULL(callback, TAG, "callback is null");
1285 VERIFY_NON_NULL(env, TAG, "env is null");
1287 if (!CALEIsEnableBTAdapter(env))
1289 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1290 return CA_ADAPTER_NOT_ENABLED;
1293 // get default bt adapter class
1294 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1295 if (!jni_cid_BTAdapter)
1297 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1298 return CA_STATUS_FAILED;
1301 // get remote bt adapter method
1302 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1303 "getDefaultAdapter",
1304 METHODID_OBJECTNONPARAM);
1305 if (!jni_mid_getDefaultAdapter)
1307 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1308 return CA_STATUS_FAILED;
1311 // get start le scan method
1312 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1313 "(Landroid/bluetooth/BluetoothAdapter$"
1314 "LeScanCallback;)Z");
1315 if (!jni_mid_startLeScan)
1317 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1318 return CA_STATUS_FAILED;
1321 // gat bt adapter object
1322 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1323 jni_mid_getDefaultAdapter);
1324 if (!jni_obj_BTAdapter)
1326 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1327 return CA_STATUS_FAILED;
1330 // call start le scan method
1331 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1332 jni_mid_startLeScan, callback);
1333 if (!jni_obj_startLeScan)
1335 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1336 return CA_STATUS_FAILED;
1340 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1341 CALEClientSetScanFlag(true);
1344 return CA_STATUS_OK;
1347 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1349 VERIFY_NON_NULL(callback, TAG, "callback is null");
1350 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1351 VERIFY_NON_NULL(env, TAG, "env is null");
1353 if (!CALEIsEnableBTAdapter(env))
1355 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1356 return CA_ADAPTER_NOT_ENABLED;
1359 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1360 if (!jni_cid_BTAdapter)
1362 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1363 return CA_STATUS_FAILED;
1366 // get remote bt adapter method
1367 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1368 "getDefaultAdapter",
1369 METHODID_OBJECTNONPARAM);
1370 if (!jni_mid_getDefaultAdapter)
1372 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1373 return CA_STATUS_FAILED;
1376 // get start le scan method
1377 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1378 "([Ljava/util/UUID;Landroid/bluetooth/"
1379 "BluetoothAdapter$LeScanCallback;)Z");
1380 if (!jni_mid_startLeScan)
1382 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1383 return CA_STATUS_FAILED;
1386 // get bt adapter object
1387 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1388 jni_mid_getDefaultAdapter);
1389 if (!jni_obj_BTAdapter)
1391 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1392 return CA_STATUS_FAILED;
1395 // call start le scan method
1396 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1397 jni_mid_startLeScan, uuids, callback);
1398 if (!jni_obj_startLeScan)
1400 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1401 return CA_STATUS_FAILED;
1405 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1406 CALEClientSetScanFlag(true);
1409 return CA_STATUS_OK;
1412 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1414 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1415 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1418 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1421 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1425 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1426 "(Ljava/lang/String;)"
1427 "Ljava/util/UUID;");
1428 if (!jni_mid_fromString)
1430 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1434 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1435 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1439 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1443 return jni_obj_uuid;
1446 CAResult_t CALEClientStopScan()
1450 OIC_LOG(ERROR, TAG, "g_jvm is null");
1451 return CA_STATUS_FAILED;
1454 if (!g_isStartedScan)
1456 OIC_LOG(INFO, TAG, "scanning is already stopped");
1457 return CA_STATUS_OK;
1460 bool isAttached = false;
1462 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1465 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1466 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1469 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1470 return CA_STATUS_FAILED;
1475 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1476 if (CA_STATUS_OK != ret)
1478 if (CA_ADAPTER_NOT_ENABLED == ret)
1480 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1484 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1489 CALEClientSetScanFlag(false);
1494 (*g_jvm)->DetachCurrentThread(g_jvm);
1500 void CALEClientSetScanFlag(bool flag)
1502 ca_mutex_lock(g_scanMutex);
1503 g_isStartedScan = flag;
1504 ca_mutex_unlock(g_scanMutex);
1507 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1509 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1510 VERIFY_NON_NULL(callback, TAG, "callback is null");
1511 VERIFY_NON_NULL(env, TAG, "env is null");
1513 if (!CALEIsEnableBTAdapter(env))
1515 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1516 return CA_ADAPTER_NOT_ENABLED;
1519 // get default bt adapter class
1520 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1521 if (!jni_cid_BTAdapter)
1523 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1524 return CA_STATUS_FAILED;
1527 // get remote bt adapter method
1528 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1529 "getDefaultAdapter",
1530 METHODID_OBJECTNONPARAM);
1531 if (!jni_mid_getDefaultAdapter)
1533 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1534 return CA_STATUS_FAILED;
1537 // get start le scan method
1538 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1539 "(Landroid/bluetooth/"
1540 "BluetoothAdapter$LeScanCallback;)V");
1541 if (!jni_mid_stopLeScan)
1543 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1544 return CA_STATUS_FAILED;
1547 // gat bt adapter object
1548 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1549 jni_mid_getDefaultAdapter);
1550 if (!jni_obj_BTAdapter)
1552 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1553 return CA_STATUS_FAILED;
1556 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1557 // call start le scan method
1558 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1559 if ((*env)->ExceptionCheck(env))
1561 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1562 (*env)->ExceptionDescribe(env);
1563 (*env)->ExceptionClear(env);
1564 return CA_STATUS_FAILED;
1567 return CA_STATUS_OK;
1570 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1572 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1573 VERIFY_NON_NULL(env, TAG, "env");
1574 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1576 ca_mutex_lock(g_deviceStateListMutex);
1578 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1581 OIC_LOG(ERROR, TAG, "address is not available");
1582 return CA_STATUS_FAILED;
1585 if (CALEClientIsDeviceInList(address))
1587 CALEState_t* curState = CALEClientGetStateInfo(address);
1590 OIC_LOG(ERROR, TAG, "curState is null");
1591 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1592 ca_mutex_unlock(g_deviceStateListMutex);
1593 return CA_STATUS_FAILED;
1595 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1597 curState->autoConnectFlag = flag;
1600 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1601 ca_mutex_unlock(g_deviceStateListMutex);
1602 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1603 return CA_STATUS_OK;
1606 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1608 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1609 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1610 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1612 ca_mutex_lock(g_deviceStateListMutex);
1614 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1617 OIC_LOG(ERROR, TAG, "address is not available");
1621 CALEState_t* curState = CALEClientGetStateInfo(address);
1624 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1625 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1626 ca_mutex_unlock(g_deviceStateListMutex);
1629 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1631 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1632 ca_mutex_unlock(g_deviceStateListMutex);
1634 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1635 return curState->autoConnectFlag;
1638 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1640 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1641 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1642 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1644 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1645 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1648 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1651 OIC_LOG(ERROR, TAG, "address is not available");
1655 // close the gatt service
1656 jobject gatt = CALEClientGetGattObjInList(env, address);
1659 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1660 if (CA_STATUS_OK != res)
1662 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1663 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1667 // clean previous gatt object after close profile service
1668 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1669 if (CA_STATUS_OK != res)
1671 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1672 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1676 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1679 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1682 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1686 // add new gatt object into g_gattObjectList
1687 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1688 if (CA_STATUS_OK != res)
1690 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1697 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1699 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1700 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1701 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1703 if (!CALEIsEnableBTAdapter(env))
1705 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1709 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1712 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1716 // get BluetoothDevice method
1717 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1718 jmethodID jni_mid_connectGatt = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1720 "(Landroid/content/Context;ZLandroid/"
1721 "bluetooth/BluetoothGattCallback;)"
1722 "Landroid/bluetooth/BluetoothGatt;");
1723 if (!jni_mid_connectGatt)
1725 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1729 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1730 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1731 jni_mid_connectGatt,
1733 autoconnect, g_leGattCallback);
1734 if (!jni_obj_connectGatt)
1736 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1737 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1738 CALEClientUpdateSendCnt(env);
1743 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1745 return jni_obj_connectGatt;
1748 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1750 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1752 VERIFY_NON_NULL(env, TAG, "env is null");
1753 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1755 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1756 if (!jni_cid_BTAdapter)
1758 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1759 return CA_STATUS_FAILED;
1762 // get remote bt adapter method
1763 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1764 "getDefaultAdapter",
1765 METHODID_OBJECTNONPARAM);
1766 if (!jni_mid_getDefaultAdapter)
1768 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1769 return CA_STATUS_FAILED;
1772 // gat bt adapter object
1773 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1774 jni_mid_getDefaultAdapter);
1775 if (!jni_obj_BTAdapter)
1777 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1778 return CA_STATUS_FAILED;
1781 // get closeProfileProxy method
1782 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1783 "closeProfileProxy",
1784 "(ILandroid/bluetooth/"
1785 "BluetoothProfile;)V");
1786 if (!jni_mid_closeProfileProxy)
1788 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1789 return CA_STATUS_FAILED;
1792 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1793 if (!jni_cid_BTProfile)
1795 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1796 return CA_STATUS_FAILED;
1799 // GATT - Constant value : 7 (0x00000007)
1800 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1804 OIC_LOG(ERROR, TAG, "id_gatt is null");
1805 return CA_STATUS_FAILED;
1808 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1810 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1811 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1812 if ((*env)->ExceptionCheck(env))
1814 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1815 (*env)->ExceptionDescribe(env);
1816 (*env)->ExceptionClear(env);
1817 return CA_STATUS_FAILED;
1820 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1821 return CA_STATUS_OK;
1825 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1827 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1828 VERIFY_NON_NULL(env, TAG, "env is null");
1829 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1831 // get BluetoothGatt method
1832 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1833 jmethodID jni_mid_disconnectGatt = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
1834 "disconnect", "()V");
1835 if (!jni_mid_disconnectGatt)
1837 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1838 return CA_STATUS_FAILED;
1841 // call disconnect gatt method
1842 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1843 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1844 if ((*env)->ExceptionCheck(env))
1846 OIC_LOG(ERROR, TAG, "disconnect has failed");
1847 (*env)->ExceptionDescribe(env);
1848 (*env)->ExceptionClear(env);
1849 return CA_STATUS_FAILED;
1852 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1854 return CA_STATUS_OK;
1857 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1859 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1860 VERIFY_NON_NULL(env, TAG, "env is null");
1862 if (!g_gattObjectList)
1864 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1865 return CA_STATUS_OK;
1868 uint32_t length = u_arraylist_length(g_gattObjectList);
1869 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1870 for (uint32_t index = 0; index < length; index++)
1872 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1873 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1876 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1879 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1880 if (CA_STATUS_OK != res)
1882 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1887 return CA_STATUS_OK;
1890 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1892 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1893 VERIFY_NON_NULL(env, TAG, "env is null");
1895 if (!g_gattObjectList)
1897 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1898 return CA_STATUS_OK;
1901 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1904 OIC_LOG(ERROR, TAG, "address is null");
1905 return CA_STATUS_FAILED;
1908 uint32_t length = u_arraylist_length(g_gattObjectList);
1909 for (uint32_t index = 0; index < length; index++)
1911 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1914 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1918 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1919 if (!jni_setAddress)
1921 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1922 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1923 return CA_STATUS_FAILED;
1926 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1929 OIC_LOG(ERROR, TAG, "setAddress is null");
1930 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1931 return CA_STATUS_FAILED;
1934 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1935 if (!strcmp(address, setAddress))
1937 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1938 if (CA_STATUS_OK != res)
1940 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1941 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1942 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1943 return CA_STATUS_FAILED;
1945 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1946 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1947 return CA_STATUS_OK;
1949 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1951 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1953 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1954 return CA_STATUS_OK;
1957 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1959 VERIFY_NON_NULL(env, TAG, "env is null");
1960 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1962 if (!CALEIsEnableBTAdapter(env))
1964 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1965 return CA_ADAPTER_NOT_ENABLED;
1968 // get BluetoothGatt.discoverServices method
1969 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1970 jmethodID jni_mid_discoverServices = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
1971 "discoverServices", "()Z");
1972 if (!jni_mid_discoverServices)
1974 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1975 return CA_STATUS_FAILED;
1978 // call disconnect gatt method
1979 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1980 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1983 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1984 return CA_STATUS_FAILED;
1987 return CA_STATUS_OK;
1990 static void CALEWriteCharacteristicThread(void* object)
1992 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1994 bool isAttached = false;
1996 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1999 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2000 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2004 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2010 jobject gatt = (jobject)object;
2011 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
2012 if (CA_STATUS_OK != ret)
2014 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
2019 (*g_jvm)->DetachCurrentThread(g_jvm);
2023 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
2025 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2026 VERIFY_NON_NULL(env, TAG, "env is null");
2029 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2030 if (!jni_obj_character)
2032 CALEClientSendFinish(env, gatt);
2033 return CA_STATUS_FAILED;
2036 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2037 if (CA_STATUS_OK != ret)
2039 CALEClientSendFinish(env, gatt);
2040 return CA_STATUS_FAILED;
2043 // wait for callback for write Characteristic with success to sent data
2044 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2045 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2046 if (!g_isSignalSetFlag)
2048 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2049 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2050 g_threadWriteCharacteristicMutex,
2051 WAIT_TIME_WRITE_CHARACTERISTIC))
2053 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2054 g_isSignalSetFlag = false;
2055 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2056 return CA_STATUS_FAILED;
2059 // reset flag set by writeCharacteristic Callback
2060 g_isSignalSetFlag = false;
2061 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2063 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2064 return CA_STATUS_OK;
2067 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2069 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2070 VERIFY_NON_NULL(env, TAG, "env is null");
2071 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2073 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2074 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2075 CALEWriteCharacteristicThread, (void*)gattParam))
2077 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2078 return CA_STATUS_FAILED;
2081 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2082 return CA_STATUS_OK;
2085 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2086 jobject gattCharacteristic)
2088 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2089 VERIFY_NON_NULL(env, TAG, "env is null");
2090 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2091 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2093 if (!CALEIsEnableBTAdapter(env))
2095 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2096 return CA_STATUS_FAILED;
2099 // get BluetoothGatt.write characteristic method
2100 OIC_LOG(DEBUG, TAG, "write characteristic method");
2101 jmethodID jni_mid_writeCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2102 "writeCharacteristic",
2103 "(Landroid/bluetooth/"
2104 "BluetoothGattCharacteristic;)Z");
2105 if (!jni_mid_writeCharacteristic)
2107 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2108 return CA_STATUS_FAILED;
2111 // call disconnect gatt method
2112 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2113 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2114 jni_mid_writeCharacteristic,
2115 gattCharacteristic);
2118 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2122 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2123 return CA_STATUS_FAILED;
2126 return CA_STATUS_OK;
2129 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2131 VERIFY_NON_NULL(env, TAG, "env is null");
2132 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2134 if (!CALEIsEnableBTAdapter(env))
2136 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2137 return CA_STATUS_FAILED;
2140 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2143 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2144 return CA_STATUS_FAILED;
2147 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2148 if (!jni_obj_GattCharacteristic)
2150 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2151 return CA_STATUS_FAILED;
2154 OIC_LOG(DEBUG, TAG, "read characteristic method");
2155 jmethodID jni_mid_readCharacteristic = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2156 "readCharacteristic",
2157 "(Landroid/bluetooth/"
2158 "BluetoothGattCharacteristic;)Z");
2159 if (!jni_mid_readCharacteristic)
2161 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2162 return CA_STATUS_FAILED;
2165 // call disconnect gatt method
2166 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2167 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2168 jni_obj_GattCharacteristic);
2171 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2175 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2176 return CA_STATUS_FAILED;
2179 return CA_STATUS_OK;
2182 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2183 jobject characteristic)
2185 VERIFY_NON_NULL(env, TAG, "env is null");
2186 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2187 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2189 if (!CALEIsEnableBTAdapter(env))
2191 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2192 return CA_ADAPTER_NOT_ENABLED;
2195 // get BluetoothGatt.setCharacteristicNotification method
2196 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2197 jmethodID jni_mid_setNotification = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2198 "setCharacteristicNotification",
2199 "(Landroid/bluetooth/"
2200 "BluetoothGattCharacteristic;Z)Z");
2201 if (!jni_mid_setNotification)
2203 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2204 return CA_STATUS_FAILED;
2207 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2208 characteristic, JNI_TRUE);
2209 if (JNI_TRUE == ret)
2211 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2215 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2216 return CA_STATUS_FAILED;
2219 return CA_STATUS_OK;
2222 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2224 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2225 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2226 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2228 if (!CALEIsEnableBTAdapter(env))
2230 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2234 // get BluetoothGatt.getService method
2235 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2236 jmethodID jni_mid_getService = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
2238 "(Ljava/util/UUID;)Landroid/bluetooth/"
2239 "BluetoothGattService;");
2240 if (!jni_mid_getService)
2242 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2246 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2247 if (!jni_obj_service_uuid)
2249 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2253 // get bluetooth gatt service
2254 OIC_LOG(DEBUG, TAG, "request to get service");
2255 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2256 jni_obj_service_uuid);
2257 if (!jni_obj_gattService)
2259 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2263 // get bluetooth gatt service method
2264 jmethodID jni_mid_getCharacteristic = CALEGetJNIMethodID(env, "android/bluetooth/"
2265 "BluetoothGattService",
2266 "getCharacteristic",
2267 "(Ljava/util/UUID;)"
2268 "Landroid/bluetooth/"
2269 "BluetoothGattCharacteristic;");
2270 if (!jni_mid_getCharacteristic)
2272 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2276 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2279 OIC_LOG(ERROR, TAG, "uuid is null");
2283 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2284 if (!jni_obj_tx_uuid)
2286 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2287 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2291 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2292 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2293 jni_mid_getCharacteristic,
2296 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2297 return jni_obj_GattCharacteristic;
2300 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2302 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2303 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2304 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2305 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2307 if (!CALEIsEnableBTAdapter(env))
2309 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2313 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2316 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2320 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2321 if (!jni_obj_GattCharacteristic)
2323 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2327 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2328 "/BluetoothGattCharacteristic");
2329 if (!jni_cid_BTGattCharacteristic)
2331 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2335 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2336 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2338 if (!jni_mid_setValue)
2340 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2344 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2346 if (JNI_TRUE == ret)
2348 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2352 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2357 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2358 "setWriteType", "(I)V");
2359 if (!jni_mid_setWriteType)
2361 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2365 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2366 "WRITE_TYPE_NO_RESPONSE", "I");
2367 if (!jni_fid_no_response)
2369 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2373 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2374 jni_fid_no_response);
2376 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2378 return jni_obj_GattCharacteristic;
2381 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2383 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2384 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2386 if (!CALEIsEnableBTAdapter(env))
2388 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2392 jmethodID jni_mid_getValue = CALEGetJNIMethodID(env, "android/bluetooth/"
2393 "BluetoothGattCharacteristic",
2394 "getValue", "()[B");
2395 if (!jni_mid_getValue)
2397 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2401 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2403 return jni_obj_data_array;
2406 CAResult_t CALEClientCreateUUIDList()
2410 OIC_LOG(ERROR, TAG, "g_jvm is null");
2411 return CA_STATUS_FAILED;
2414 bool isAttached = false;
2416 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2419 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2420 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2424 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2425 return CA_STATUS_FAILED;
2430 // create new object array
2431 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2432 if (!jni_cid_uuid_list)
2434 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2438 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2439 jni_cid_uuid_list, NULL);
2440 if (!jni_obj_uuid_list)
2442 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2447 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2450 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2453 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2455 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2459 (*g_jvm)->DetachCurrentThread(g_jvm);
2462 return CA_STATUS_OK;
2469 (*g_jvm)->DetachCurrentThread(g_jvm);
2471 return CA_STATUS_FAILED;
2474 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2475 jobject characteristic)
2477 VERIFY_NON_NULL(env, TAG, "env is null");
2478 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2479 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2481 if (!CALEIsEnableBTAdapter(env))
2483 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2484 return CA_ADAPTER_NOT_ENABLED;
2487 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2488 jmethodID jni_mid_getDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/"
2489 "BluetoothGattCharacteristic",
2491 "(Ljava/util/UUID;)Landroid/bluetooth/"
2492 "BluetoothGattDescriptor;");
2493 if (!jni_mid_getDescriptor)
2495 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2496 return CA_STATUS_FAILED;
2499 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2500 if (!jni_obj_cc_uuid)
2502 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2503 return CA_STATUS_FAILED;
2506 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2507 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2508 jni_mid_getDescriptor, jni_obj_cc_uuid);
2509 if (!jni_obj_descriptor)
2511 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2512 return CA_NOT_SUPPORTED;
2515 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2516 jclass jni_cid_descriptor = (*env)->FindClass(env,
2517 "android/bluetooth/BluetoothGattDescriptor");
2518 if (!jni_cid_descriptor)
2520 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2521 return CA_STATUS_FAILED;
2524 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2525 if (!jni_mid_setValue)
2527 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2528 return CA_STATUS_FAILED;
2531 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2532 "ENABLE_NOTIFICATION_VALUE", "[B");
2533 if (!jni_fid_NotiValue)
2535 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2536 return CA_STATUS_FAILED;
2539 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2541 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2542 env, jni_obj_descriptor, jni_mid_setValue,
2543 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2546 OIC_LOG(DEBUG, TAG, "setValue success");
2550 OIC_LOG(ERROR, TAG, "setValue has failed");
2551 return CA_STATUS_FAILED;
2554 jmethodID jni_mid_writeDescriptor = CALEGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2556 "(Landroid/bluetooth/"
2557 "BluetoothGattDescriptor;)Z");
2558 if (!jni_mid_writeDescriptor)
2560 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2561 return CA_STATUS_FAILED;
2564 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2565 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2566 jni_obj_descriptor);
2569 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2573 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2574 return CA_STATUS_FAILED;
2577 return CA_STATUS_OK;
2580 void CALEClientCreateScanDeviceList(JNIEnv *env)
2582 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2583 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2585 ca_mutex_lock(g_deviceListMutex);
2586 // create new object array
2587 if (g_deviceList == NULL)
2589 OIC_LOG(DEBUG, TAG, "Create device list");
2591 g_deviceList = u_arraylist_create();
2593 ca_mutex_unlock(g_deviceListMutex);
2596 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2598 VERIFY_NON_NULL(device, TAG, "device is null");
2599 VERIFY_NON_NULL(env, TAG, "env is null");
2601 ca_mutex_lock(g_deviceListMutex);
2605 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2606 ca_mutex_unlock(g_deviceListMutex);
2607 return CA_STATUS_FAILED;
2610 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2611 if (!jni_remoteAddress)
2613 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2614 ca_mutex_unlock(g_deviceListMutex);
2615 return CA_STATUS_FAILED;
2618 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2621 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2622 ca_mutex_unlock(g_deviceListMutex);
2623 return CA_STATUS_FAILED;
2626 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2628 jobject gdevice = (*env)->NewGlobalRef(env, device);
2629 u_arraylist_add(g_deviceList, gdevice);
2630 ca_cond_signal(g_deviceDescCond);
2631 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2633 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2635 ca_mutex_unlock(g_deviceListMutex);
2637 return CA_STATUS_OK;
2640 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2642 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2643 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2647 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2651 uint32_t length = u_arraylist_length(g_deviceList);
2652 for (uint32_t index = 0; index < length; index++)
2654 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2657 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2661 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2662 if (!jni_setAddress)
2664 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2668 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2671 OIC_LOG(ERROR, TAG, "setAddress is null");
2675 if (!strcmp(remoteAddress, setAddress))
2677 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2681 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2684 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2689 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2691 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2692 VERIFY_NON_NULL(env, TAG, "env is null");
2694 ca_mutex_lock(g_deviceListMutex);
2698 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2699 ca_mutex_unlock(g_deviceListMutex);
2700 return CA_STATUS_FAILED;
2703 uint32_t length = u_arraylist_length(g_deviceList);
2704 for (uint32_t index = 0; index < length; index++)
2706 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2709 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2712 (*env)->DeleteGlobalRef(env, jarrayObj);
2716 OICFree(g_deviceList);
2717 g_deviceList = NULL;
2719 ca_mutex_unlock(g_deviceListMutex);
2720 return CA_STATUS_OK;
2723 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2725 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2726 VERIFY_NON_NULL(address, TAG, "address is null");
2727 VERIFY_NON_NULL(env, TAG, "env is null");
2729 ca_mutex_lock(g_deviceListMutex);
2733 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2734 ca_mutex_unlock(g_deviceListMutex);
2735 return CA_STATUS_FAILED;
2738 uint32_t length = u_arraylist_length(g_deviceList);
2739 for (uint32_t index = 0; index < length; index++)
2741 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2744 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2745 ca_mutex_unlock(g_deviceListMutex);
2746 return CA_STATUS_FAILED;
2749 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2750 if (!jni_setAddress)
2752 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2753 ca_mutex_unlock(g_deviceListMutex);
2754 return CA_STATUS_FAILED;
2757 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2760 OIC_LOG(ERROR, TAG, "setAddress is null");
2761 ca_mutex_unlock(g_deviceListMutex);
2762 return CA_STATUS_FAILED;
2765 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2768 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2769 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2770 ca_mutex_unlock(g_deviceListMutex);
2771 return CA_STATUS_FAILED;
2774 if (!strcmp(setAddress, remoteAddress))
2776 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2777 (*env)->DeleteGlobalRef(env, jarrayObj);
2779 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2780 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2782 if (NULL == u_arraylist_remove(g_deviceList, index))
2784 OIC_LOG(ERROR, TAG, "List removal failed.");
2785 ca_mutex_unlock(g_deviceListMutex);
2786 return CA_STATUS_FAILED;
2788 ca_mutex_unlock(g_deviceListMutex);
2789 return CA_STATUS_OK;
2791 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2792 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2795 ca_mutex_unlock(g_deviceListMutex);
2796 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2798 return CA_STATUS_OK;
2805 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2807 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2808 VERIFY_NON_NULL(env, TAG, "env is null");
2809 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2811 ca_mutex_lock(g_gattObjectMutex);
2813 if (!g_gattObjectList)
2815 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2816 ca_mutex_unlock(g_gattObjectMutex);
2817 return CA_STATUS_FAILED;
2820 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2821 if (!jni_remoteAddress)
2823 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2824 ca_mutex_unlock(g_gattObjectMutex);
2825 return CA_STATUS_FAILED;
2828 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2831 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2832 ca_mutex_unlock(g_gattObjectMutex);
2833 return CA_STATUS_FAILED;
2836 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2837 if (!CALEClientIsGattObjInList(env, remoteAddress))
2839 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2840 u_arraylist_add(g_gattObjectList, newGatt);
2841 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2844 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2845 ca_mutex_unlock(g_gattObjectMutex);
2846 return CA_STATUS_OK;
2849 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2851 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2852 VERIFY_NON_NULL(env, TAG, "env is null");
2853 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2855 uint32_t length = u_arraylist_length(g_gattObjectList);
2856 for (uint32_t index = 0; index < length; index++)
2859 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2862 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2866 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2867 if (!jni_setAddress)
2869 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2873 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2876 OIC_LOG(ERROR, TAG, "setAddress is null");
2880 if (!strcmp(remoteAddress, setAddress))
2882 OIC_LOG(DEBUG, TAG, "the device is already set");
2883 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2888 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2893 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2897 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2899 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2900 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2901 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2903 ca_mutex_lock(g_gattObjectMutex);
2904 uint32_t length = u_arraylist_length(g_gattObjectList);
2905 for (uint32_t index = 0; index < length; index++)
2907 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2910 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2911 ca_mutex_unlock(g_gattObjectMutex);
2915 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2916 if (!jni_setAddress)
2918 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2919 ca_mutex_unlock(g_gattObjectMutex);
2923 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2926 OIC_LOG(ERROR, TAG, "setAddress is null");
2927 ca_mutex_unlock(g_gattObjectMutex);
2931 if (!strcmp(remoteAddress, setAddress))
2933 OIC_LOG(DEBUG, TAG, "the device is already set");
2934 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2935 ca_mutex_unlock(g_gattObjectMutex);
2938 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2941 ca_mutex_unlock(g_gattObjectMutex);
2942 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2946 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2948 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2949 VERIFY_NON_NULL(env, TAG, "env is null");
2951 ca_mutex_lock(g_gattObjectMutex);
2952 if (!g_gattObjectList)
2954 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2955 ca_mutex_unlock(g_gattObjectMutex);
2956 return CA_STATUS_OK;
2959 uint32_t length = u_arraylist_length(g_gattObjectList);
2960 for (uint32_t index = 0; index < length; index++)
2962 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2965 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2968 (*env)->DeleteGlobalRef(env, jarrayObj);
2972 OICFree(g_gattObjectList);
2973 g_gattObjectList = NULL;
2974 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2975 ca_mutex_unlock(g_gattObjectMutex);
2976 return CA_STATUS_OK;
2979 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2981 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2982 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2983 VERIFY_NON_NULL(env, TAG, "env is null");
2985 ca_mutex_lock(g_gattObjectMutex);
2986 if (!g_gattObjectList)
2988 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2989 ca_mutex_unlock(g_gattObjectMutex);
2990 return CA_STATUS_OK;
2993 uint32_t length = u_arraylist_length(g_gattObjectList);
2994 for (uint32_t index = 0; index < length; index++)
2996 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2999 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3000 ca_mutex_unlock(g_gattObjectMutex);
3001 return CA_STATUS_FAILED;
3004 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3005 if (!jni_setAddress)
3007 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3008 ca_mutex_unlock(g_gattObjectMutex);
3009 return CA_STATUS_FAILED;
3012 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3015 OIC_LOG(ERROR, TAG, "setAddress is null");
3016 ca_mutex_unlock(g_gattObjectMutex);
3017 return CA_STATUS_FAILED;
3020 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
3021 if (!jni_remoteAddress)
3023 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3024 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3025 ca_mutex_unlock(g_gattObjectMutex);
3026 return CA_STATUS_FAILED;
3029 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3032 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3033 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3034 ca_mutex_unlock(g_gattObjectMutex);
3035 return CA_STATUS_FAILED;
3038 if (!strcmp(setAddress, remoteAddress))
3040 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3041 (*env)->DeleteGlobalRef(env, jarrayObj);
3043 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3044 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3046 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3048 OIC_LOG(ERROR, TAG, "List removal failed.");
3049 ca_mutex_unlock(g_gattObjectMutex);
3050 return CA_STATUS_FAILED;
3052 ca_mutex_unlock(g_gattObjectMutex);
3053 return CA_STATUS_OK;
3055 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3056 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3059 ca_mutex_unlock(g_gattObjectMutex);
3060 OIC_LOG(DEBUG, TAG, "there are no target object");
3061 return CA_STATUS_OK;
3064 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3066 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3067 VERIFY_NON_NULL(addr, TAG, "addr is null");
3068 VERIFY_NON_NULL(env, TAG, "env is null");
3070 ca_mutex_lock(g_gattObjectMutex);
3071 if (!g_gattObjectList)
3073 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3074 ca_mutex_unlock(g_gattObjectMutex);
3075 return CA_STATUS_OK;
3078 uint32_t length = u_arraylist_length(g_gattObjectList);
3079 for (uint32_t index = 0; index < length; index++)
3081 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3084 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3085 ca_mutex_unlock(g_gattObjectMutex);
3086 return CA_STATUS_FAILED;
3089 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3090 if (!jni_setAddress)
3092 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3093 ca_mutex_unlock(g_gattObjectMutex);
3094 return CA_STATUS_FAILED;
3097 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3100 OIC_LOG(ERROR, TAG, "setAddress is null");
3101 ca_mutex_unlock(g_gattObjectMutex);
3102 return CA_STATUS_FAILED;
3105 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3108 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3109 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3110 ca_mutex_unlock(g_gattObjectMutex);
3111 return CA_STATUS_FAILED;
3114 if (!strcmp(setAddress, remoteAddress))
3116 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3117 (*env)->DeleteGlobalRef(env, jarrayObj);
3119 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3120 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3121 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3123 OIC_LOG(ERROR, TAG, "List removal failed.");
3124 ca_mutex_unlock(g_gattObjectMutex);
3125 return CA_STATUS_FAILED;
3127 ca_mutex_unlock(g_gattObjectMutex);
3128 return CA_STATUS_OK;
3130 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3131 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3134 ca_mutex_unlock(g_gattObjectMutex);
3135 OIC_LOG(DEBUG, TAG, "there are no target object");
3136 return CA_STATUS_FAILED;
3139 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3141 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3143 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3144 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3146 // get Bluetooth Address
3147 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3148 if (!jni_btTargetAddress)
3150 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3154 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3157 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3161 // get method ID of getDevice()
3162 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
3163 "getDevice", METHODID_BT_DEVICE);
3164 if (!jni_mid_getDevice)
3166 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3167 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3171 size_t length = u_arraylist_length(g_gattObjectList);
3172 for (size_t index = 0; index < length; index++)
3174 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3177 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3178 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3182 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3183 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3184 if (!jni_obj_device)
3186 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3187 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3191 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3194 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3195 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3199 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3202 OIC_LOG(ERROR, TAG, "btAddress is not available");
3203 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3207 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3208 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3209 if (!strcmp(targetAddress, btAddress))
3211 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3214 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3217 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3219 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3220 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3221 (*env)->DeleteLocalRef(env, jni_btAddress);
3222 (*env)->DeleteLocalRef(env, jni_obj_device);
3223 return jni_LEAddress;
3225 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3226 (*env)->DeleteLocalRef(env, jni_btAddress);
3227 (*env)->DeleteLocalRef(env, jni_obj_device);
3230 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3238 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3239 uint16_t notificationState, uint16_t sendState)
3241 VERIFY_NON_NULL(address, TAG, "address is null");
3243 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3246 OIC_LOG(ERROR, TAG, "out of memory");
3247 return CA_MEMORY_ALLOC_FAILED;
3250 if (strlen(address) > CA_MACADDR_SIZE)
3252 OIC_LOG(ERROR, TAG, "address is not proper");
3254 return CA_STATUS_FAILED;
3257 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3258 newstate->connectedState = connectedState;
3259 newstate->notificationState = notificationState;
3260 newstate->sendState = sendState;
3261 return CALEClientAddDeviceStateToList(newstate);
3264 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3266 VERIFY_NON_NULL(state, TAG, "state is null");
3268 ca_mutex_lock(g_deviceStateListMutex);
3270 if (!g_deviceStateList)
3272 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3273 ca_mutex_unlock(g_deviceStateListMutex);
3274 return CA_STATUS_FAILED;
3277 if (CALEClientIsDeviceInList(state->address))
3279 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3282 OIC_LOG(ERROR, TAG, "curState is null");
3283 ca_mutex_unlock(g_deviceStateListMutex);
3284 return CA_STATUS_FAILED;
3287 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3289 state->notificationState = curState->notificationState;
3291 state->autoConnectFlag = curState->autoConnectFlag;
3293 // delete previous state for update new state
3294 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3295 if (CA_STATUS_OK != res)
3297 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3298 ca_mutex_unlock(g_deviceStateListMutex);
3302 u_arraylist_add(g_deviceStateList, state); // update new state
3303 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
3304 state->connectedState, state->notificationState,
3305 state->address, state->autoConnectFlag);
3307 ca_mutex_unlock(g_deviceStateListMutex);
3308 return CA_STATUS_OK;
3311 bool CALEClientIsDeviceInList(const char* remoteAddress)
3313 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3315 if (!g_deviceStateList)
3317 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3321 uint32_t length = u_arraylist_length(g_deviceStateList);
3322 for (uint32_t index = 0; index < length; index++)
3324 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3327 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3331 if (!strcmp(remoteAddress, state->address))
3333 OIC_LOG(DEBUG, TAG, "the device is already set");
3342 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3346 CAResult_t CALEClientRemoveAllDeviceState()
3348 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3350 ca_mutex_lock(g_deviceStateListMutex);
3351 if (!g_deviceStateList)
3353 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3354 ca_mutex_unlock(g_deviceStateListMutex);
3355 return CA_STATUS_FAILED;
3358 uint32_t length = u_arraylist_length(g_deviceStateList);
3359 for (uint32_t index = 0; index < length; index++)
3361 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3364 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3370 OICFree(g_deviceStateList);
3371 g_deviceStateList = NULL;
3372 ca_mutex_unlock(g_deviceStateListMutex);
3374 return CA_STATUS_OK;
3377 CAResult_t CALEClientResetDeviceStateForAll()
3379 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3381 ca_mutex_lock(g_deviceStateListMutex);
3382 if (!g_deviceStateList)
3384 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3385 ca_mutex_unlock(g_deviceStateListMutex);
3386 return CA_STATUS_FAILED;
3389 size_t length = u_arraylist_length(g_deviceStateList);
3390 for (size_t index = 0; index < length; index++)
3392 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3395 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3399 // autoConnectFlag value will be not changed,
3400 // since it has reset only termination case.
3401 state->connectedState = STATE_DISCONNECTED;
3402 state->notificationState = STATE_CHARACTER_UNSET;
3403 state->sendState = STATE_SEND_NONE;
3405 ca_mutex_unlock(g_deviceStateListMutex);
3407 return CA_STATUS_OK;
3410 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3412 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3413 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3415 if (!g_deviceStateList)
3417 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3418 return CA_STATUS_FAILED;
3421 uint32_t length = u_arraylist_length(g_deviceStateList);
3422 for (uint32_t index = 0; index < length; index++)
3424 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3427 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3431 if (!strcmp(state->address, remoteAddress))
3433 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3435 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3437 if (NULL == targetState)
3439 OIC_LOG(ERROR, TAG, "List removal failed.");
3440 return CA_STATUS_FAILED;
3443 OICFree(targetState);
3444 return CA_STATUS_OK;
3448 return CA_STATUS_OK;
3451 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3453 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3454 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3456 if (!g_deviceStateList)
3458 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3462 uint32_t length = u_arraylist_length(g_deviceStateList);
3463 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3465 for (uint32_t index = 0; index < length; index++)
3467 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3470 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3474 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3475 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3477 if (!strcmp(state->address, remoteAddress))
3479 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3486 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3488 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3489 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3491 ca_mutex_lock(g_deviceStateListMutex);
3492 if (!g_deviceStateList)
3494 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3495 ca_mutex_unlock(g_deviceStateListMutex);
3499 uint32_t length = u_arraylist_length(g_deviceStateList);
3500 for (uint32_t index = 0; index < length; index++)
3502 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3505 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3509 if (!strcmp(state->address, remoteAddress))
3511 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3513 if (STATE_CONNECTED == state->connectedState)
3515 ca_mutex_unlock(g_deviceStateListMutex);
3520 ca_mutex_unlock(g_deviceStateListMutex);
3525 ca_mutex_unlock(g_deviceStateListMutex);
3529 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3531 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3532 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3534 ca_mutex_lock(g_deviceStateListMutex);
3535 if (!g_deviceStateList)
3537 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3538 ca_mutex_unlock(g_deviceStateListMutex);
3542 uint32_t length = u_arraylist_length(g_deviceStateList);
3543 for (uint32_t index = 0; index < length; index++)
3545 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3548 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3552 if (!strcmp(state->address, remoteAddress))
3554 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3556 if (STATE_CHARACTER_SET == state->notificationState)
3558 ca_mutex_unlock(g_deviceStateListMutex);
3563 ca_mutex_unlock(g_deviceStateListMutex);
3569 ca_mutex_unlock(g_deviceStateListMutex);
3573 void CALEClientCreateDeviceList()
3575 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3577 // create new object array
3578 if (!g_gattObjectList)
3580 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3582 g_gattObjectList = u_arraylist_create();
3585 if (!g_deviceStateList)
3587 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3589 g_deviceStateList = u_arraylist_create();
3594 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3596 g_deviceList = u_arraylist_create();
3601 * Check Sent Count for remove g_sendBuffer
3603 void CALEClientUpdateSendCnt(JNIEnv *env)
3605 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3607 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3609 ca_mutex_lock(g_threadMutex);
3613 if (g_targetCnt <= g_currentSentCnt)
3616 g_currentSentCnt = 0;
3620 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3621 g_sendBuffer = NULL;
3623 // notity the thread
3624 ca_cond_signal(g_threadCond);
3626 CALEClientSetSendFinishFlag(true);
3627 OIC_LOG(DEBUG, TAG, "set signal for send data");
3630 ca_mutex_unlock(g_threadMutex);
3633 CAResult_t CALEClientInitGattMutexVaraibles()
3635 if (NULL == g_bleReqRespClientCbMutex)
3637 g_bleReqRespClientCbMutex = ca_mutex_new();
3638 if (NULL == g_bleReqRespClientCbMutex)
3640 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3641 return CA_STATUS_FAILED;
3645 if (NULL == g_bleServerBDAddressMutex)
3647 g_bleServerBDAddressMutex = ca_mutex_new();
3648 if (NULL == g_bleServerBDAddressMutex)
3650 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3651 return CA_STATUS_FAILED;
3655 if (NULL == g_threadMutex)
3657 g_threadMutex = ca_mutex_new();
3658 if (NULL == g_threadMutex)
3660 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3661 return CA_STATUS_FAILED;
3665 if (NULL == g_threadSendMutex)
3667 g_threadSendMutex = ca_mutex_new();
3668 if (NULL == g_threadSendMutex)
3670 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3671 return CA_STATUS_FAILED;
3675 if (NULL == g_deviceListMutex)
3677 g_deviceListMutex = ca_mutex_new();
3678 if (NULL == g_deviceListMutex)
3680 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3681 return CA_STATUS_FAILED;
3685 if (NULL == g_gattObjectMutex)
3687 g_gattObjectMutex = ca_mutex_new();
3688 if (NULL == g_gattObjectMutex)
3690 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3691 return CA_STATUS_FAILED;
3695 if (NULL == g_deviceStateListMutex)
3697 g_deviceStateListMutex = ca_mutex_new();
3698 if (NULL == g_deviceStateListMutex)
3700 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3701 return CA_STATUS_FAILED;
3705 if (NULL == g_SendFinishMutex)
3707 g_SendFinishMutex = ca_mutex_new();
3708 if (NULL == g_SendFinishMutex)
3710 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3711 return CA_STATUS_FAILED;
3715 if (NULL == g_scanMutex)
3717 g_scanMutex = ca_mutex_new();
3718 if (NULL == g_scanMutex)
3720 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3721 return CA_STATUS_FAILED;
3725 if (NULL == g_threadWriteCharacteristicMutex)
3727 g_threadWriteCharacteristicMutex = ca_mutex_new();
3728 if (NULL == g_threadWriteCharacteristicMutex)
3730 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3731 return CA_STATUS_FAILED;
3735 if (NULL == g_deviceScanRetryDelayMutex)
3737 g_deviceScanRetryDelayMutex = ca_mutex_new();
3738 if (NULL == g_deviceScanRetryDelayMutex)
3740 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3741 return CA_STATUS_FAILED;
3745 return CA_STATUS_OK;
3748 void CALEClientTerminateGattMutexVariables()
3750 ca_mutex_free(g_bleReqRespClientCbMutex);
3751 g_bleReqRespClientCbMutex = NULL;
3753 ca_mutex_free(g_bleServerBDAddressMutex);
3754 g_bleServerBDAddressMutex = NULL;
3756 ca_mutex_free(g_threadMutex);
3757 g_threadMutex = NULL;
3759 ca_mutex_free(g_threadSendMutex);
3760 g_threadSendMutex = NULL;
3762 ca_mutex_free(g_deviceListMutex);
3763 g_deviceListMutex = NULL;
3765 ca_mutex_free(g_SendFinishMutex);
3766 g_SendFinishMutex = NULL;
3768 ca_mutex_free(g_scanMutex);
3771 ca_mutex_free(g_threadWriteCharacteristicMutex);
3772 g_threadWriteCharacteristicMutex = NULL;
3774 ca_mutex_free(g_deviceScanRetryDelayMutex);
3775 g_deviceScanRetryDelayMutex = NULL;
3778 void CALEClientSetSendFinishFlag(bool flag)
3780 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3782 ca_mutex_lock(g_SendFinishMutex);
3783 g_isFinishedSendData = flag;
3784 ca_mutex_unlock(g_SendFinishMutex);
3791 CAResult_t CAStartLEGattClient()
3793 // init mutex for send logic
3794 if (!g_deviceDescCond)
3796 g_deviceDescCond = ca_cond_new();
3801 g_threadCond = ca_cond_new();
3804 if (!g_threadWriteCharacteristicCond)
3806 g_threadWriteCharacteristicCond = ca_cond_new();
3809 CAResult_t res = CALEClientStartMulticastServer();
3810 if (CA_STATUS_OK != res)
3812 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3816 g_isStartedLEClient = true;
3822 void CAStopLEGattClient()
3824 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3828 OIC_LOG(ERROR, TAG, "g_jvm is null");
3832 bool isAttached = false;
3834 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3837 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3838 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3842 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3848 CAResult_t ret = CALEClientDisconnectAll(env);
3849 if (CA_STATUS_OK != ret)
3851 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3854 ret = CALEClientStopScan();
3855 if(CA_STATUS_OK != ret)
3857 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3860 ca_mutex_lock(g_threadMutex);
3861 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3862 ca_cond_signal(g_threadCond);
3863 ca_mutex_unlock(g_threadMutex);
3865 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3866 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3867 ca_cond_signal(g_threadWriteCharacteristicCond);
3868 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3870 ca_mutex_lock(g_threadSendMutex);
3871 OIC_LOG(DEBUG, TAG, "signal - send cond");
3872 ca_cond_signal(g_deviceDescCond);
3873 ca_mutex_unlock(g_threadSendMutex);
3875 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3876 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3877 ca_cond_signal(g_deviceScanRetryDelayCond);
3878 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3881 ca_cond_free(g_deviceDescCond);
3882 ca_cond_free(g_threadCond);
3883 ca_cond_free(g_threadWriteCharacteristicCond);
3884 ca_cond_free(g_deviceScanRetryDelayCond);
3886 g_deviceDescCond = NULL;
3887 g_threadCond = NULL;
3888 g_threadWriteCharacteristicCond = NULL;
3889 g_deviceScanRetryDelayCond = NULL;
3893 (*g_jvm)->DetachCurrentThread(g_jvm);
3898 CAResult_t CAInitializeLEGattClient()
3900 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3901 CALEClientInitialize();
3902 return CA_STATUS_OK;
3905 void CATerminateLEGattClient()
3907 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3908 CAStopLEGattClient();
3909 CALEClientTerminate();
3912 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3913 uint32_t dataLen, CALETransferType_t type,
3916 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3917 VERIFY_NON_NULL(data, TAG, "data is null");
3918 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3920 if (LE_UNICAST != type || position < 0)
3922 OIC_LOG(ERROR, TAG, "this request is not unicast");
3923 return CA_STATUS_INVALID_PARAM;
3926 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3929 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3931 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3932 VERIFY_NON_NULL(data, TAG, "data is null");
3934 return CALEClientSendMulticastMessage(data, dataLen);
3937 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3939 ca_mutex_lock(g_bleReqRespClientCbMutex);
3940 g_CABLEClientDataReceivedCallback = callback;
3941 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3944 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3946 g_threadPoolHandle = handle;
3949 CAResult_t CAGetLEAddress(char **local_address)
3951 VERIFY_NON_NULL(local_address, TAG, "local_address");
3952 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3953 return CA_NOT_SUPPORTED;
3956 JNIEXPORT void JNICALL
3957 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3960 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3961 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3962 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3963 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3965 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3968 JNIEXPORT void JNICALL
3969 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3972 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3973 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3974 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3975 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3977 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3980 JNIEXPORT void JNICALL
3981 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3984 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3985 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3986 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3988 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3989 if (CA_STATUS_OK != res)
3991 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3995 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
3997 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
3999 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
4000 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
4002 jmethodID jni_mid_getDevice = CALEGetJNIMethodID(env, CLASSPATH_BT_GATT,
4003 "getDevice", METHODID_BT_DEVICE);
4004 if (!jni_mid_getDevice)
4006 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
4010 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
4011 if (!jni_obj_device)
4013 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
4017 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
4020 OIC_LOG(ERROR, TAG, "jni_address is null");
4024 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4029 * Class: org_iotivity_ca_jar_caleinterface
4030 * Method: CALeGattConnectionStateChangeCallback
4031 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4033 JNIEXPORT void JNICALL
4034 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4040 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4042 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4043 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4044 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4046 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4047 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4048 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4050 if (gatt_success == status && state_connected == newstate) // le connected
4052 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4058 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4061 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4062 STATE_CHARACTER_NO_CHANGE,
4064 if (CA_STATUS_OK != res)
4066 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4067 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4070 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4072 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4075 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4076 if (CA_STATUS_OK != res)
4078 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4082 res = CALEClientDiscoverServices(env, gatt);
4083 if (CA_STATUS_OK != res)
4085 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4089 else if (state_disconnected == newstate) // le disconnected
4091 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4094 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4098 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4101 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4102 STATE_CHARACTER_UNSET,
4104 if (CA_STATUS_OK != res)
4106 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4107 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4110 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4112 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4115 CAResult_t res = CALEClientGattClose(env, gatt);
4116 if (CA_STATUS_OK != res)
4118 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4121 if (gatt_success == status)
4123 // that state is a general reason to disconnect BLE.
4124 // its means manual disconnected message from BT platform.
4125 // in this case Scanning has to start again and clean previous data.
4126 CAResult_t res = CALEClientStartScan();
4127 if (CA_STATUS_OK != res)
4129 if (CA_ADAPTER_NOT_ENABLED == res)
4131 // scan will be started with start server when adapter is enabled
4132 OIC_LOG(INFO, TAG, "Adapter was disabled");
4136 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
4141 else if (GATT_ERROR == status)
4143 // when we get GATT ERROR(0x85), gatt connection can be called again.
4144 OIC_LOG(INFO, TAG, "retry gatt connect");
4146 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4149 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4153 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4156 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4160 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4163 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4171 if (CALECheckConnectionStateValue(status))
4173 // this state is unexpected reason to disconnect
4174 // if the reason is suitable, connection logic of the device will be destroyed.
4175 OIC_LOG(INFO, TAG, "connection logic destroy");
4180 // other reason is expected to running background connection in BT platform.
4181 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
4182 CALEClientUpdateSendCnt(env);
4189 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4190 g_sendBuffer = NULL;
4198 CALEClientSendFinish(env, gatt);
4203 * Class: org_iotivity_ca_jar_caleinterface
4204 * Method: CALeGattServicesDiscoveredCallback
4205 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4207 JNIEXPORT void JNICALL
4208 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4213 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4214 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4215 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4216 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4218 if (0 != status) // discovery error
4220 CALEClientSendFinish(env, gatt);
4224 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4227 CALEClientSendFinish(env, gatt);
4231 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4234 CALEClientSendFinish(env, gatt);
4238 if (!CALEClientIsSetCharacteristic(address))
4240 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4243 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4247 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4248 if (!jni_obj_GattCharacteristic)
4250 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4254 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4255 jni_obj_GattCharacteristic);
4256 if (CA_STATUS_OK != res)
4258 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4262 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4263 if (CA_STATUS_OK != res)
4265 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4268 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4269 if (CA_STATUS_OK != res)
4271 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4277 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4279 if (CA_STATUS_OK != res)
4281 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4289 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4290 if (CA_STATUS_OK != res)
4292 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4297 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4298 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4303 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4304 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4305 CALEClientSendFinish(env, gatt);
4310 * Class: org_iotivity_ca_jar_caleinterface
4311 * Method: CALeGattCharacteristicWritjclasseCallback
4312 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4314 JNIEXPORT void JNICALL
4315 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4316 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4319 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4320 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4321 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4322 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4324 // send success & signal
4325 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4331 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4337 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4338 if (gatt_success != status) // error case
4340 OIC_LOG(ERROR, TAG, "send failure");
4343 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4344 if (CA_STATUS_OK != res)
4346 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4347 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4348 g_isSignalSetFlag = true;
4349 ca_cond_signal(g_threadWriteCharacteristicCond);
4350 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4352 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4353 STATE_CHARACTER_SET,
4355 if (CA_STATUS_OK != res)
4357 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4360 if (g_clientErrorCallback)
4362 jint length = (*env)->GetArrayLength(env, data);
4363 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4366 CALEClientSendFinish(env, gatt);
4372 OIC_LOG(DEBUG, TAG, "send success");
4373 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4374 STATE_SEND_SUCCESS);
4375 if (CA_STATUS_OK != res)
4377 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4380 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4381 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4382 g_isSignalSetFlag = true;
4383 ca_cond_signal(g_threadWriteCharacteristicCond);
4384 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4386 CALEClientUpdateSendCnt(env);
4389 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4395 CALEClientSendFinish(env, gatt);
4400 * Class: org_iotivity_ca_jar_caleinterface
4401 * Method: CALeGattCharacteristicChangedCallback
4402 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4404 JNIEXPORT void JNICALL
4405 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4406 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4408 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4409 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4410 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4411 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4412 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4414 // get Byte Array and convert to uint8_t*
4415 jint length = (*env)->GetArrayLength(env, data);
4418 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4420 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4421 jni_byte_responseData);
4423 uint8_t* receivedData = OICMalloc(length);
4426 OIC_LOG(ERROR, TAG, "receivedData is null");
4430 memcpy(receivedData, jni_byte_responseData, length);
4431 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4433 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4436 OIC_LOG(ERROR, TAG, "jni_address is null");
4437 OICFree(receivedData);
4441 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4444 OIC_LOG(ERROR, TAG, "address is null");
4445 OICFree(receivedData);
4449 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4450 receivedData, length);
4452 ca_mutex_lock(g_bleServerBDAddressMutex);
4453 uint32_t sentLength = 0;
4454 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4456 ca_mutex_unlock(g_bleServerBDAddressMutex);
4458 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4462 * Class: org_iotivity_ca_jar_caleinterface
4463 * Method: CALeGattDescriptorWriteCallback
4464 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4466 JNIEXPORT void JNICALL
4467 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4471 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4472 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4473 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4474 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4476 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4477 if (gatt_success != status) // error
4484 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4485 if (CA_STATUS_OK != res)
4487 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4496 CALEClientSendFinish(env, gatt);