1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 #define GATT_CONNECTION_PRIORITY_BALANCED 0
46 #define GATT_FAILURE 257
47 #define GATT_INSUFFICIENT_AUTHENTICATION 5
48 #define GATT_INSUFFICIENT_ENCRYPTION 15
49 #define GATT_INVALID_ATTRIBUTE_LENGTH 13
50 #define GATT_INVALID_OFFSET 7
51 #define GATT_READ_NOT_PERMITTED 2
52 #define GATT_REQUEST_NOT_SUPPORTED 6
53 #define GATT_WRITE_NOT_PERMITTED 3
55 static ca_thread_pool_t g_threadPoolHandle = NULL;
58 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
59 static u_arraylist_t *g_gattObjectList = NULL;
60 static u_arraylist_t *g_deviceStateList = NULL;
62 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
63 static CABLEErrorHandleCallback g_clientErrorCallback;
64 static jobject g_leScanCallback = NULL;
65 static jobject g_leGattCallback = NULL;
66 static jobject g_context = NULL;
67 static jobjectArray g_uuidList = NULL;
69 // it will be prevent to start send logic when adapter has stopped.
70 static bool g_isStartedLEClient = false;
71 static bool g_isStartedScan = false;
73 static jbyteArray g_sendBuffer = NULL;
74 static uint32_t g_targetCnt = 0;
75 static uint32_t g_currentSentCnt = 0;
76 static bool g_isFinishedSendData = false;
77 static ca_mutex g_SendFinishMutex = NULL;
78 static ca_mutex g_threadMutex = NULL;
79 static ca_cond g_threadCond = NULL;
80 static ca_cond g_deviceDescCond = NULL;
82 static ca_mutex g_threadSendMutex = NULL;
83 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
84 static ca_cond g_threadWriteCharacteristicCond = NULL;
85 static bool g_isSignalSetFlag = false;
87 static ca_mutex g_bleReqRespClientCbMutex = NULL;
88 static ca_mutex g_bleServerBDAddressMutex = NULL;
90 static ca_mutex g_deviceListMutex = NULL;
91 static ca_mutex g_gattObjectMutex = NULL;
92 static ca_mutex g_deviceStateListMutex = NULL;
94 static ca_mutex g_deviceScanRetryDelayMutex = NULL;
95 static ca_cond g_deviceScanRetryDelayCond = NULL;
97 static ca_mutex g_scanMutex = NULL;
99 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
102 * check if retry logic for connection routine has to be stopped or not.
103 * in case of error value including this method, connection routine has to be stopped.
104 * since there is no retry logic for this error reason in this client.
105 * @param state constant value of bluetoothgatt.
106 * @return true - waiting for background connection in BT platform.
107 * false - connection routine has to be stopped.
109 static bool CALECheckConnectionStateValue(jint state)
113 case GATT_CONNECTION_PRIORITY_BALANCED:
115 case GATT_INSUFFICIENT_AUTHENTICATION:
116 case GATT_INSUFFICIENT_ENCRYPTION:
117 case GATT_INVALID_ATTRIBUTE_LENGTH:
118 case GATT_INVALID_OFFSET:
119 case GATT_READ_NOT_PERMITTED:
120 case GATT_REQUEST_NOT_SUPPORTED:
121 case GATT_WRITE_NOT_PERMITTED:
128 void CALEClientJniInit()
130 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
131 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
134 void CALEClientJNISetContext()
136 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
137 g_context = (jobject) CANativeJNIGetContext();
140 CAResult_t CALECreateJniInterfaceObject()
142 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
146 OIC_LOG(ERROR, TAG, "g_context is null");
147 return CA_STATUS_FAILED;
152 OIC_LOG(ERROR, TAG, "g_jvm is null");
153 return CA_STATUS_FAILED;
156 bool isAttached = false;
158 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
161 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
162 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
166 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
167 return CA_STATUS_FAILED;
172 jmethodID mid_getApplicationContext = CAGetJNIMethodID(env, "android/content/Context",
173 "getApplicationContext",
174 "()Landroid/content/Context;");
176 if (!mid_getApplicationContext)
178 OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
179 return CA_STATUS_FAILED;
182 jobject jApplicationContext = (*env)->CallObjectMethod(env, g_context,
183 mid_getApplicationContext);
184 if (!jApplicationContext)
186 OIC_LOG(ERROR, TAG, "Could not get application context");
187 return CA_STATUS_FAILED;
190 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
191 if (!jni_LEInterface)
193 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
197 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
198 "(Landroid/content/Context;)V");
199 if (!LeInterfaceConstructorMethod)
201 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
205 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, jApplicationContext);
206 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
210 (*g_jvm)->DetachCurrentThread(g_jvm);
219 (*g_jvm)->DetachCurrentThread(g_jvm);
222 return CA_STATUS_FAILED;
225 CAResult_t CALEClientInitialize()
227 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
233 OIC_LOG(ERROR, TAG, "g_jvm is null");
234 return CA_STATUS_FAILED;
237 bool isAttached = false;
239 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
242 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
243 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
247 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
248 return CA_STATUS_FAILED;
253 CAResult_t ret = CALECheckPlatformVersion(env, 18);
254 if (CA_STATUS_OK != ret)
256 OIC_LOG(ERROR, TAG, "it is not supported");
260 (*g_jvm)->DetachCurrentThread(g_jvm);
266 ret = CALEClientInitGattMutexVaraibles();
267 if (CA_STATUS_OK != ret)
269 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
270 CALEClientTerminateGattMutexVariables();
274 (*g_jvm)->DetachCurrentThread(g_jvm);
280 g_deviceDescCond = ca_cond_new();
282 // init mutex for send logic
283 g_threadCond = ca_cond_new();
284 g_threadWriteCharacteristicCond = ca_cond_new();
285 g_deviceScanRetryDelayCond = ca_cond_new();
287 CALEClientCreateDeviceList();
288 CALEClientJNISetContext();
290 ret = CALEClientCreateUUIDList();
291 if (CA_STATUS_OK != ret)
293 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
297 (*g_jvm)->DetachCurrentThread(g_jvm);
303 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
304 if (CA_STATUS_OK != ret)
306 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
310 (*g_jvm)->DetachCurrentThread(g_jvm);
315 g_isStartedLEClient = true;
319 (*g_jvm)->DetachCurrentThread(g_jvm);
325 void CALEClientTerminate()
327 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
331 OIC_LOG(ERROR, TAG, "g_jvm is null");
335 bool isAttached = false;
337 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
340 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
341 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
345 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
351 if (g_leScanCallback)
353 (*env)->DeleteGlobalRef(env, g_leScanCallback);
354 g_leScanCallback = NULL;
357 if (g_leGattCallback)
359 (*env)->DeleteGlobalRef(env, g_leGattCallback);
360 g_leGattCallback = NULL;
365 (*env)->DeleteGlobalRef(env, g_sendBuffer);
371 (*env)->DeleteGlobalRef(env, g_uuidList);
375 CAResult_t ret = CALEClientRemoveAllDeviceState();
376 if (CA_STATUS_OK != ret)
378 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
381 ret = CALEClientRemoveAllScanDevices(env);
382 if (CA_STATUS_OK != ret)
384 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
387 ret = CALEClientRemoveAllGattObjs(env);
388 if (CA_STATUS_OK != ret)
390 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
393 CALEClientSetScanFlag(false);
394 CALEClientSetSendFinishFlag(true);
396 CALEClientTerminateGattMutexVariables();
397 CALEClientDestroyJniInterface();
399 ca_cond_free(g_deviceDescCond);
400 ca_cond_free(g_threadCond);
401 ca_cond_free(g_threadWriteCharacteristicCond);
402 ca_cond_free(g_deviceScanRetryDelayCond);
404 g_deviceDescCond = NULL;
406 g_threadWriteCharacteristicCond = NULL;
407 g_deviceScanRetryDelayCond = NULL;
409 g_isSignalSetFlag = false;
413 (*g_jvm)->DetachCurrentThread(g_jvm);
417 CAResult_t CALEClientDestroyJniInterface()
419 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
423 OIC_LOG(ERROR, TAG, "g_jvm is null");
424 return CA_STATUS_FAILED;
427 bool isAttached = false;
429 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
432 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
433 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
437 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
438 return CA_STATUS_FAILED;
443 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
444 if (!jni_LeInterface)
446 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
450 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
451 "destroyLeInterface",
453 if (!jni_InterfaceDestroyMethod)
455 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
459 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
461 if ((*env)->ExceptionCheck(env))
463 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
464 (*env)->ExceptionDescribe(env);
465 (*env)->ExceptionClear(env);
469 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
473 (*g_jvm)->DetachCurrentThread(g_jvm);
482 (*g_jvm)->DetachCurrentThread(g_jvm);
485 return CA_STATUS_FAILED;
488 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
490 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
491 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
495 CAResult_t res = CALEClientDisconnect(env, gatt);
496 if (CA_STATUS_OK != res)
498 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
501 CALEClientUpdateSendCnt(env);
504 CAResult_t CALEClientSendUnicastMessage(const char* address,
506 const uint32_t dataLen)
508 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
509 VERIFY_NON_NULL(address, TAG, "address is null");
510 VERIFY_NON_NULL(data, TAG, "data is null");
512 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
515 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
516 const uint32_t dataLen)
518 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
519 VERIFY_NON_NULL(data, TAG, "data is null");
523 OIC_LOG(ERROR, TAG, "g_jvm is null");
524 return CA_STATUS_FAILED;
527 bool isAttached = false;
529 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
532 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
533 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
537 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
538 return CA_STATUS_FAILED;
543 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
544 if (CA_STATUS_OK != ret)
546 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
551 (*g_jvm)->DetachCurrentThread(g_jvm);
557 CAResult_t CALEClientStartUnicastServer(const char* address)
559 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
561 return CA_NOT_SUPPORTED;
564 CAResult_t CALEClientStartMulticastServer()
566 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
568 return CA_NOT_SUPPORTED;
571 void CALEClientStopUnicastServer()
573 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
576 void CALEClientStopMulticastServer()
578 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
581 void CALEClientSetCallback(CAPacketReceiveCallback callback)
583 g_packetReceiveCallback = callback;
586 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
588 g_clientErrorCallback = callback;
591 CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
593 VERIFY_NON_NULL(env, TAG, "env");
597 return CA_STATUS_FAILED;
600 if (0 == u_arraylist_length(g_deviceList) // multicast
601 || (address && !CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
603 // Wait for LE peripherals to be discovered.
605 // Number of times to wait for discovery to complete.
606 static size_t const RETRIES = 5;
608 static uint64_t const TIMEOUT =
609 2 * MICROSECS_PER_SEC; // Microseconds
611 bool devicesDiscovered = false;
612 for (size_t i = 0; i < RETRIES; ++i)
614 OIC_LOG(DEBUG, TAG, "waiting for target device");
615 if (ca_cond_wait_for(g_deviceDescCond,
617 TIMEOUT) == CA_WAIT_SUCCESS)
619 ca_mutex_lock(g_deviceListMutex);
620 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
621 ca_mutex_unlock(g_deviceListMutex);
623 if (0 < scannedDeviceLen)
625 if (!address // multicast
626 || (address && CALEClientIsDeviceInScanDeviceList(env, address))) // unicast
628 devicesDiscovered = true;
635 OIC_LOG(INFO, TAG, "waiting..");
637 ca_mutex_lock(g_deviceScanRetryDelayMutex);
638 if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
639 g_deviceScanRetryDelayMutex,
640 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
642 OIC_LOG(INFO, TAG, "finish to waiting for target device");
643 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
646 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
649 // checking whether a target device is found while waiting for time-out.
650 if (CALEClientIsDeviceInScanDeviceList(env, address))
652 devicesDiscovered = true;
661 // time out for scanning devices
662 if (!devicesDiscovered)
664 return CA_STATUS_FAILED;
672 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
673 const uint32_t dataLen)
675 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
677 VERIFY_NON_NULL(address, TAG, "address is null");
678 VERIFY_NON_NULL(data, TAG, "data is null");
682 OIC_LOG(ERROR, TAG, "g_jvm is null");
683 return CA_STATUS_FAILED;
686 bool isAttached = false;
688 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
691 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
692 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
695 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
696 return CA_STATUS_FAILED;
701 ca_mutex_lock(g_threadSendMutex);
703 CALEClientSetSendFinishFlag(false);
705 CAResult_t ret = CALEClientIsThereScannedDevices(env, address);
706 if (CA_STATUS_OK != ret)
708 OIC_LOG(INFO, TAG, "there is no scanned device");
712 if (g_context && g_deviceList)
714 uint32_t length = u_arraylist_length(g_deviceList);
715 for (uint32_t index = 0; index < length; index++)
717 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
720 OIC_LOG(ERROR, TAG, "jarrayObj is null");
724 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
727 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
731 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
734 OIC_LOG(ERROR, TAG, "setAddress is null");
738 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
740 if (!strcmp(setAddress, address))
742 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
744 // connect to gatt server
745 ret = CALEClientStopScan();
746 if (CA_STATUS_OK != ret)
748 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
754 (*env)->DeleteGlobalRef(env, g_sendBuffer);
757 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
758 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
759 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
761 // Target device to send message is just one.
764 ret = CALEClientSendData(env, jarrayObj);
765 if (CA_STATUS_OK != ret)
767 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
771 OIC_LOG(INFO, TAG, "wake up");
774 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
778 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
780 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
781 // if there is no connection state.
782 ca_mutex_lock(g_threadMutex);
783 if (!g_isFinishedSendData)
785 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
786 ca_cond_wait(g_threadCond, g_threadMutex);
787 OIC_LOG(DEBUG, TAG, "the data was sent");
789 ca_mutex_unlock(g_threadMutex);
793 (*g_jvm)->DetachCurrentThread(g_jvm);
796 // start LE Scan again
797 ret = CALEClientStartScan();
798 if (CA_STATUS_OK != ret)
800 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
801 ca_mutex_unlock(g_threadSendMutex);
805 ca_mutex_unlock(g_threadSendMutex);
806 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
807 return CALECheckSendState(address);
812 // start LE Scan again
813 ret = CALEClientStartScan();
814 if (CA_STATUS_OK != ret)
816 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
817 ca_mutex_unlock(g_threadSendMutex);
820 (*g_jvm)->DetachCurrentThread(g_jvm);
827 (*g_jvm)->DetachCurrentThread(g_jvm);
830 if (g_clientErrorCallback)
832 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
834 ca_mutex_unlock(g_threadSendMutex);
835 return CA_SEND_FAILED;
838 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
839 const uint32_t dataLen)
841 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
842 VERIFY_NON_NULL(data, TAG, "data is null");
843 VERIFY_NON_NULL(env, TAG, "env is null");
847 OIC_LOG(ERROR, TAG, "g_deviceList is null");
848 return CA_STATUS_FAILED;
851 ca_mutex_lock(g_threadSendMutex);
853 CALEClientSetSendFinishFlag(false);
855 OIC_LOG(DEBUG, TAG, "set byteArray for data");
858 (*env)->DeleteGlobalRef(env, g_sendBuffer);
862 CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
863 if (CA_STATUS_OK != res)
865 OIC_LOG(INFO, TAG, "there is no scanned device");
869 // connect to gatt server
870 res = CALEClientStopScan();
871 if (CA_STATUS_OK != res)
873 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
874 ca_mutex_unlock(g_threadSendMutex);
877 uint32_t length = u_arraylist_length(g_deviceList);
878 g_targetCnt = length;
880 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
881 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
882 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
884 for (uint32_t index = 0; index < length; index++)
886 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
889 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
893 res = CALEClientSendData(env, jarrayObj);
894 if (res != CA_STATUS_OK)
896 OIC_LOG(ERROR, TAG, "BT device - send has failed");
899 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
902 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
906 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
909 OIC_LOG(ERROR, TAG, "address is not available");
913 (*env)->ReleaseStringUTFChars(env, jni_address, address);
916 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
918 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
919 ca_mutex_lock(g_threadMutex);
920 if (!g_isFinishedSendData)
922 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
923 ca_cond_wait(g_threadCond, g_threadMutex);
924 OIC_LOG(DEBUG, TAG, "the data was sent");
926 ca_mutex_unlock(g_threadMutex);
928 // start LE Scan again
929 res = CALEClientStartScan();
930 if (CA_STATUS_OK != res)
932 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
933 ca_mutex_unlock(g_threadSendMutex);
937 ca_mutex_unlock(g_threadSendMutex);
938 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
942 res = CALEClientStartScan();
943 if (CA_STATUS_OK != res)
945 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
946 ca_mutex_unlock(g_threadSendMutex);
950 ca_mutex_unlock(g_threadSendMutex);
951 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
952 return CA_SEND_FAILED;
955 CAResult_t CALECheckSendState(const char* address)
957 VERIFY_NON_NULL(address, TAG, "address is null");
959 ca_mutex_lock(g_deviceStateListMutex);
960 CALEState_t* state = CALEClientGetStateInfo(address);
963 OIC_LOG(ERROR, TAG, "state is null");
964 ca_mutex_unlock(g_deviceStateListMutex);
965 return CA_SEND_FAILED;
968 if (STATE_SEND_SUCCESS != state->sendState)
970 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
971 ca_mutex_unlock(g_deviceStateListMutex);
972 return CA_SEND_FAILED;
975 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
976 ca_mutex_unlock(g_deviceStateListMutex);
980 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
982 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
983 VERIFY_NON_NULL(device, TAG, "device is null");
984 VERIFY_NON_NULL(env, TAG, "env is null");
986 // get BLE address from bluetooth device object.
987 char* address = NULL;
988 CALEState_t* state = NULL;
989 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
992 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
993 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
996 OIC_LOG(ERROR, TAG, "address is not available");
997 return CA_STATUS_FAILED;
999 ca_mutex_lock(g_deviceStateListMutex);
1000 state = CALEClientGetStateInfo(address);
1001 ca_mutex_unlock(g_deviceStateListMutex);
1002 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1007 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1009 // cancel previous connection request before connection
1010 // if there is gatt object in g_gattObjectList.
1013 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1016 OIC_LOG(ERROR, TAG, "address is not available");
1017 return CA_STATUS_FAILED;
1020 jobject gatt = CALEClientGetGattObjInList(env, address);
1023 CAResult_t res = CALEClientDisconnect(env, gatt);
1024 if (CA_STATUS_OK != res)
1026 OIC_LOG(INFO, TAG, "there is no gatt object");
1029 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1032 // connection request
1033 jobject newGatt = CALEClientConnect(env, device,
1035 if (NULL == newGatt)
1037 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1038 return CA_STATUS_FAILED;
1043 if (STATE_CONNECTED == state->connectedState)
1045 OIC_LOG(INFO, TAG, "GATT has already connected");
1048 OIC_LOG(ERROR, TAG, "jni_address is not available");
1049 return CA_STATUS_FAILED;
1052 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1055 OIC_LOG(ERROR, TAG, "address is not available");
1056 return CA_STATUS_FAILED;
1059 jobject gatt = CALEClientGetGattObjInList(env, address);
1062 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1063 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1064 return CA_STATUS_FAILED;
1067 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1068 if (CA_STATUS_OK != ret)
1070 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1071 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1074 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1078 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1080 // cancel previous connection request before connection
1081 // if there is gatt object in g_gattObjectList.
1084 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1087 OIC_LOG(ERROR, TAG, "address is not available");
1088 return CA_STATUS_FAILED;
1091 jobject gatt = CALEClientGetGattObjInList(env, address);
1094 CAResult_t res = CALEClientDisconnect(env, gatt);
1095 if (CA_STATUS_OK != res)
1097 OIC_LOG(INFO, TAG, "there is no gatt object");
1100 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1103 OIC_LOG(DEBUG, TAG, "start to connect LE");
1104 jobject gatt = CALEClientConnect(env, device,
1105 CALEClientGetAutoConnectFlag(env, jni_address));
1108 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1109 return CA_STATUS_FAILED;
1114 return CA_STATUS_OK;
1117 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1119 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1120 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1122 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "getDevice",
1123 "()Landroid/bluetooth/BluetoothDevice;");
1124 if (!jni_mid_getDevice)
1126 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1130 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1131 if (!jni_obj_device)
1133 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1137 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1140 OIC_LOG(ERROR, TAG, "jni_address is null");
1150 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1153 OIC_LOG(DEBUG, TAG, "Gatt Close");
1154 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1155 VERIFY_NON_NULL(env, TAG, "env is null");
1157 // get BluetoothGatt method
1158 OIC_LOG(DEBUG, TAG, "get BluetoothGatt method");
1159 jmethodID jni_mid_closeGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT, "close", "()V");
1160 if (!jni_mid_closeGatt)
1162 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1163 return CA_STATUS_OK;
1166 // call disconnect gatt method
1167 OIC_LOG(DEBUG, TAG, "request to close GATT");
1168 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1170 if ((*env)->ExceptionCheck(env))
1172 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1173 (*env)->ExceptionDescribe(env);
1174 (*env)->ExceptionClear(env);
1175 return CA_STATUS_FAILED;
1178 return CA_STATUS_OK;
1181 CAResult_t CALEClientStartScan()
1183 if (!g_isStartedLEClient)
1185 OIC_LOG(ERROR, TAG, "LE client is not started");
1186 return CA_STATUS_FAILED;
1191 OIC_LOG(ERROR, TAG, "g_jvm is null");
1192 return CA_STATUS_FAILED;
1195 if (g_isStartedScan)
1197 OIC_LOG(INFO, TAG, "scanning is already started");
1198 return CA_STATUS_OK;
1201 bool isAttached = false;
1203 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1206 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1208 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1211 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1212 return CA_STATUS_FAILED;
1217 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1219 CAResult_t ret = CA_STATUS_OK;
1220 // scan gatt server with UUID
1221 if (g_leScanCallback && g_uuidList)
1224 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1226 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1228 if (CA_STATUS_OK != ret)
1230 if (CA_ADAPTER_NOT_ENABLED == ret)
1232 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1236 OIC_LOG(ERROR, TAG, "start scan has failed");
1243 (*g_jvm)->DetachCurrentThread(g_jvm);
1249 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1251 VERIFY_NON_NULL(callback, TAG, "callback is null");
1252 VERIFY_NON_NULL(env, TAG, "env is null");
1254 if (!CALEIsEnableBTAdapter(env))
1256 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1257 return CA_ADAPTER_NOT_ENABLED;
1260 // get default bt adapter class
1261 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1262 if (!jni_cid_BTAdapter)
1264 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1265 return CA_STATUS_FAILED;
1268 // get remote bt adapter method
1269 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1270 "getDefaultAdapter",
1271 METHODID_OBJECTNONPARAM);
1272 if (!jni_mid_getDefaultAdapter)
1274 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1275 return CA_STATUS_FAILED;
1278 // get start le scan method
1279 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1280 "(Landroid/bluetooth/BluetoothAdapter$"
1281 "LeScanCallback;)Z");
1282 if (!jni_mid_startLeScan)
1284 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1285 return CA_STATUS_FAILED;
1288 // gat bt adapter object
1289 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1290 jni_mid_getDefaultAdapter);
1291 if (!jni_obj_BTAdapter)
1293 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1294 return CA_STATUS_FAILED;
1297 // call start le scan method
1298 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1299 jni_mid_startLeScan, callback);
1300 if (!jni_obj_startLeScan)
1302 OIC_LOG(INFO, TAG, "startLeScan is failed");
1306 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1307 CALEClientSetScanFlag(true);
1310 return CA_STATUS_OK;
1313 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1315 VERIFY_NON_NULL(callback, TAG, "callback is null");
1316 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1317 VERIFY_NON_NULL(env, TAG, "env is null");
1319 if (!CALEIsEnableBTAdapter(env))
1321 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1322 return CA_ADAPTER_NOT_ENABLED;
1325 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1326 if (!jni_cid_BTAdapter)
1328 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1329 return CA_STATUS_FAILED;
1332 // get remote bt adapter method
1333 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1334 "getDefaultAdapter",
1335 METHODID_OBJECTNONPARAM);
1336 if (!jni_mid_getDefaultAdapter)
1338 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1339 return CA_STATUS_FAILED;
1342 // get start le scan method
1343 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1344 "([Ljava/util/UUID;Landroid/bluetooth/"
1345 "BluetoothAdapter$LeScanCallback;)Z");
1346 if (!jni_mid_startLeScan)
1348 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1349 return CA_STATUS_FAILED;
1352 // get bt adapter object
1353 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1354 jni_mid_getDefaultAdapter);
1355 if (!jni_obj_BTAdapter)
1357 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1358 return CA_STATUS_FAILED;
1361 // call start le scan method
1362 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1363 jni_mid_startLeScan, uuids, callback);
1364 if (!jni_obj_startLeScan)
1366 OIC_LOG(INFO, TAG, "startLeScan With UUID is failed");
1370 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1371 CALEClientSetScanFlag(true);
1374 return CA_STATUS_OK;
1377 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1379 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1380 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1383 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1386 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1390 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1391 "(Ljava/lang/String;)"
1392 "Ljava/util/UUID;");
1393 if (!jni_mid_fromString)
1395 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1399 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1400 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1404 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1408 return jni_obj_uuid;
1411 CAResult_t CALEClientStopScan()
1415 OIC_LOG(ERROR, TAG, "g_jvm is null");
1416 return CA_STATUS_FAILED;
1419 if (!g_isStartedScan)
1421 OIC_LOG(INFO, TAG, "scanning is already stopped");
1422 return CA_STATUS_OK;
1425 bool isAttached = false;
1427 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1430 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1431 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1434 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1435 return CA_STATUS_FAILED;
1440 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1441 if (CA_STATUS_OK != ret)
1443 if (CA_ADAPTER_NOT_ENABLED == ret)
1445 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1449 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1454 CALEClientSetScanFlag(false);
1459 (*g_jvm)->DetachCurrentThread(g_jvm);
1465 void CALEClientSetScanFlag(bool flag)
1467 ca_mutex_lock(g_scanMutex);
1468 g_isStartedScan = flag;
1469 ca_mutex_unlock(g_scanMutex);
1472 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1474 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1475 VERIFY_NON_NULL(callback, TAG, "callback is null");
1476 VERIFY_NON_NULL(env, TAG, "env is null");
1478 if (!CALEIsEnableBTAdapter(env))
1480 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1481 return CA_ADAPTER_NOT_ENABLED;
1484 // get default bt adapter class
1485 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1486 if (!jni_cid_BTAdapter)
1488 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1489 return CA_STATUS_FAILED;
1492 // get remote bt adapter method
1493 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1494 "getDefaultAdapter",
1495 METHODID_OBJECTNONPARAM);
1496 if (!jni_mid_getDefaultAdapter)
1498 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1499 return CA_STATUS_FAILED;
1502 // get start le scan method
1503 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1504 "(Landroid/bluetooth/"
1505 "BluetoothAdapter$LeScanCallback;)V");
1506 if (!jni_mid_stopLeScan)
1508 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1509 return CA_STATUS_FAILED;
1512 // gat bt adapter object
1513 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1514 jni_mid_getDefaultAdapter);
1515 if (!jni_obj_BTAdapter)
1517 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1518 return CA_STATUS_FAILED;
1521 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1522 // call start le scan method
1523 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1524 if ((*env)->ExceptionCheck(env))
1526 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1527 (*env)->ExceptionDescribe(env);
1528 (*env)->ExceptionClear(env);
1529 return CA_STATUS_FAILED;
1532 return CA_STATUS_OK;
1535 CAResult_t CALEClientSetAutoConnectFlag(JNIEnv *env, jstring jni_address, jboolean flag)
1537 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1538 VERIFY_NON_NULL(env, TAG, "env");
1539 VERIFY_NON_NULL(jni_address, TAG, "jni_address");
1541 ca_mutex_lock(g_deviceStateListMutex);
1543 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1546 OIC_LOG(ERROR, TAG, "address is not available");
1547 return CA_STATUS_FAILED;
1550 if (CALEClientIsDeviceInList(address))
1552 CALEState_t* curState = CALEClientGetStateInfo(address);
1555 OIC_LOG(ERROR, TAG, "curState is null");
1556 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1557 ca_mutex_unlock(g_deviceStateListMutex);
1558 return CA_STATUS_FAILED;
1560 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1562 curState->autoConnectFlag = flag;
1565 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1566 ca_mutex_unlock(g_deviceStateListMutex);
1567 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1568 return CA_STATUS_OK;
1571 jboolean CALEClientGetAutoConnectFlag(JNIEnv *env, jstring jni_address)
1573 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1574 VERIFY_NON_NULL_RET(env, TAG, "env", false);
1575 VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
1577 ca_mutex_lock(g_deviceStateListMutex);
1579 char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1582 OIC_LOG(ERROR, TAG, "address is not available");
1586 CALEState_t* curState = CALEClientGetStateInfo(address);
1589 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1590 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1591 ca_mutex_unlock(g_deviceStateListMutex);
1594 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1596 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1597 ca_mutex_unlock(g_deviceStateListMutex);
1599 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1600 return curState->autoConnectFlag;
1603 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1605 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1606 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1607 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1609 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1610 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1613 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1616 OIC_LOG(ERROR, TAG, "address is not available");
1620 // close the gatt service
1621 jobject gatt = CALEClientGetGattObjInList(env, address);
1624 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1625 if (CA_STATUS_OK != res)
1627 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1628 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1632 // clean previous gatt object after close profile service
1633 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1634 if (CA_STATUS_OK != res)
1636 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1637 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1641 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1644 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1647 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1651 // add new gatt object into g_gattObjectList
1652 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1653 if (CA_STATUS_OK != res)
1655 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1662 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1664 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1665 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1666 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1668 if (!g_leGattCallback)
1670 OIC_LOG(INFO, TAG, "g_leGattCallback is null");
1674 if (!CALEIsEnableBTAdapter(env))
1676 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1680 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1683 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1687 // get BluetoothDevice method
1688 OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
1689 jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
1691 "(Landroid/content/Context;ZLandroid/"
1692 "bluetooth/BluetoothGattCallback;)"
1693 "Landroid/bluetooth/BluetoothGatt;");
1694 if (!jni_mid_connectGatt)
1696 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1700 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1701 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1702 jni_mid_connectGatt,
1704 autoconnect, g_leGattCallback);
1705 if (!jni_obj_connectGatt)
1707 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1708 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1709 CALEClientUpdateSendCnt(env);
1714 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1716 return jni_obj_connectGatt;
1719 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1721 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1723 VERIFY_NON_NULL(env, TAG, "env is null");
1724 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1726 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1727 if (!jni_cid_BTAdapter)
1729 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1730 return CA_STATUS_FAILED;
1733 // get remote bt adapter method
1734 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1735 "getDefaultAdapter",
1736 METHODID_OBJECTNONPARAM);
1737 if (!jni_mid_getDefaultAdapter)
1739 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1740 return CA_STATUS_FAILED;
1743 // gat bt adapter object
1744 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1745 jni_mid_getDefaultAdapter);
1746 if (!jni_obj_BTAdapter)
1748 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1749 return CA_STATUS_FAILED;
1752 // get closeProfileProxy method
1753 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1754 "closeProfileProxy",
1755 "(ILandroid/bluetooth/"
1756 "BluetoothProfile;)V");
1757 if (!jni_mid_closeProfileProxy)
1759 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1760 return CA_STATUS_FAILED;
1763 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1764 if (!jni_cid_BTProfile)
1766 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1767 return CA_STATUS_FAILED;
1770 // GATT - Constant value : 7 (0x00000007)
1771 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1775 OIC_LOG(ERROR, TAG, "id_gatt is null");
1776 return CA_STATUS_FAILED;
1779 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1781 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1782 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1783 if ((*env)->ExceptionCheck(env))
1785 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1786 (*env)->ExceptionDescribe(env);
1787 (*env)->ExceptionClear(env);
1788 return CA_STATUS_FAILED;
1791 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1792 return CA_STATUS_OK;
1796 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1798 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1799 VERIFY_NON_NULL(env, TAG, "env is null");
1800 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1802 // get BluetoothGatt method
1803 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1804 jmethodID jni_mid_disconnectGatt = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1805 "disconnect", "()V");
1806 if (!jni_mid_disconnectGatt)
1808 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1809 return CA_STATUS_FAILED;
1812 // call disconnect gatt method
1813 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1814 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1815 if ((*env)->ExceptionCheck(env))
1817 OIC_LOG(ERROR, TAG, "disconnect has failed");
1818 (*env)->ExceptionDescribe(env);
1819 (*env)->ExceptionClear(env);
1820 return CA_STATUS_FAILED;
1823 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1825 return CA_STATUS_OK;
1828 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1830 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1831 VERIFY_NON_NULL(env, TAG, "env is null");
1833 if (!g_gattObjectList)
1835 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1836 return CA_STATUS_OK;
1839 uint32_t length = u_arraylist_length(g_gattObjectList);
1840 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1841 for (uint32_t index = 0; index < length; index++)
1843 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1844 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1847 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1850 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1851 if (CA_STATUS_OK != res)
1853 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1858 return CA_STATUS_OK;
1861 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1863 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1864 VERIFY_NON_NULL(env, TAG, "env is null");
1866 if (!g_gattObjectList)
1868 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1869 return CA_STATUS_OK;
1872 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1875 OIC_LOG(ERROR, TAG, "address is null");
1876 return CA_STATUS_FAILED;
1879 uint32_t length = u_arraylist_length(g_gattObjectList);
1880 for (uint32_t index = 0; index < length; index++)
1882 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1885 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1889 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1890 if (!jni_setAddress)
1892 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1893 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1894 return CA_STATUS_FAILED;
1897 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1900 OIC_LOG(ERROR, TAG, "setAddress is null");
1901 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1902 return CA_STATUS_FAILED;
1905 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1906 if (!strcmp(address, setAddress))
1908 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1909 if (CA_STATUS_OK != res)
1911 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1912 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1913 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1914 return CA_STATUS_FAILED;
1916 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1917 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1918 return CA_STATUS_OK;
1920 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1922 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1924 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1925 return CA_STATUS_OK;
1928 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1930 VERIFY_NON_NULL(env, TAG, "env is null");
1931 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1933 if (!CALEIsEnableBTAdapter(env))
1935 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1936 return CA_ADAPTER_NOT_ENABLED;
1939 // get BluetoothGatt.discoverServices method
1940 OIC_LOG(DEBUG, TAG, "get BluetoothGatt.discoverServices method");
1941 jmethodID jni_mid_discoverServices = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
1942 "discoverServices", "()Z");
1943 if (!jni_mid_discoverServices)
1945 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1946 return CA_STATUS_FAILED;
1949 // call disconnect gatt method
1950 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1951 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1954 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1955 return CA_STATUS_FAILED;
1958 return CA_STATUS_OK;
1961 static void CALEWriteCharacteristicThread(void* object)
1963 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1965 bool isAttached = false;
1967 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1970 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1971 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1975 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1981 jobject gatt = (jobject)object;
1982 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1983 if (CA_STATUS_OK != ret)
1985 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1990 (*g_jvm)->DetachCurrentThread(g_jvm);
1994 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1996 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1997 VERIFY_NON_NULL(env, TAG, "env is null");
2000 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
2001 if (!jni_obj_character)
2003 CALEClientSendFinish(env, gatt);
2004 return CA_STATUS_FAILED;
2007 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
2008 if (CA_STATUS_OK != ret)
2010 CALEClientSendFinish(env, gatt);
2011 return CA_STATUS_FAILED;
2014 // wait for callback for write Characteristic with success to sent data
2015 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
2016 ca_mutex_lock(g_threadWriteCharacteristicMutex);
2017 if (!g_isSignalSetFlag)
2019 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
2020 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
2021 g_threadWriteCharacteristicMutex,
2022 WAIT_TIME_WRITE_CHARACTERISTIC))
2024 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
2025 g_isSignalSetFlag = false;
2026 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2027 return CA_STATUS_FAILED;
2030 // reset flag set by writeCharacteristic Callback
2031 g_isSignalSetFlag = false;
2032 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
2034 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
2035 return CA_STATUS_OK;
2038 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
2040 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
2041 VERIFY_NON_NULL(env, TAG, "env is null");
2042 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2044 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
2045 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
2046 CALEWriteCharacteristicThread, (void*)gattParam))
2048 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
2049 return CA_STATUS_FAILED;
2052 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
2053 return CA_STATUS_OK;
2056 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
2057 jobject gattCharacteristic)
2059 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
2060 VERIFY_NON_NULL(env, TAG, "env is null");
2061 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2062 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
2064 if (!CALEIsEnableBTAdapter(env))
2066 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2067 return CA_STATUS_FAILED;
2070 // get BluetoothGatt.write characteristic method
2071 OIC_LOG(DEBUG, TAG, "write characteristic method");
2072 jmethodID jni_mid_writeCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2073 "writeCharacteristic",
2074 "(Landroid/bluetooth/"
2075 "BluetoothGattCharacteristic;)Z");
2076 if (!jni_mid_writeCharacteristic)
2078 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2079 return CA_STATUS_FAILED;
2082 // call disconnect gatt method
2083 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2084 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2085 jni_mid_writeCharacteristic,
2086 gattCharacteristic);
2089 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2093 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2094 return CA_STATUS_FAILED;
2097 return CA_STATUS_OK;
2100 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2102 VERIFY_NON_NULL(env, TAG, "env is null");
2103 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2105 if (!CALEIsEnableBTAdapter(env))
2107 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2108 return CA_STATUS_FAILED;
2111 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2114 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2115 return CA_STATUS_FAILED;
2118 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2119 if (!jni_obj_GattCharacteristic)
2121 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2122 return CA_STATUS_FAILED;
2125 OIC_LOG(DEBUG, TAG, "read characteristic method");
2126 jmethodID jni_mid_readCharacteristic = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2127 "readCharacteristic",
2128 "(Landroid/bluetooth/"
2129 "BluetoothGattCharacteristic;)Z");
2130 if (!jni_mid_readCharacteristic)
2132 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2133 return CA_STATUS_FAILED;
2136 // call disconnect gatt method
2137 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2138 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2139 jni_obj_GattCharacteristic);
2142 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2146 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2147 return CA_STATUS_FAILED;
2150 return CA_STATUS_OK;
2153 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2154 jobject characteristic)
2156 VERIFY_NON_NULL(env, TAG, "env is null");
2157 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2158 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2160 if (!CALEIsEnableBTAdapter(env))
2162 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2163 return CA_ADAPTER_NOT_ENABLED;
2166 // get BluetoothGatt.setCharacteristicNotification method
2167 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2168 jmethodID jni_mid_setNotification = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2169 "setCharacteristicNotification",
2170 "(Landroid/bluetooth/"
2171 "BluetoothGattCharacteristic;Z)Z");
2172 if (!jni_mid_setNotification)
2174 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2175 return CA_STATUS_FAILED;
2178 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2179 characteristic, JNI_TRUE);
2180 if (JNI_TRUE == ret)
2182 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2186 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2187 return CA_STATUS_FAILED;
2190 return CA_STATUS_OK;
2193 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2195 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2196 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2197 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2199 if (!CALEIsEnableBTAdapter(env))
2201 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2205 // get BluetoothGatt.getService method
2206 OIC_LOG(DEBUG, TAG, "BluetoothGatt.getService");
2207 jmethodID jni_mid_getService = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
2209 "(Ljava/util/UUID;)Landroid/bluetooth/"
2210 "BluetoothGattService;");
2211 if (!jni_mid_getService)
2213 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2217 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2218 if (!jni_obj_service_uuid)
2220 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2224 // get bluetooth gatt service
2225 OIC_LOG(DEBUG, TAG, "request to get service");
2226 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2227 jni_obj_service_uuid);
2228 if (!jni_obj_gattService)
2230 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2234 // get bluetooth gatt service method
2235 jmethodID jni_mid_getCharacteristic = CAGetJNIMethodID(env, "android/bluetooth/"
2236 "BluetoothGattService",
2237 "getCharacteristic",
2238 "(Ljava/util/UUID;)"
2239 "Landroid/bluetooth/"
2240 "BluetoothGattCharacteristic;");
2241 if (!jni_mid_getCharacteristic)
2243 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2247 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2250 OIC_LOG(ERROR, TAG, "uuid is null");
2254 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2255 if (!jni_obj_tx_uuid)
2257 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2258 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2262 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2263 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2264 jni_mid_getCharacteristic,
2267 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2268 return jni_obj_GattCharacteristic;
2271 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2273 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2274 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2275 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2276 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2278 if (!CALEIsEnableBTAdapter(env))
2280 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2284 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2287 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2291 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2292 if (!jni_obj_GattCharacteristic)
2294 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2298 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2299 "/BluetoothGattCharacteristic");
2300 if (!jni_cid_BTGattCharacteristic)
2302 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2306 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2307 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2309 if (!jni_mid_setValue)
2311 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2315 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2317 if (JNI_TRUE == ret)
2319 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2323 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2328 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2329 "setWriteType", "(I)V");
2330 if (!jni_mid_setWriteType)
2332 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2336 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2337 "WRITE_TYPE_NO_RESPONSE", "I");
2338 if (!jni_fid_no_response)
2340 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2344 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2345 jni_fid_no_response);
2347 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2349 return jni_obj_GattCharacteristic;
2352 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2354 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2355 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2357 if (!CALEIsEnableBTAdapter(env))
2359 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2363 jmethodID jni_mid_getValue = CAGetJNIMethodID(env, "android/bluetooth/"
2364 "BluetoothGattCharacteristic",
2365 "getValue", "()[B");
2366 if (!jni_mid_getValue)
2368 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2372 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2374 return jni_obj_data_array;
2377 CAResult_t CALEClientCreateUUIDList()
2381 OIC_LOG(ERROR, TAG, "g_jvm is null");
2382 return CA_STATUS_FAILED;
2385 bool isAttached = false;
2387 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2390 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2391 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2395 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2396 return CA_STATUS_FAILED;
2401 // create new object array
2402 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2403 if (!jni_cid_uuid_list)
2405 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2409 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2410 jni_cid_uuid_list, NULL);
2411 if (!jni_obj_uuid_list)
2413 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2418 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2421 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2424 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2426 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2430 (*g_jvm)->DetachCurrentThread(g_jvm);
2433 return CA_STATUS_OK;
2440 (*g_jvm)->DetachCurrentThread(g_jvm);
2442 return CA_STATUS_FAILED;
2445 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2446 jobject characteristic)
2448 VERIFY_NON_NULL(env, TAG, "env is null");
2449 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2450 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2452 if (!CALEIsEnableBTAdapter(env))
2454 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2455 return CA_ADAPTER_NOT_ENABLED;
2458 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2459 jmethodID jni_mid_getDescriptor = CAGetJNIMethodID(env, "android/bluetooth/"
2460 "BluetoothGattCharacteristic",
2462 "(Ljava/util/UUID;)Landroid/bluetooth/"
2463 "BluetoothGattDescriptor;");
2464 if (!jni_mid_getDescriptor)
2466 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2467 return CA_STATUS_FAILED;
2470 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2471 if (!jni_obj_cc_uuid)
2473 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2474 return CA_STATUS_FAILED;
2477 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2478 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2479 jni_mid_getDescriptor, jni_obj_cc_uuid);
2480 if (!jni_obj_descriptor)
2482 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2483 return CA_NOT_SUPPORTED;
2486 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2487 jclass jni_cid_descriptor = (*env)->FindClass(env,
2488 "android/bluetooth/BluetoothGattDescriptor");
2489 if (!jni_cid_descriptor)
2491 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2492 return CA_STATUS_FAILED;
2495 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2496 if (!jni_mid_setValue)
2498 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2499 return CA_STATUS_FAILED;
2502 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2503 "ENABLE_NOTIFICATION_VALUE", "[B");
2504 if (!jni_fid_NotiValue)
2506 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2507 return CA_STATUS_FAILED;
2510 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2512 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2513 env, jni_obj_descriptor, jni_mid_setValue,
2514 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2517 OIC_LOG(DEBUG, TAG, "setValue success");
2521 OIC_LOG(ERROR, TAG, "setValue has failed");
2522 return CA_STATUS_FAILED;
2525 jmethodID jni_mid_writeDescriptor = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
2527 "(Landroid/bluetooth/"
2528 "BluetoothGattDescriptor;)Z");
2529 if (!jni_mid_writeDescriptor)
2531 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2532 return CA_STATUS_FAILED;
2535 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2536 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2537 jni_obj_descriptor);
2540 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2544 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2545 return CA_STATUS_FAILED;
2548 return CA_STATUS_OK;
2551 void CALEClientCreateScanDeviceList(JNIEnv *env)
2553 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2554 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2556 ca_mutex_lock(g_deviceListMutex);
2557 // create new object array
2558 if (g_deviceList == NULL)
2560 OIC_LOG(DEBUG, TAG, "Create device list");
2562 g_deviceList = u_arraylist_create();
2564 ca_mutex_unlock(g_deviceListMutex);
2567 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2569 VERIFY_NON_NULL(device, TAG, "device is null");
2570 VERIFY_NON_NULL(env, TAG, "env is null");
2572 ca_mutex_lock(g_deviceListMutex);
2576 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2578 CALEClientSetScanFlag(false);
2579 if (CA_STATUS_OK != CALEClientStopScan())
2581 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2584 ca_mutex_unlock(g_deviceListMutex);
2585 return CA_STATUS_FAILED;
2588 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2589 if (!jni_remoteAddress)
2591 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2592 ca_mutex_unlock(g_deviceListMutex);
2593 return CA_STATUS_FAILED;
2596 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2599 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2600 ca_mutex_unlock(g_deviceListMutex);
2601 return CA_STATUS_FAILED;
2604 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2606 jobject gdevice = (*env)->NewGlobalRef(env, device);
2607 u_arraylist_add(g_deviceList, gdevice);
2608 ca_cond_signal(g_deviceDescCond);
2609 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2611 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2613 ca_mutex_unlock(g_deviceListMutex);
2615 return CA_STATUS_OK;
2618 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2620 VERIFY_NON_NULL_RET(env, TAG, "env is null", true);
2621 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2625 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2629 uint32_t length = u_arraylist_length(g_deviceList);
2630 for (uint32_t index = 0; index < length; index++)
2632 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2635 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2639 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2640 if (!jni_setAddress)
2642 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2646 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2649 OIC_LOG(ERROR, TAG, "setAddress is null");
2653 if (!strcmp(remoteAddress, setAddress))
2655 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2659 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2662 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2667 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2669 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2670 VERIFY_NON_NULL(env, TAG, "env is null");
2672 ca_mutex_lock(g_deviceListMutex);
2676 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2677 ca_mutex_unlock(g_deviceListMutex);
2678 return CA_STATUS_FAILED;
2681 uint32_t length = u_arraylist_length(g_deviceList);
2682 for (uint32_t index = 0; index < length; index++)
2684 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2687 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2690 (*env)->DeleteGlobalRef(env, jarrayObj);
2694 OICFree(g_deviceList);
2695 g_deviceList = NULL;
2697 ca_mutex_unlock(g_deviceListMutex);
2698 return CA_STATUS_OK;
2701 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2703 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2704 VERIFY_NON_NULL(address, TAG, "address is null");
2705 VERIFY_NON_NULL(env, TAG, "env is null");
2707 ca_mutex_lock(g_deviceListMutex);
2711 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2712 ca_mutex_unlock(g_deviceListMutex);
2713 return CA_STATUS_FAILED;
2716 uint32_t length = u_arraylist_length(g_deviceList);
2717 for (uint32_t index = 0; index < length; index++)
2719 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2722 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2723 ca_mutex_unlock(g_deviceListMutex);
2724 return CA_STATUS_FAILED;
2727 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2728 if (!jni_setAddress)
2730 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2731 ca_mutex_unlock(g_deviceListMutex);
2732 return CA_STATUS_FAILED;
2735 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2738 OIC_LOG(ERROR, TAG, "setAddress is null");
2739 ca_mutex_unlock(g_deviceListMutex);
2740 return CA_STATUS_FAILED;
2743 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2746 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2747 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2748 ca_mutex_unlock(g_deviceListMutex);
2749 return CA_STATUS_FAILED;
2752 if (!strcmp(setAddress, remoteAddress))
2754 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2755 (*env)->DeleteGlobalRef(env, jarrayObj);
2757 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2758 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2760 if (NULL == u_arraylist_remove(g_deviceList, index))
2762 OIC_LOG(ERROR, TAG, "List removal failed.");
2763 ca_mutex_unlock(g_deviceListMutex);
2764 return CA_STATUS_FAILED;
2766 ca_mutex_unlock(g_deviceListMutex);
2767 return CA_STATUS_OK;
2769 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2770 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2773 ca_mutex_unlock(g_deviceListMutex);
2774 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2776 return CA_STATUS_OK;
2783 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2785 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2786 VERIFY_NON_NULL(env, TAG, "env is null");
2787 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2789 ca_mutex_lock(g_gattObjectMutex);
2791 if (!g_gattObjectList)
2793 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2794 ca_mutex_unlock(g_gattObjectMutex);
2795 return CA_STATUS_FAILED;
2798 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2799 if (!jni_remoteAddress)
2801 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2802 ca_mutex_unlock(g_gattObjectMutex);
2803 return CA_STATUS_FAILED;
2806 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2809 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2810 ca_mutex_unlock(g_gattObjectMutex);
2811 return CA_STATUS_FAILED;
2814 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2815 if (!CALEClientIsGattObjInList(env, remoteAddress))
2817 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2818 u_arraylist_add(g_gattObjectList, newGatt);
2819 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2822 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2823 ca_mutex_unlock(g_gattObjectMutex);
2824 return CA_STATUS_OK;
2827 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2829 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2830 VERIFY_NON_NULL(env, TAG, "env is null");
2831 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2833 uint32_t length = u_arraylist_length(g_gattObjectList);
2834 for (uint32_t index = 0; index < length; index++)
2837 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2840 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2844 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2845 if (!jni_setAddress)
2847 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2851 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2854 OIC_LOG(ERROR, TAG, "setAddress is null");
2858 if (!strcmp(remoteAddress, setAddress))
2860 OIC_LOG(DEBUG, TAG, "the device is already set");
2861 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2866 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2871 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2875 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2877 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2878 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2879 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2881 ca_mutex_lock(g_gattObjectMutex);
2882 uint32_t length = u_arraylist_length(g_gattObjectList);
2883 for (uint32_t index = 0; index < length; index++)
2885 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2888 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2889 ca_mutex_unlock(g_gattObjectMutex);
2893 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2894 if (!jni_setAddress)
2896 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2897 ca_mutex_unlock(g_gattObjectMutex);
2901 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2904 OIC_LOG(ERROR, TAG, "setAddress is null");
2905 ca_mutex_unlock(g_gattObjectMutex);
2909 if (!strcmp(remoteAddress, setAddress))
2911 OIC_LOG(DEBUG, TAG, "the device is already set");
2912 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2913 ca_mutex_unlock(g_gattObjectMutex);
2916 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2919 ca_mutex_unlock(g_gattObjectMutex);
2920 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2924 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2926 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2927 VERIFY_NON_NULL(env, TAG, "env is null");
2929 ca_mutex_lock(g_gattObjectMutex);
2930 if (!g_gattObjectList)
2932 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2933 ca_mutex_unlock(g_gattObjectMutex);
2934 return CA_STATUS_OK;
2937 uint32_t length = u_arraylist_length(g_gattObjectList);
2938 for (uint32_t index = 0; index < length; index++)
2940 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2943 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2946 (*env)->DeleteGlobalRef(env, jarrayObj);
2950 OICFree(g_gattObjectList);
2951 g_gattObjectList = NULL;
2952 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2953 ca_mutex_unlock(g_gattObjectMutex);
2954 return CA_STATUS_OK;
2957 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2959 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2960 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2961 VERIFY_NON_NULL(env, TAG, "env is null");
2963 ca_mutex_lock(g_gattObjectMutex);
2964 if (!g_gattObjectList)
2966 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2967 ca_mutex_unlock(g_gattObjectMutex);
2968 return CA_STATUS_OK;
2971 uint32_t length = u_arraylist_length(g_gattObjectList);
2972 for (uint32_t index = 0; index < length; index++)
2974 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2977 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2978 ca_mutex_unlock(g_gattObjectMutex);
2979 return CA_STATUS_FAILED;
2982 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2983 if (!jni_setAddress)
2985 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2986 ca_mutex_unlock(g_gattObjectMutex);
2987 return CA_STATUS_FAILED;
2990 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2993 OIC_LOG(ERROR, TAG, "setAddress is null");
2994 ca_mutex_unlock(g_gattObjectMutex);
2995 return CA_STATUS_FAILED;
2998 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2999 if (!jni_remoteAddress)
3001 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
3002 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3003 ca_mutex_unlock(g_gattObjectMutex);
3004 return CA_STATUS_FAILED;
3007 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
3010 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3011 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3012 ca_mutex_unlock(g_gattObjectMutex);
3013 return CA_STATUS_FAILED;
3016 if (!strcmp(setAddress, remoteAddress))
3018 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3019 (*env)->DeleteGlobalRef(env, jarrayObj);
3021 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3022 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3024 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3026 OIC_LOG(ERROR, TAG, "List removal failed.");
3027 ca_mutex_unlock(g_gattObjectMutex);
3028 return CA_STATUS_FAILED;
3030 ca_mutex_unlock(g_gattObjectMutex);
3031 return CA_STATUS_OK;
3033 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3034 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3037 ca_mutex_unlock(g_gattObjectMutex);
3038 OIC_LOG(DEBUG, TAG, "there are no target object");
3039 return CA_STATUS_OK;
3042 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3044 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3045 VERIFY_NON_NULL(addr, TAG, "addr is null");
3046 VERIFY_NON_NULL(env, TAG, "env is null");
3048 ca_mutex_lock(g_gattObjectMutex);
3049 if (!g_gattObjectList)
3051 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3052 ca_mutex_unlock(g_gattObjectMutex);
3053 return CA_STATUS_OK;
3056 uint32_t length = u_arraylist_length(g_gattObjectList);
3057 for (uint32_t index = 0; index < length; index++)
3059 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3062 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3063 ca_mutex_unlock(g_gattObjectMutex);
3064 return CA_STATUS_FAILED;
3067 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3068 if (!jni_setAddress)
3070 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3071 ca_mutex_unlock(g_gattObjectMutex);
3072 return CA_STATUS_FAILED;
3075 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3078 OIC_LOG(ERROR, TAG, "setAddress is null");
3079 ca_mutex_unlock(g_gattObjectMutex);
3080 return CA_STATUS_FAILED;
3083 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3086 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3087 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3088 ca_mutex_unlock(g_gattObjectMutex);
3089 return CA_STATUS_FAILED;
3092 if (!strcmp(setAddress, remoteAddress))
3094 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3095 (*env)->DeleteGlobalRef(env, jarrayObj);
3097 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3098 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3099 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3101 OIC_LOG(ERROR, TAG, "List removal failed.");
3102 ca_mutex_unlock(g_gattObjectMutex);
3103 return CA_STATUS_FAILED;
3105 ca_mutex_unlock(g_gattObjectMutex);
3106 return CA_STATUS_OK;
3108 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3109 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3112 ca_mutex_unlock(g_gattObjectMutex);
3113 OIC_LOG(DEBUG, TAG, "there are no target object");
3114 return CA_STATUS_FAILED;
3117 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3119 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3121 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3122 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3124 // get Bluetooth Address
3125 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3126 if (!jni_btTargetAddress)
3128 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3132 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3135 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3139 // get method ID of getDevice()
3140 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3141 "getDevice", METHODID_BT_DEVICE);
3142 if (!jni_mid_getDevice)
3144 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3145 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3149 size_t length = u_arraylist_length(g_gattObjectList);
3150 for (size_t index = 0; index < length; index++)
3152 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3155 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3156 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3160 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3161 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3162 if (!jni_obj_device)
3164 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3165 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3169 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3172 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3173 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3177 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3180 OIC_LOG(ERROR, TAG, "btAddress is not available");
3181 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3185 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3186 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3187 if (!strcmp(targetAddress, btAddress))
3189 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3192 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3195 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3197 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3198 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3199 (*env)->DeleteLocalRef(env, jni_btAddress);
3200 (*env)->DeleteLocalRef(env, jni_obj_device);
3201 return jni_LEAddress;
3203 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3204 (*env)->DeleteLocalRef(env, jni_btAddress);
3205 (*env)->DeleteLocalRef(env, jni_obj_device);
3208 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3216 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3217 uint16_t notificationState, uint16_t sendState)
3219 VERIFY_NON_NULL(address, TAG, "address is null");
3221 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
3224 OIC_LOG(ERROR, TAG, "out of memory");
3225 return CA_MEMORY_ALLOC_FAILED;
3228 if (strlen(address) > CA_MACADDR_SIZE)
3230 OIC_LOG(ERROR, TAG, "address is not proper");
3232 return CA_STATUS_FAILED;
3235 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3236 newstate->connectedState = connectedState;
3237 newstate->notificationState = notificationState;
3238 newstate->sendState = sendState;
3239 return CALEClientAddDeviceStateToList(newstate);
3242 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3244 VERIFY_NON_NULL(state, TAG, "state is null");
3246 ca_mutex_lock(g_deviceStateListMutex);
3248 if (!g_deviceStateList)
3250 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3251 ca_mutex_unlock(g_deviceStateListMutex);
3252 return CA_STATUS_FAILED;
3255 if (CALEClientIsDeviceInList(state->address))
3257 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3260 OIC_LOG(ERROR, TAG, "curState is null");
3261 ca_mutex_unlock(g_deviceStateListMutex);
3262 return CA_STATUS_FAILED;
3265 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3267 state->notificationState = curState->notificationState;
3269 state->autoConnectFlag = curState->autoConnectFlag;
3271 // delete previous state for update new state
3272 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3273 if (CA_STATUS_OK != res)
3275 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3276 ca_mutex_unlock(g_deviceStateListMutex);
3280 u_arraylist_add(g_deviceStateList, state); // update new state
3281 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
3282 state->connectedState, state->notificationState,
3283 state->address, state->autoConnectFlag);
3285 ca_mutex_unlock(g_deviceStateListMutex);
3286 return CA_STATUS_OK;
3289 bool CALEClientIsDeviceInList(const char* remoteAddress)
3291 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3293 if (!g_deviceStateList)
3295 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3299 uint32_t length = u_arraylist_length(g_deviceStateList);
3300 for (uint32_t index = 0; index < length; index++)
3302 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3305 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3309 if (!strcmp(remoteAddress, state->address))
3311 OIC_LOG(DEBUG, TAG, "the device is already set");
3320 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3324 CAResult_t CALEClientRemoveAllDeviceState()
3326 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3328 ca_mutex_lock(g_deviceStateListMutex);
3329 if (!g_deviceStateList)
3331 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3332 ca_mutex_unlock(g_deviceStateListMutex);
3333 return CA_STATUS_FAILED;
3336 uint32_t length = u_arraylist_length(g_deviceStateList);
3337 for (uint32_t index = 0; index < length; index++)
3339 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3342 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3348 OICFree(g_deviceStateList);
3349 g_deviceStateList = NULL;
3350 ca_mutex_unlock(g_deviceStateListMutex);
3352 return CA_STATUS_OK;
3355 CAResult_t CALEClientResetDeviceStateForAll()
3357 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
3359 ca_mutex_lock(g_deviceStateListMutex);
3360 if (!g_deviceStateList)
3362 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3363 ca_mutex_unlock(g_deviceStateListMutex);
3364 return CA_STATUS_FAILED;
3367 size_t length = u_arraylist_length(g_deviceStateList);
3368 for (size_t index = 0; index < length; index++)
3370 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3373 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3377 // autoConnectFlag value will be not changed,
3378 // since it has reset only termination case.
3379 state->connectedState = STATE_DISCONNECTED;
3380 state->notificationState = STATE_CHARACTER_UNSET;
3381 state->sendState = STATE_SEND_NONE;
3383 ca_mutex_unlock(g_deviceStateListMutex);
3385 return CA_STATUS_OK;
3388 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3390 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3391 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3393 if (!g_deviceStateList)
3395 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3396 return CA_STATUS_FAILED;
3399 uint32_t length = u_arraylist_length(g_deviceStateList);
3400 for (uint32_t index = 0; index < length; index++)
3402 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3405 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3409 if (!strcmp(state->address, remoteAddress))
3411 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3413 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3415 if (NULL == targetState)
3417 OIC_LOG(ERROR, TAG, "List removal failed.");
3418 return CA_STATUS_FAILED;
3421 OICFree(targetState);
3422 return CA_STATUS_OK;
3426 return CA_STATUS_OK;
3429 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3431 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3432 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3434 if (!g_deviceStateList)
3436 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3440 uint32_t length = u_arraylist_length(g_deviceStateList);
3441 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3443 for (uint32_t index = 0; index < length; index++)
3445 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3448 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3452 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3453 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3455 if (!strcmp(state->address, remoteAddress))
3457 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3464 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3466 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3467 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3469 ca_mutex_lock(g_deviceStateListMutex);
3470 if (!g_deviceStateList)
3472 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3473 ca_mutex_unlock(g_deviceStateListMutex);
3477 uint32_t length = u_arraylist_length(g_deviceStateList);
3478 for (uint32_t index = 0; index < length; index++)
3480 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3483 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3487 if (!strcmp(state->address, remoteAddress))
3489 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3491 if (STATE_CONNECTED == state->connectedState)
3493 ca_mutex_unlock(g_deviceStateListMutex);
3498 ca_mutex_unlock(g_deviceStateListMutex);
3503 ca_mutex_unlock(g_deviceStateListMutex);
3507 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3509 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3510 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3512 ca_mutex_lock(g_deviceStateListMutex);
3513 if (!g_deviceStateList)
3515 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3516 ca_mutex_unlock(g_deviceStateListMutex);
3520 uint32_t length = u_arraylist_length(g_deviceStateList);
3521 for (uint32_t index = 0; index < length; index++)
3523 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3526 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3530 if (!strcmp(state->address, remoteAddress))
3532 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3534 if (STATE_CHARACTER_SET == state->notificationState)
3536 ca_mutex_unlock(g_deviceStateListMutex);
3541 ca_mutex_unlock(g_deviceStateListMutex);
3547 ca_mutex_unlock(g_deviceStateListMutex);
3551 void CALEClientCreateDeviceList()
3553 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3555 // create new object array
3556 if (!g_gattObjectList)
3558 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3560 g_gattObjectList = u_arraylist_create();
3563 if (!g_deviceStateList)
3565 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3567 g_deviceStateList = u_arraylist_create();
3572 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3574 g_deviceList = u_arraylist_create();
3579 * Check Sent Count for remove g_sendBuffer
3581 void CALEClientUpdateSendCnt(JNIEnv *env)
3583 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3585 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3587 ca_mutex_lock(g_threadMutex);
3591 if (g_targetCnt <= g_currentSentCnt)
3594 g_currentSentCnt = 0;
3598 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3599 g_sendBuffer = NULL;
3601 // notity the thread
3602 ca_cond_signal(g_threadCond);
3604 CALEClientSetSendFinishFlag(true);
3605 OIC_LOG(DEBUG, TAG, "set signal for send data");
3608 ca_mutex_unlock(g_threadMutex);
3611 CAResult_t CALEClientInitGattMutexVaraibles()
3613 if (NULL == g_bleReqRespClientCbMutex)
3615 g_bleReqRespClientCbMutex = ca_mutex_new();
3616 if (NULL == g_bleReqRespClientCbMutex)
3618 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3619 return CA_STATUS_FAILED;
3623 if (NULL == g_bleServerBDAddressMutex)
3625 g_bleServerBDAddressMutex = ca_mutex_new();
3626 if (NULL == g_bleServerBDAddressMutex)
3628 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3629 return CA_STATUS_FAILED;
3633 if (NULL == g_threadMutex)
3635 g_threadMutex = ca_mutex_new();
3636 if (NULL == g_threadMutex)
3638 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3639 return CA_STATUS_FAILED;
3643 if (NULL == g_threadSendMutex)
3645 g_threadSendMutex = ca_mutex_new();
3646 if (NULL == g_threadSendMutex)
3648 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3649 return CA_STATUS_FAILED;
3653 if (NULL == g_deviceListMutex)
3655 g_deviceListMutex = ca_mutex_new();
3656 if (NULL == g_deviceListMutex)
3658 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3659 return CA_STATUS_FAILED;
3663 if (NULL == g_gattObjectMutex)
3665 g_gattObjectMutex = ca_mutex_new();
3666 if (NULL == g_gattObjectMutex)
3668 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3669 return CA_STATUS_FAILED;
3673 if (NULL == g_deviceStateListMutex)
3675 g_deviceStateListMutex = ca_mutex_new();
3676 if (NULL == g_deviceStateListMutex)
3678 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3679 return CA_STATUS_FAILED;
3683 if (NULL == g_SendFinishMutex)
3685 g_SendFinishMutex = ca_mutex_new();
3686 if (NULL == g_SendFinishMutex)
3688 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3689 return CA_STATUS_FAILED;
3693 if (NULL == g_scanMutex)
3695 g_scanMutex = ca_mutex_new();
3696 if (NULL == g_scanMutex)
3698 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3699 return CA_STATUS_FAILED;
3703 if (NULL == g_threadWriteCharacteristicMutex)
3705 g_threadWriteCharacteristicMutex = ca_mutex_new();
3706 if (NULL == g_threadWriteCharacteristicMutex)
3708 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3709 return CA_STATUS_FAILED;
3713 if (NULL == g_deviceScanRetryDelayMutex)
3715 g_deviceScanRetryDelayMutex = ca_mutex_new();
3716 if (NULL == g_deviceScanRetryDelayMutex)
3718 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3719 return CA_STATUS_FAILED;
3723 return CA_STATUS_OK;
3726 void CALEClientTerminateGattMutexVariables()
3728 ca_mutex_free(g_bleReqRespClientCbMutex);
3729 g_bleReqRespClientCbMutex = NULL;
3731 ca_mutex_free(g_bleServerBDAddressMutex);
3732 g_bleServerBDAddressMutex = NULL;
3734 ca_mutex_free(g_threadMutex);
3735 g_threadMutex = NULL;
3737 ca_mutex_free(g_threadSendMutex);
3738 g_threadSendMutex = NULL;
3740 ca_mutex_free(g_deviceListMutex);
3741 g_deviceListMutex = NULL;
3743 ca_mutex_free(g_SendFinishMutex);
3744 g_SendFinishMutex = NULL;
3746 ca_mutex_free(g_scanMutex);
3749 ca_mutex_free(g_threadWriteCharacteristicMutex);
3750 g_threadWriteCharacteristicMutex = NULL;
3752 ca_mutex_free(g_deviceScanRetryDelayMutex);
3753 g_deviceScanRetryDelayMutex = NULL;
3756 void CALEClientSetSendFinishFlag(bool flag)
3758 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3760 ca_mutex_lock(g_SendFinishMutex);
3761 g_isFinishedSendData = flag;
3762 ca_mutex_unlock(g_SendFinishMutex);
3769 CAResult_t CAStartLEGattClient()
3771 // init mutex for send logic
3772 if (!g_deviceDescCond)
3774 g_deviceDescCond = ca_cond_new();
3779 g_threadCond = ca_cond_new();
3782 if (!g_threadWriteCharacteristicCond)
3784 g_threadWriteCharacteristicCond = ca_cond_new();
3787 CAResult_t ret = CALEClientStartScan();
3788 if (CA_STATUS_OK != ret)
3790 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3794 g_isStartedLEClient = true;
3795 return CA_STATUS_OK;
3798 void CAStopLEGattClient()
3800 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3804 OIC_LOG(ERROR, TAG, "g_jvm is null");
3808 bool isAttached = false;
3810 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3813 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3814 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3818 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3824 CAResult_t ret = CALEClientDisconnectAll(env);
3825 if (CA_STATUS_OK != ret)
3827 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3830 ret = CALEClientStopScan();
3831 if(CA_STATUS_OK != ret)
3833 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3836 ca_mutex_lock(g_threadMutex);
3837 OIC_LOG(DEBUG, TAG, "signal - connection cond");
3838 ca_cond_signal(g_threadCond);
3839 CALEClientSetSendFinishFlag(true);
3840 ca_mutex_unlock(g_threadMutex);
3842 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3843 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
3844 ca_cond_signal(g_threadWriteCharacteristicCond);
3845 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3847 ca_mutex_lock(g_deviceScanRetryDelayMutex);
3848 OIC_LOG(DEBUG, TAG, "signal - delay cond");
3849 ca_cond_signal(g_deviceScanRetryDelayCond);
3850 ca_mutex_unlock(g_deviceScanRetryDelayMutex);
3852 ca_cond_free(g_deviceDescCond);
3853 ca_cond_free(g_threadCond);
3854 ca_cond_free(g_threadWriteCharacteristicCond);
3855 ca_cond_free(g_deviceScanRetryDelayCond);
3857 g_deviceDescCond = NULL;
3858 g_threadCond = NULL;
3859 g_threadWriteCharacteristicCond = NULL;
3860 g_deviceScanRetryDelayCond = NULL;
3864 (*g_jvm)->DetachCurrentThread(g_jvm);
3869 CAResult_t CAInitializeLEGattClient()
3871 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3872 CALEClientInitialize();
3873 return CA_STATUS_OK;
3876 void CATerminateLEGattClient()
3878 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3879 CAStopLEGattClient();
3880 CALEClientTerminate();
3883 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3884 uint32_t dataLen, CALETransferType_t type,
3887 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3888 VERIFY_NON_NULL(data, TAG, "data is null");
3889 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3891 if (LE_UNICAST != type || position < 0)
3893 OIC_LOG(ERROR, TAG, "this request is not unicast");
3894 return CA_STATUS_INVALID_PARAM;
3897 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3900 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3902 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3903 VERIFY_NON_NULL(data, TAG, "data is null");
3905 return CALEClientSendMulticastMessage(data, dataLen);
3908 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3910 ca_mutex_lock(g_bleReqRespClientCbMutex);
3911 g_CABLEClientDataReceivedCallback = callback;
3912 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3915 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3917 g_threadPoolHandle = handle;
3920 CAResult_t CAGetLEAddress(char **local_address)
3922 VERIFY_NON_NULL(local_address, TAG, "local_address");
3923 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3924 return CA_NOT_SUPPORTED;
3927 JNIEXPORT void JNICALL
3928 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3931 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3932 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3933 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3934 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3936 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3939 JNIEXPORT void JNICALL
3940 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3943 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3944 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3945 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3946 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3948 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3951 JNIEXPORT void JNICALL
3952 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3955 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3956 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3957 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3959 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3960 if (CA_STATUS_OK != res)
3962 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3966 static jstring CALEClientGetAddressFromGatt(JNIEnv *env, jobject gatt)
3968 OIC_LOG(DEBUG, TAG, "IN - CAManagerGetAddressFromGatt");
3970 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
3971 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
3973 jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
3974 "getDevice", METHODID_BT_DEVICE);
3975 if (!jni_mid_getDevice)
3977 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3981 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
3982 if (!jni_obj_device)
3984 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3988 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
3991 OIC_LOG(ERROR, TAG, "jni_address is null");
3995 OIC_LOG(DEBUG, TAG, "OUT - CAManagerGetAddressFromGatt");
4000 * Class: org_iotivity_ca_jar_caleinterface
4001 * Method: CALeGattConnectionStateChangeCallback
4002 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
4004 JNIEXPORT void JNICALL
4005 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
4011 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
4013 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4014 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4015 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4017 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
4018 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
4019 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4021 if (gatt_success == status && state_connected == newstate) // le connected
4023 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4029 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4032 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4033 STATE_CHARACTER_NO_CHANGE,
4035 if (CA_STATUS_OK != res)
4037 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4038 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4041 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4043 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4046 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
4047 if (CA_STATUS_OK != res)
4049 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
4053 res = CALEClientDiscoverServices(env, gatt);
4054 if (CA_STATUS_OK != res)
4056 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
4060 else if (state_disconnected == newstate) // le disconnected
4062 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4065 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
4069 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4072 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
4073 STATE_CHARACTER_UNSET,
4075 if (CA_STATUS_OK != res)
4077 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4078 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4081 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
4083 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4086 CAResult_t res = CALEClientGattClose(env, gatt);
4087 if (CA_STATUS_OK != res)
4089 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
4092 if (GATT_ERROR == status)
4094 // when we get GATT ERROR(0x85), gatt connection can be called again.
4095 OIC_LOG(INFO, TAG, "retry gatt connect");
4097 jstring leAddress = CALEClientGetAddressFromGatt(env, gatt);
4100 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGatt has failed");
4104 jobject btObject = CALEGetRemoteDevice(env, leAddress);
4107 OIC_LOG(ERROR, TAG, "CALEGetRemoteDevice has failed");
4111 jobject newGatt = CALEClientConnect(env, btObject, JNI_TRUE);
4114 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
4122 if (CALECheckConnectionStateValue(status))
4124 // this state is unexpected reason to disconnect
4125 // if the reason is suitable, connection logic of the device will be destroyed.
4126 OIC_LOG(INFO, TAG, "connection logic destroy");
4131 // other reason except for gatt_success is expected to running
4132 // background connection in BT platform.
4133 OIC_LOG(INFO, TAG, "unknown state or manual disconnected state");
4134 CALEClientUpdateSendCnt(env);
4141 (*env)->DeleteGlobalRef(env, g_sendBuffer);
4142 g_sendBuffer = NULL;
4150 CALEClientSendFinish(env, gatt);
4155 * Class: org_iotivity_ca_jar_caleinterface
4156 * Method: CALeGattServicesDiscoveredCallback
4157 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4159 JNIEXPORT void JNICALL
4160 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4165 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4166 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4167 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4168 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4170 if (0 != status) // discovery error
4172 CALEClientSendFinish(env, gatt);
4176 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4179 CALEClientSendFinish(env, gatt);
4183 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4186 CALEClientSendFinish(env, gatt);
4190 if (!CALEClientIsSetCharacteristic(address))
4192 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4195 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4199 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4200 if (!jni_obj_GattCharacteristic)
4202 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4206 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4207 jni_obj_GattCharacteristic);
4208 if (CA_STATUS_OK != res)
4210 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4214 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4215 if (CA_STATUS_OK != res)
4217 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4220 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4221 if (CA_STATUS_OK != res)
4223 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4229 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4231 if (CA_STATUS_OK != res)
4233 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4241 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4242 if (CA_STATUS_OK != res)
4244 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4249 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4250 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4255 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4256 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4257 CALEClientSendFinish(env, gatt);
4262 * Class: org_iotivity_ca_jar_caleinterface
4263 * Method: CALeGattCharacteristicWritjclasseCallback
4264 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4266 JNIEXPORT void JNICALL
4267 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4268 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4271 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4272 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4273 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4274 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4276 // send success & signal
4277 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4283 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4289 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4290 if (gatt_success != status) // error case
4292 OIC_LOG(ERROR, TAG, "send failure");
4295 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4296 if (CA_STATUS_OK != res)
4298 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4299 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4300 g_isSignalSetFlag = true;
4301 ca_cond_signal(g_threadWriteCharacteristicCond);
4302 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4304 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4305 STATE_CHARACTER_SET,
4307 if (CA_STATUS_OK != res)
4309 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4312 if (g_clientErrorCallback)
4314 jint length = (*env)->GetArrayLength(env, data);
4315 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4318 CALEClientSendFinish(env, gatt);
4324 OIC_LOG(DEBUG, TAG, "send success");
4325 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4326 STATE_SEND_SUCCESS);
4327 if (CA_STATUS_OK != res)
4329 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4332 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4333 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4334 g_isSignalSetFlag = true;
4335 ca_cond_signal(g_threadWriteCharacteristicCond);
4336 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4338 CALEClientUpdateSendCnt(env);
4341 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4347 CALEClientSendFinish(env, gatt);
4352 * Class: org_iotivity_ca_jar_caleinterface
4353 * Method: CALeGattCharacteristicChangedCallback
4354 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4356 JNIEXPORT void JNICALL
4357 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4358 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4360 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4361 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4362 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4363 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4364 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4366 // get Byte Array and convert to uint8_t*
4367 jint length = (*env)->GetArrayLength(env, data);
4370 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4372 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4373 jni_byte_responseData);
4375 uint8_t* receivedData = OICMalloc(length);
4378 OIC_LOG(ERROR, TAG, "receivedData is null");
4382 memcpy(receivedData, jni_byte_responseData, length);
4383 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4385 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4388 OIC_LOG(ERROR, TAG, "jni_address is null");
4389 OICFree(receivedData);
4393 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4396 OIC_LOG(ERROR, TAG, "address is null");
4397 OICFree(receivedData);
4401 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4402 receivedData, length);
4404 ca_mutex_lock(g_bleServerBDAddressMutex);
4405 uint32_t sentLength = 0;
4406 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4408 ca_mutex_unlock(g_bleServerBDAddressMutex);
4410 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4414 * Class: org_iotivity_ca_jar_caleinterface
4415 * Method: CALeGattDescriptorWriteCallback
4416 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4418 JNIEXPORT void JNICALL
4419 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4423 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4424 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4425 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4426 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4428 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4429 if (gatt_success != status) // error
4436 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4437 if (CA_STATUS_OK != res)
4439 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4448 CALEClientSendFinish(env, gatt);