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("CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
44 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
45 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
46 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
47 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
50 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
51 static u_arraylist_t *g_gattObjectList = NULL;
52 static u_arraylist_t *g_deviceStateList = NULL;
54 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
55 static CABLEErrorHandleCallback g_clientErrorCallback;
56 static ca_thread_pool_t g_threadPoolHandle = NULL;
57 static jobject g_leScanCallback = NULL;
58 static jobject g_leGattCallback = NULL;
59 static jobject g_context = NULL;
60 static jobjectArray g_uuidList = NULL;
62 // it will be prevent to start send logic when adapter has stopped.
63 static bool g_isStartedLEClient = false;
64 static bool g_isStartedMulticastServer = false;
65 static bool g_isStartedScan = false;
67 static jbyteArray g_sendBuffer = NULL;
68 static uint32_t g_targetCnt = 0;
69 static uint32_t g_currentSentCnt = 0;
70 static bool g_isFinishedSendData = false;
71 static ca_mutex g_SendFinishMutex = NULL;
72 static ca_mutex g_threadMutex = NULL;
73 static ca_cond g_threadCond = NULL;
74 static ca_cond g_deviceDescCond = NULL;
76 static ca_mutex g_threadSendMutex = NULL;
78 static ca_mutex g_bleReqRespClientCbMutex = NULL;
79 static ca_mutex g_bleServerBDAddressMutex = NULL;
81 static ca_mutex g_deviceListMutex = NULL;
82 static ca_mutex g_gattObjectMutex = NULL;
83 static ca_mutex g_deviceStateListMutex = NULL;
85 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
88 void CALEClientJniInit()
90 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
91 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
94 void CALEClientJNISetContext()
96 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
97 g_context = (jobject) CANativeJNIGetContext();
100 CAResult_t CALECreateJniInterfaceObject()
102 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
106 OIC_LOG(ERROR, TAG, "g_context is null");
107 return CA_STATUS_FAILED;
112 OIC_LOG(ERROR, TAG, "g_jvm is null");
113 return CA_STATUS_FAILED;
116 bool isAttached = false;
118 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
121 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
122 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
126 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
127 return CA_STATUS_FAILED;
132 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
133 if (!jni_LEInterface)
135 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
139 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
140 "(Landroid/content/Context;)V");
141 if (!LeInterfaceConstructorMethod)
143 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
147 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
148 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
152 (*g_jvm)->DetachCurrentThread(g_jvm);
161 (*g_jvm)->DetachCurrentThread(g_jvm);
164 return CA_STATUS_FAILED;
167 CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
169 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
175 OIC_LOG(ERROR, TAG, "g_jvm is null");
176 return CA_STATUS_FAILED;
179 bool isAttached = false;
181 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
184 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
185 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
189 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
190 return CA_STATUS_FAILED;
195 CAResult_t ret = CALECheckPlatformVersion(env, 18);
196 if (CA_STATUS_OK != ret)
198 OIC_LOG(ERROR, TAG, "it is not supported");
202 (*g_jvm)->DetachCurrentThread(g_jvm);
208 g_threadPoolHandle = handle;
210 ret = CALEClientInitGattMutexVaraibles();
211 if (CA_STATUS_OK != ret)
213 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
214 CALEClientTerminateGattMutexVariables();
218 (*g_jvm)->DetachCurrentThread(g_jvm);
224 g_deviceDescCond = ca_cond_new();
226 // init mutex for send logic
227 g_threadCond = ca_cond_new();
229 CALEClientCreateDeviceList();
230 CALEClientJNISetContext();
232 ret = CALEClientCreateUUIDList();
233 if (CA_STATUS_OK != ret)
235 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
239 (*g_jvm)->DetachCurrentThread(g_jvm);
245 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
246 if (CA_STATUS_OK != ret)
248 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
252 (*g_jvm)->DetachCurrentThread(g_jvm);
257 g_isStartedLEClient = true;
261 (*g_jvm)->DetachCurrentThread(g_jvm);
267 void CALEClientTerminate()
269 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
273 OIC_LOG(ERROR, TAG, "g_jvm is null");
277 bool isAttached = false;
279 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
282 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
283 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
287 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
293 if (g_leScanCallback)
295 (*env)->DeleteGlobalRef(env, g_leScanCallback);
298 if (g_leGattCallback)
300 (*env)->DeleteGlobalRef(env, g_leGattCallback);
305 (*env)->DeleteGlobalRef(env, g_sendBuffer);
310 (*env)->DeleteGlobalRef(env, g_uuidList);
313 CAResult_t ret = CALEClientRemoveAllDeviceState();
314 if (CA_STATUS_OK != ret)
316 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
319 ret = CALEClientRemoveAllScanDevices(env);
320 if (CA_STATUS_OK != ret)
322 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
325 ret = CALEClientRemoveAllGattObjs(env);
326 if (CA_STATUS_OK != ret)
328 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
331 g_isStartedMulticastServer = false;
332 g_isStartedScan = false;
333 CALEClientSetSendFinishFlag(false);
335 CALEClientTerminateGattMutexVariables();
337 ca_cond_free(g_deviceDescCond);
338 ca_cond_free(g_threadCond);
340 g_deviceDescCond = NULL;
345 (*g_jvm)->DetachCurrentThread(g_jvm);
349 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
351 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
352 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
356 CAResult_t res = CALEClientDisconnect(env, gatt);
357 if (CA_STATUS_OK != res)
359 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
362 CALEClientUpdateSendCnt(env);
365 CAResult_t CALEClientSendUnicastMessage(const char* address,
367 const uint32_t dataLen)
369 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
370 VERIFY_NON_NULL(address, TAG, "address is null");
371 VERIFY_NON_NULL(data, TAG, "data is null");
373 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
376 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
377 const uint32_t dataLen)
379 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
380 VERIFY_NON_NULL(data, TAG, "data is null");
384 OIC_LOG(ERROR, TAG, "g_jvm is null");
385 return CA_STATUS_FAILED;
388 bool isAttached = false;
390 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
393 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
394 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
398 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
399 return CA_STATUS_FAILED;
404 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
405 if (CA_STATUS_OK != ret)
407 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
412 (*g_jvm)->DetachCurrentThread(g_jvm);
418 CAResult_t CALEClientStartUnicastServer(const char* address)
420 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
422 return CA_NOT_SUPPORTED;
425 CAResult_t CALEClientStartMulticastServer()
427 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
429 if (g_isStartedMulticastServer)
431 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
432 return CA_STATUS_FAILED;
437 OIC_LOG(ERROR, TAG, "g_jvm is null");
438 return CA_STATUS_FAILED;
441 bool isAttached = false;
443 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
446 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
447 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
451 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
452 return CA_STATUS_FAILED;
457 g_isStartedMulticastServer = true;
458 CAResult_t ret = CALEClientStartScan();
459 if (CA_STATUS_OK != ret)
461 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
466 (*g_jvm)->DetachCurrentThread(g_jvm);
472 void CALEClientStopUnicastServer()
474 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
477 void CALEClientStopMulticastServer()
479 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
480 g_isStartedMulticastServer = false;
481 CAResult_t res = CALEClientStopScan();
482 if (CA_STATUS_OK != res)
484 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
489 void CALEClientSetCallback(CAPacketReceiveCallback callback)
491 g_packetReceiveCallback = callback;
494 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
496 g_clientErrorCallback = callback;
499 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
500 const uint32_t dataLen)
502 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
504 VERIFY_NON_NULL(address, TAG, "address is null");
505 VERIFY_NON_NULL(data, TAG, "data is null");
509 OIC_LOG(ERROR, TAG, "g_jvm is null");
510 return CA_STATUS_FAILED;
513 bool isAttached = false;
515 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
518 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
519 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
522 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
523 return CA_STATUS_FAILED;
528 ca_mutex_lock(g_threadSendMutex);
530 CAResult_t ret = CA_STATUS_OK;
531 if (g_context && g_deviceList)
533 uint32_t length = u_arraylist_length(g_deviceList);
534 for (uint32_t index = 0; index < length; index++)
536 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
539 OIC_LOG(ERROR, TAG, "jarrayObj is null");
543 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
546 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
550 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
553 OIC_LOG(ERROR, TAG, "setAddress is null");
557 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
559 if (!strcmp(setAddress, address))
561 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
563 // connect to gatt server
564 ret = CALEClientStopScan();
565 if (CA_STATUS_OK != ret)
567 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
573 (*env)->DeleteGlobalRef(env, g_sendBuffer);
575 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
576 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
577 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
579 ret = CALEClientSendData(env, jarrayObj);
580 if (CA_STATUS_OK != ret)
582 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
586 OIC_LOG(INFO, TAG, "wake up");
589 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
595 (*g_jvm)->DetachCurrentThread(g_jvm);
598 // start LE Scan again
599 ret = CALEClientStartScan();
600 if (CA_STATUS_OK != ret)
602 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
603 ca_mutex_unlock(g_threadSendMutex);
607 ca_mutex_unlock(g_threadSendMutex);
608 OIC_LOG(INFO, TAG, "unicast - send success");
614 // start LE Scan again
615 ret = CALEClientStartScan();
616 if (CA_STATUS_OK != ret)
618 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
619 ca_mutex_unlock(g_threadSendMutex);
622 (*g_jvm)->DetachCurrentThread(g_jvm);
629 (*g_jvm)->DetachCurrentThread(g_jvm);
632 if (g_clientErrorCallback)
634 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
636 ca_mutex_unlock(g_threadSendMutex);
637 return CA_SEND_FAILED;
640 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
641 const uint32_t dataLen)
643 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
644 VERIFY_NON_NULL(data, TAG, "data is null");
645 VERIFY_NON_NULL(env, TAG, "env is null");
649 OIC_LOG(ERROR, TAG, "g_deviceList is null");
650 return CA_STATUS_FAILED;
653 ca_mutex_lock(g_threadSendMutex);
655 CALEClientSetSendFinishFlag(false);
657 OIC_LOG(DEBUG, TAG, "set byteArray for data");
660 (*env)->DeleteGlobalRef(env, g_sendBuffer);
663 if (0 == u_arraylist_length(g_deviceList))
665 // Wait for LE peripherals to be discovered.
667 // Number of times to wait for discovery to complete.
668 static size_t const RETRIES = 5;
670 static uint64_t const TIMEOUT =
671 2 * MICROSECS_PER_SEC; // Microseconds
673 bool devicesDiscovered = false;
675 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
678 if (ca_cond_wait_for(g_deviceDescCond,
682 devicesDiscovered = true;
686 if (!devicesDiscovered)
692 // connect to gatt server
693 CAResult_t res = CALEClientStopScan();
694 if (CA_STATUS_OK != res)
696 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
697 ca_mutex_unlock(g_threadSendMutex);
700 uint32_t length = u_arraylist_length(g_deviceList);
701 g_targetCnt = length;
703 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
704 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
705 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
707 for (uint32_t index = 0; index < length; index++)
709 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
712 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
716 res = CALEClientSendData(env, jarrayObj);
717 if (res != CA_STATUS_OK)
719 OIC_LOG(ERROR, TAG, "BT device - send has failed");
722 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
725 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
729 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
732 OIC_LOG(ERROR, TAG, "address is not available");
736 (*env)->ReleaseStringUTFChars(env, jni_address, address);
739 OIC_LOG(DEBUG, TAG, "connection routine is finished");
741 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
742 if (!g_isFinishedSendData)
744 ca_mutex_lock(g_threadMutex);
745 ca_cond_wait(g_threadCond, g_threadMutex);
746 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
747 ca_mutex_unlock(g_threadMutex);
750 // start LE Scan again
751 res = CALEClientStartScan();
752 if (CA_STATUS_OK != res)
754 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
755 ca_mutex_unlock(g_threadSendMutex);
759 ca_mutex_unlock(g_threadSendMutex);
760 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
764 res = CALEClientStartScan();
765 if (CA_STATUS_OK != res)
767 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
768 ca_mutex_unlock(g_threadSendMutex);
772 ca_mutex_unlock(g_threadSendMutex);
773 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
774 return CA_SEND_FAILED;
777 CAResult_t CALECheckSendState(const char* address)
779 VERIFY_NON_NULL(address, TAG, "address is null");
781 ca_mutex_lock(g_deviceStateListMutex);
782 CALEState_t* state = CALEClientGetStateInfo(address);
785 OIC_LOG(ERROR, TAG, "state is null");
786 ca_mutex_unlock(g_deviceStateListMutex);
787 return CA_SEND_FAILED;
790 if (STATE_SEND_SUCCESS != state->sendState)
792 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
793 ca_mutex_unlock(g_deviceStateListMutex);
794 return CA_SEND_FAILED;
796 ca_mutex_unlock(g_deviceStateListMutex);
800 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
802 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
803 VERIFY_NON_NULL(device, TAG, "device is null");
804 VERIFY_NON_NULL(env, TAG, "env is null");
806 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
809 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
810 return CA_STATUS_FAILED;
813 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
816 OIC_LOG(ERROR, TAG, "address is not available");
817 return CA_STATUS_FAILED;
820 ca_mutex_lock(g_deviceStateListMutex);
821 CALEState_t* state = CALEClientGetStateInfo(address);
822 ca_mutex_unlock(g_deviceStateListMutex);
825 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
826 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
827 if (CA_STATUS_OK != ret)
829 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
830 (*env)->ReleaseStringUTFChars(env, jni_address, address);
836 if (STATE_CONNECTED == state->connectedState)
838 OIC_LOG(INFO, TAG, "GATT has already connected");
839 jobject gatt = CALEClientGetGattObjInList(env, address);
842 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
843 (*env)->ReleaseStringUTFChars(env, jni_address, address);
844 return CA_STATUS_FAILED;
847 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
848 if (CA_STATUS_OK != ret)
850 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
851 (*env)->ReleaseStringUTFChars(env, jni_address, address);
857 OIC_LOG(DEBUG, TAG, "start to connect LE");
858 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
859 if (CA_STATUS_OK != ret)
861 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
862 (*env)->ReleaseStringUTFChars(env, jni_address, address);
868 (*env)->ReleaseStringUTFChars(env, jni_address, address);
872 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
874 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
875 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
877 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
878 if (!jni_cid_gattdevice_list)
880 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
884 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
885 "()Landroid/bluetooth/BluetoothDevice;");
886 if (!jni_mid_getDevice)
888 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
892 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
895 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
899 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
902 OIC_LOG(ERROR, TAG, "jni_address is null");
912 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
915 OIC_LOG(DEBUG, TAG, "Gatt Close");
916 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
917 VERIFY_NON_NULL(env, TAG, "env is null");
919 // get BluetoothGatt class
920 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
921 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
922 if (!jni_cid_BluetoothGatt)
924 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
925 return CA_STATUS_FAILED;
928 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
929 if (!jni_mid_closeGatt)
931 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
935 // call disconnect gatt method
936 OIC_LOG(DEBUG, TAG, "request to close GATT");
937 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
939 if ((*env)->ExceptionCheck(env))
941 OIC_LOG(ERROR, TAG, "closeGATT has failed");
942 (*env)->ExceptionDescribe(env);
943 (*env)->ExceptionClear(env);
944 return CA_STATUS_FAILED;
950 CAResult_t CALEClientStartScan()
952 if (!g_isStartedMulticastServer)
954 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
955 return CA_STATUS_FAILED;
958 if (!g_isStartedLEClient)
960 OIC_LOG(ERROR, TAG, "LE client is not started");
961 return CA_STATUS_FAILED;
966 OIC_LOG(ERROR, TAG, "g_jvm is null");
967 return CA_STATUS_FAILED;
972 OIC_LOG(INFO, TAG, "scanning is already started");
976 bool isAttached = false;
978 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
981 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
983 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
986 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
987 return CA_STATUS_FAILED;
992 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
994 CAResult_t ret = CA_STATUS_OK;
995 // scan gatt server with UUID
996 if (g_leScanCallback && g_uuidList)
999 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1000 if(CA_STATUS_OK != ret)
1002 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
1005 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1006 if (CA_STATUS_OK != ret)
1008 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
1015 (*g_jvm)->DetachCurrentThread(g_jvm);
1021 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1023 VERIFY_NON_NULL(callback, TAG, "callback is null");
1024 VERIFY_NON_NULL(env, TAG, "env is null");
1026 if (!CALEIsEnableBTAdapter(env))
1028 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1029 return CA_ADAPTER_NOT_ENABLED;
1032 // get default bt adapter class
1033 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1034 if (!jni_cid_BTAdapter)
1036 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1037 return CA_STATUS_FAILED;
1040 // get remote bt adapter method
1041 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1042 "getDefaultAdapter",
1043 METHODID_OBJECTNONPARAM);
1044 if (!jni_mid_getDefaultAdapter)
1046 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1047 return CA_STATUS_FAILED;
1050 // get start le scan method
1051 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1052 "(Landroid/bluetooth/BluetoothAdapter$"
1053 "LeScanCallback;)Z");
1054 if (!jni_mid_startLeScan)
1056 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1057 return CA_STATUS_FAILED;
1060 // gat bt adapter object
1061 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1062 jni_mid_getDefaultAdapter);
1063 if (!jni_obj_BTAdapter)
1065 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1066 return CA_STATUS_FAILED;
1069 // call start le scan method
1070 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1071 jni_mid_startLeScan, callback);
1072 if (!jni_obj_startLeScan)
1074 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1075 return CA_STATUS_FAILED;
1079 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1080 g_isStartedScan = true;
1083 return CA_STATUS_OK;
1086 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1088 VERIFY_NON_NULL(callback, TAG, "callback is null");
1089 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1090 VERIFY_NON_NULL(env, TAG, "env is null");
1092 if (!CALEIsEnableBTAdapter(env))
1094 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1095 return CA_ADAPTER_NOT_ENABLED;
1098 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1099 if (!jni_cid_BTAdapter)
1101 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1102 return CA_STATUS_FAILED;
1105 // get remote bt adapter method
1106 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1107 "getDefaultAdapter",
1108 METHODID_OBJECTNONPARAM);
1109 if (!jni_mid_getDefaultAdapter)
1111 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1112 return CA_STATUS_FAILED;
1115 // get start le scan method
1116 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1117 "([Ljava/util/UUID;Landroid/bluetooth/"
1118 "BluetoothAdapter$LeScanCallback;)Z");
1119 if (!jni_mid_startLeScan)
1121 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1122 return CA_STATUS_FAILED;
1125 // get bt adapter object
1126 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1127 jni_mid_getDefaultAdapter);
1128 if (!jni_obj_BTAdapter)
1130 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1131 return CA_STATUS_FAILED;
1134 // call start le scan method
1135 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1136 jni_mid_startLeScan, uuids, callback);
1137 if (!jni_obj_startLeScan)
1139 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1140 return CA_STATUS_FAILED;
1144 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1145 g_isStartedScan = true;
1148 return CA_STATUS_OK;
1151 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1153 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1154 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1157 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1160 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1164 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1165 "(Ljava/lang/String;)"
1166 "Ljava/util/UUID;");
1167 if (!jni_mid_fromString)
1169 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1173 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1174 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1178 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1182 return jni_obj_uuid;
1185 CAResult_t CALEClientStopScan()
1189 OIC_LOG(ERROR, TAG, "g_jvm is null");
1190 return CA_STATUS_FAILED;
1193 if (!g_isStartedScan)
1195 OIC_LOG(INFO, TAG, "scanning is already stopped");
1196 return CA_STATUS_OK;
1199 bool isAttached = false;
1201 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1204 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1205 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1208 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1209 return CA_STATUS_FAILED;
1214 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1215 if (CA_STATUS_OK != ret)
1217 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1221 g_isStartedScan = false;
1226 (*g_jvm)->DetachCurrentThread(g_jvm);
1232 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1234 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1235 VERIFY_NON_NULL(callback, TAG, "callback is null");
1236 VERIFY_NON_NULL(env, TAG, "env is null");
1238 if (!CALEIsEnableBTAdapter(env))
1240 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1241 return CA_ADAPTER_NOT_ENABLED;
1244 // get default bt adapter class
1245 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1246 if (!jni_cid_BTAdapter)
1248 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1249 return CA_STATUS_FAILED;
1252 // get remote bt adapter method
1253 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1254 "getDefaultAdapter",
1255 METHODID_OBJECTNONPARAM);
1256 if (!jni_mid_getDefaultAdapter)
1258 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1259 return CA_STATUS_FAILED;
1262 // get start le scan method
1263 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1264 "(Landroid/bluetooth/"
1265 "BluetoothAdapter$LeScanCallback;)V");
1266 if (!jni_mid_stopLeScan)
1268 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1269 return CA_STATUS_FAILED;
1272 // gat bt adapter object
1273 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1274 jni_mid_getDefaultAdapter);
1275 if (!jni_obj_BTAdapter)
1277 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1278 return CA_STATUS_FAILED;
1281 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1282 // call start le scan method
1283 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1284 if ((*env)->ExceptionCheck(env))
1286 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1287 (*env)->ExceptionDescribe(env);
1288 (*env)->ExceptionClear(env);
1289 return CA_STATUS_FAILED;
1292 return CA_STATUS_OK;
1295 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1298 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1299 VERIFY_NON_NULL(env, TAG, "env is null");
1300 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1301 VERIFY_NON_NULL(callback, TAG, "callback is null");
1303 if (!CALEIsEnableBTAdapter(env))
1305 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1306 return CA_ADAPTER_NOT_ENABLED;
1309 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1312 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1313 return CA_STATUS_FAILED;
1316 // get BluetoothDevice class
1317 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1318 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1319 if (!jni_cid_BluetoothDevice)
1321 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1322 return CA_STATUS_FAILED;
1325 // get connectGatt method
1326 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1327 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1328 "(Landroid/content/Context;ZLandroid/"
1329 "bluetooth/BluetoothGattCallback;)"
1330 "Landroid/bluetooth/BluetoothGatt;");
1331 if (!jni_mid_connectGatt)
1333 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1334 return CA_STATUS_FAILED;
1337 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1338 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1339 jni_mid_connectGatt,
1341 autoconnect, callback);
1342 if (!jni_obj_connectGatt)
1344 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1345 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1346 CALEClientUpdateSendCnt(env);
1347 return CA_STATUS_FAILED;
1351 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1353 return CA_STATUS_OK;
1356 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1358 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1359 VERIFY_NON_NULL(env, TAG, "env is null");
1360 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1362 if (!CALEIsEnableBTAdapter(env))
1364 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1365 return CA_ADAPTER_NOT_ENABLED;
1368 // get BluetoothGatt class
1369 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1370 if (!jni_cid_BluetoothGatt)
1372 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1373 return CA_STATUS_FAILED;
1376 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1377 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1378 "disconnect", "()V");
1379 if (!jni_mid_disconnectGatt)
1381 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1382 return CA_STATUS_FAILED;
1385 // call disconnect gatt method
1386 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1387 if ((*env)->ExceptionCheck(env))
1389 OIC_LOG(ERROR, TAG, "disconnect has failed");
1390 (*env)->ExceptionDescribe(env);
1391 (*env)->ExceptionClear(env);
1392 return CA_STATUS_FAILED;
1395 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1397 return CA_STATUS_OK;
1400 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1402 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1403 VERIFY_NON_NULL(env, TAG, "env is null");
1405 if (!g_gattObjectList)
1407 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1408 return CA_STATUS_FAILED;
1411 uint32_t length = u_arraylist_length(g_gattObjectList);
1412 for (uint32_t index = 0; index < length; index++)
1414 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1417 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1420 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1421 if (CA_STATUS_OK != res)
1423 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1428 OICFree(g_gattObjectList);
1429 g_gattObjectList = NULL;
1431 return CA_STATUS_OK;
1434 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1436 VERIFY_NON_NULL(env, TAG, "env is null");
1437 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1439 if (!CALEIsEnableBTAdapter(env))
1441 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1442 return CA_ADAPTER_NOT_ENABLED;
1445 // get BluetoothGatt class
1446 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1447 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1448 if (!jni_cid_BluetoothGatt)
1450 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1451 return CA_STATUS_FAILED;
1454 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1455 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1456 "discoverServices", "()Z");
1457 if (!jni_mid_discoverServices)
1459 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1460 return CA_STATUS_FAILED;
1462 // call disconnect gatt method
1463 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1464 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1467 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1468 return CA_STATUS_FAILED;
1471 return CA_STATUS_OK;
1474 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1476 VERIFY_NON_NULL(env, TAG, "env is null");
1477 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1480 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1481 if (!jni_obj_character)
1483 CALEClientSendFinish(env, gatt);
1484 return CA_STATUS_FAILED;
1487 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1488 if (CA_STATUS_OK != ret)
1490 CALEClientSendFinish(env, gatt);
1494 return CA_STATUS_OK;
1497 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1498 jobject gattCharacteristic)
1500 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1501 VERIFY_NON_NULL(env, TAG, "env is null");
1502 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1503 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1505 if (!CALEIsEnableBTAdapter(env))
1507 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1508 return CA_STATUS_FAILED;
1511 // get BluetoothGatt class
1512 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1513 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1514 if (!jni_cid_BluetoothGatt)
1516 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1517 return CA_STATUS_FAILED;
1520 OIC_LOG(DEBUG, TAG, "write characteristic method");
1521 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1522 "writeCharacteristic",
1523 "(Landroid/bluetooth/"
1524 "BluetoothGattCharacteristic;)Z");
1525 if (!jni_mid_writeCharacteristic)
1527 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1528 return CA_STATUS_FAILED;
1531 // call disconnect gatt method
1532 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1533 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1534 jni_mid_writeCharacteristic,
1535 gattCharacteristic);
1538 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1542 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1543 return CA_STATUS_FAILED;
1546 return CA_STATUS_OK;
1549 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1551 VERIFY_NON_NULL(env, TAG, "env is null");
1552 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1554 if (!CALEIsEnableBTAdapter(env))
1556 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1557 return CA_STATUS_FAILED;
1560 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1561 if (!jni_cid_BluetoothGatt)
1563 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1564 return CA_STATUS_FAILED;
1567 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1570 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1571 return CA_STATUS_FAILED;
1574 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1575 if (!jni_obj_GattCharacteristic)
1577 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1578 return CA_STATUS_FAILED;
1581 OIC_LOG(DEBUG, TAG, "read characteristic method");
1582 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1583 "readCharacteristic",
1584 "(Landroid/bluetooth/"
1585 "BluetoothGattCharacteristic;)Z");
1586 if (!jni_mid_readCharacteristic)
1588 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1589 return CA_STATUS_FAILED;
1592 // call disconnect gatt method
1593 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1594 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1595 jni_obj_GattCharacteristic);
1598 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1602 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1603 return CA_STATUS_FAILED;
1606 return CA_STATUS_OK;
1609 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1610 jobject characteristic)
1612 VERIFY_NON_NULL(env, TAG, "env is null");
1613 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1614 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1616 if (!CALEIsEnableBTAdapter(env))
1618 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1619 return CA_ADAPTER_NOT_ENABLED;
1622 // get BluetoothGatt class
1623 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1624 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1625 if (!jni_cid_BluetoothGatt)
1627 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1628 return CA_STATUS_FAILED;
1631 // set Characteristic Notification
1632 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1633 "setCharacteristicNotification",
1634 "(Landroid/bluetooth/"
1635 "BluetoothGattCharacteristic;Z)Z");
1636 if (!jni_mid_setNotification)
1638 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1639 return CA_STATUS_FAILED;
1642 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1643 characteristic, JNI_TRUE);
1644 if (JNI_TRUE == ret)
1646 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1650 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1651 return CA_STATUS_FAILED;
1654 return CA_STATUS_OK;
1657 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1659 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1660 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1661 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1663 if (!CALEIsEnableBTAdapter(env))
1665 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1669 // get BluetoothGatt class
1670 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1671 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1672 if (!jni_cid_BluetoothGatt)
1674 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1678 jmethodID jni_mid_getService = (*env)->GetMethodID(
1679 env, jni_cid_BluetoothGatt, "getService",
1680 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1681 if (!jni_mid_getService)
1683 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1687 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1688 if (!jni_obj_service_uuid)
1690 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1694 // get bluetooth gatt service
1695 OIC_LOG(DEBUG, TAG, "request to get service");
1696 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1697 jni_obj_service_uuid);
1698 if (!jni_obj_gattService)
1700 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1704 // get bluetooth gatt service class
1705 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1706 env, "android/bluetooth/BluetoothGattService");
1707 if (!jni_cid_BluetoothGattService)
1709 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1713 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1714 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1715 "getCharacteristic",
1716 "(Ljava/util/UUID;)"
1717 "Landroid/bluetooth/"
1718 "BluetoothGattCharacteristic;");
1719 if (!jni_mid_getCharacteristic)
1721 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1725 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1728 OIC_LOG(ERROR, TAG, "uuid is null");
1732 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1733 if (!jni_obj_tx_uuid)
1735 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1736 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1740 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1741 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1742 jni_mid_getCharacteristic,
1745 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1746 return jni_obj_GattCharacteristic;
1749 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1751 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1752 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1753 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1754 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1756 if (!CALEIsEnableBTAdapter(env))
1758 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1762 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1765 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1769 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1770 if (!jni_obj_GattCharacteristic)
1772 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1776 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1777 "/BluetoothGattCharacteristic");
1778 if (!jni_cid_BTGattCharacteristic)
1780 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1784 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1785 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1787 if (!jni_mid_setValue)
1789 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1793 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1795 if (JNI_TRUE == ret)
1797 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1801 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1806 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1807 "setWriteType", "(I)V");
1808 if (!jni_mid_setWriteType)
1810 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1814 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1815 "WRITE_TYPE_NO_RESPONSE", "I");
1816 if (!jni_fid_no_response)
1818 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1822 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1823 jni_fid_no_response);
1825 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1827 return jni_obj_GattCharacteristic;
1830 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1832 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1833 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1835 if (!CALEIsEnableBTAdapter(env))
1837 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1841 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1842 "BluetoothGattCharacteristic");
1843 if (!jni_cid_BTGattCharacteristic)
1845 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1849 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1850 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1852 if (!jni_mid_getValue)
1854 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1858 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1860 return jni_obj_data_array;
1863 CAResult_t CALEClientCreateUUIDList()
1867 OIC_LOG(ERROR, TAG, "g_jvm is null");
1868 return CA_STATUS_FAILED;
1871 bool isAttached = false;
1873 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1876 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1877 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1881 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1882 return CA_STATUS_FAILED;
1887 // create new object array
1888 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1889 if (!jni_cid_uuid_list)
1891 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1895 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1896 jni_cid_uuid_list, NULL);
1897 if (!jni_obj_uuid_list)
1899 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1904 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1907 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1910 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1912 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1916 (*g_jvm)->DetachCurrentThread(g_jvm);
1919 return CA_STATUS_OK;
1926 (*g_jvm)->DetachCurrentThread(g_jvm);
1928 return CA_STATUS_FAILED;
1931 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
1932 jobject characteristic)
1934 VERIFY_NON_NULL(env, TAG, "env is null");
1935 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1936 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1938 if (!CALEIsEnableBTAdapter(env))
1940 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1941 return CA_ADAPTER_NOT_ENABLED;
1944 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
1945 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1946 "BluetoothGattCharacteristic");
1947 if (!jni_cid_BTGattCharacteristic)
1949 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1950 return CA_STATUS_FAILED;
1953 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1954 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1956 "(Ljava/util/UUID;)Landroid/bluetooth/"
1957 "BluetoothGattDescriptor;");
1958 if (!jni_mid_getDescriptor)
1960 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
1961 return CA_STATUS_FAILED;
1964 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1965 if (!jni_obj_cc_uuid)
1967 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
1968 return CA_STATUS_FAILED;
1971 OIC_LOG(DEBUG, TAG, "request to get descriptor");
1972 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
1973 jni_mid_getDescriptor, jni_obj_cc_uuid);
1974 if (!jni_obj_descriptor)
1976 OIC_LOG(ERROR, TAG, "jni_obj_descriptor is null");
1977 return CA_STATUS_FAILED;
1980 OIC_LOG(DEBUG, TAG, "set value in descriptor");
1981 jclass jni_cid_descriptor = (*env)->FindClass(env,
1982 "android/bluetooth/BluetoothGattDescriptor");
1983 if (!jni_cid_descriptor)
1985 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
1986 return CA_STATUS_FAILED;
1989 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
1990 if (!jni_mid_setValue)
1992 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1993 return CA_STATUS_FAILED;
1996 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
1997 "ENABLE_NOTIFICATION_VALUE", "[B");
1998 if (!jni_fid_NotiValue)
2000 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2001 return CA_STATUS_FAILED;
2004 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2006 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2007 env, jni_obj_descriptor, jni_mid_setValue,
2008 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2011 OIC_LOG(DEBUG, TAG, "setValue success");
2015 OIC_LOG(ERROR, TAG, "setValue has failed");
2016 return CA_STATUS_FAILED;
2019 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2022 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2023 return CA_STATUS_FAILED;
2026 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2027 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2028 "(Landroid/bluetooth/"
2029 "BluetoothGattDescriptor;)Z");
2030 if (!jni_mid_writeDescriptor)
2032 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2033 return CA_STATUS_FAILED;
2036 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2037 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2038 jni_obj_descriptor);
2041 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2045 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2046 return CA_STATUS_FAILED;
2049 return CA_STATUS_OK;
2052 void CALEClientCreateScanDeviceList(JNIEnv *env)
2054 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2055 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2057 ca_mutex_lock(g_deviceListMutex);
2058 // create new object array
2059 if (g_deviceList == NULL)
2061 OIC_LOG(DEBUG, TAG, "Create device list");
2063 g_deviceList = u_arraylist_create();
2065 ca_mutex_unlock(g_deviceListMutex);
2068 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2070 OIC_LOG(DEBUG, TAG, "IN - CALEClientAddScanDeviceToList");
2071 VERIFY_NON_NULL(device, TAG, "device is null");
2072 VERIFY_NON_NULL(env, TAG, "env is null");
2074 ca_mutex_lock(g_deviceListMutex);
2078 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2079 ca_mutex_unlock(g_deviceListMutex);
2080 return CA_STATUS_FAILED;
2083 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2084 if (!jni_remoteAddress)
2086 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2087 ca_mutex_unlock(g_deviceListMutex);
2088 return CA_STATUS_FAILED;
2091 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2094 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2095 ca_mutex_unlock(g_deviceListMutex);
2096 return CA_STATUS_FAILED;
2099 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2101 jobject gdevice = (*env)->NewGlobalRef(env, device);
2102 u_arraylist_add(g_deviceList, gdevice);
2103 ca_cond_signal(g_deviceDescCond);
2104 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
2106 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2108 ca_mutex_unlock(g_deviceListMutex);
2110 OIC_LOG(DEBUG, TAG, "OUT - CALEClientAddScanDeviceToList");
2111 return CA_STATUS_OK;
2114 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2116 OIC_LOG(DEBUG, TAG, "IN - CALEClientIsDeviceInScanDeviceList");
2117 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2118 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2122 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2126 uint32_t length = u_arraylist_length(g_deviceList);
2127 for (uint32_t index = 0; index < length; index++)
2129 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2132 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2136 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2137 if (!jni_setAddress)
2139 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2143 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2146 OIC_LOG(ERROR, TAG, "setAddress is null");
2150 if (!strcmp(remoteAddress, setAddress))
2152 OIC_LOG(DEBUG, TAG, "the device is already set");
2153 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2157 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2160 OIC_LOG(DEBUG, TAG, "OUT - CALEClientIsDeviceInScanDeviceList");
2161 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2166 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2168 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2169 VERIFY_NON_NULL(env, TAG, "env is null");
2171 ca_mutex_lock(g_deviceListMutex);
2175 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2176 ca_mutex_unlock(g_deviceListMutex);
2177 return CA_STATUS_FAILED;
2180 uint32_t length = u_arraylist_length(g_deviceList);
2181 for (uint32_t index = 0; index < length; index++)
2183 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2186 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2189 (*env)->DeleteGlobalRef(env, jarrayObj);
2192 OICFree(g_deviceList);
2193 g_deviceList = NULL;
2195 ca_mutex_unlock(g_deviceListMutex);
2196 return CA_STATUS_OK;
2199 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2201 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2202 VERIFY_NON_NULL(address, TAG, "address is null");
2203 VERIFY_NON_NULL(env, TAG, "env is null");
2205 ca_mutex_lock(g_deviceListMutex);
2209 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2210 ca_mutex_unlock(g_deviceListMutex);
2211 return CA_STATUS_FAILED;
2214 uint32_t length = u_arraylist_length(g_deviceList);
2215 for (uint32_t index = 0; index < length; index++)
2217 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2220 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2221 ca_mutex_unlock(g_deviceListMutex);
2222 return CA_STATUS_FAILED;
2225 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2226 if (!jni_setAddress)
2228 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2229 ca_mutex_unlock(g_deviceListMutex);
2230 return CA_STATUS_FAILED;
2233 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2236 OIC_LOG(ERROR, TAG, "setAddress is null");
2237 ca_mutex_unlock(g_deviceListMutex);
2238 return CA_STATUS_FAILED;
2241 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2244 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2245 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2246 ca_mutex_unlock(g_deviceListMutex);
2247 return CA_STATUS_FAILED;
2250 if (!strcmp(setAddress, remoteAddress))
2252 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2253 (*env)->DeleteGlobalRef(env, jarrayObj);
2254 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2255 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2257 if (NULL == u_arraylist_remove(g_deviceList, index))
2259 OIC_LOG(ERROR, TAG, "List removal failed.");
2260 ca_mutex_unlock(g_deviceListMutex);
2261 return CA_STATUS_FAILED;
2263 ca_mutex_unlock(g_deviceListMutex);
2264 return CA_STATUS_OK;
2266 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2267 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2270 ca_mutex_unlock(g_deviceListMutex);
2271 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2273 return CA_STATUS_OK;
2280 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2282 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2283 VERIFY_NON_NULL(env, TAG, "env is null");
2284 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2286 ca_mutex_lock(g_gattObjectMutex);
2288 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2289 if (!jni_remoteAddress)
2291 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2292 ca_mutex_unlock(g_gattObjectMutex);
2293 return CA_STATUS_FAILED;
2296 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2299 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2300 ca_mutex_unlock(g_gattObjectMutex);
2301 return CA_STATUS_FAILED;
2304 if (!CALEClientIsGattObjInList(env, remoteAddress))
2306 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2307 u_arraylist_add(g_gattObjectList, newGatt);
2308 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2311 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2312 ca_mutex_unlock(g_gattObjectMutex);
2313 return CA_STATUS_OK;
2316 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2318 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2319 VERIFY_NON_NULL(env, TAG, "env is null");
2320 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2322 uint32_t length = u_arraylist_length(g_gattObjectList);
2323 for (uint32_t index = 0; index < length; index++)
2326 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2329 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2333 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2334 if (!jni_setAddress)
2336 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2340 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2343 OIC_LOG(ERROR, TAG, "setAddress is null");
2347 if (!strcmp(remoteAddress, setAddress))
2349 OIC_LOG(DEBUG, TAG, "the device is already set");
2350 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2355 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2360 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2364 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2366 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2367 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2368 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2370 ca_mutex_lock(g_gattObjectMutex);
2371 uint32_t length = u_arraylist_length(g_gattObjectList);
2372 for (uint32_t index = 0; index < length; index++)
2374 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2377 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2378 ca_mutex_unlock(g_gattObjectMutex);
2382 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2383 if (!jni_setAddress)
2385 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2386 ca_mutex_unlock(g_gattObjectMutex);
2390 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2393 OIC_LOG(ERROR, TAG, "setAddress is null");
2394 ca_mutex_unlock(g_gattObjectMutex);
2398 if (!strcmp(remoteAddress, setAddress))
2400 OIC_LOG(DEBUG, TAG, "the device is already set");
2401 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2402 ca_mutex_unlock(g_gattObjectMutex);
2405 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2408 ca_mutex_unlock(g_gattObjectMutex);
2409 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2413 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2415 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2416 VERIFY_NON_NULL(env, TAG, "env is null");
2418 ca_mutex_lock(g_gattObjectMutex);
2419 if (!g_gattObjectList)
2421 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2422 ca_mutex_unlock(g_gattObjectMutex);
2423 return CA_STATUS_FAILED;
2426 uint32_t length = u_arraylist_length(g_gattObjectList);
2427 for (uint32_t index = 0; index < length; index++)
2429 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2432 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2435 (*env)->DeleteGlobalRef(env, jarrayObj);
2438 OICFree(g_gattObjectList);
2439 g_gattObjectList = NULL;
2440 ca_mutex_unlock(g_gattObjectMutex);
2441 return CA_STATUS_OK;
2444 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2446 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2447 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2448 VERIFY_NON_NULL(env, TAG, "env is null");
2450 ca_mutex_lock(g_gattObjectMutex);
2451 if (!g_gattObjectList)
2453 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2454 ca_mutex_unlock(g_gattObjectMutex);
2455 return CA_STATUS_FAILED;
2458 uint32_t length = u_arraylist_length(g_gattObjectList);
2459 for (uint32_t index = 0; index < length; index++)
2461 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2464 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2465 ca_mutex_unlock(g_gattObjectMutex);
2466 return CA_STATUS_FAILED;
2469 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2470 if (!jni_setAddress)
2472 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2473 ca_mutex_unlock(g_gattObjectMutex);
2474 return CA_STATUS_FAILED;
2477 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2480 OIC_LOG(ERROR, TAG, "setAddress is null");
2481 ca_mutex_unlock(g_gattObjectMutex);
2482 return CA_STATUS_FAILED;
2485 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2486 if (!jni_remoteAddress)
2488 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2489 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2490 ca_mutex_unlock(g_gattObjectMutex);
2491 return CA_STATUS_FAILED;
2494 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2497 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2498 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2499 ca_mutex_unlock(g_gattObjectMutex);
2500 return CA_STATUS_FAILED;
2503 if (!strcmp(setAddress, remoteAddress))
2505 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2506 (*env)->DeleteGlobalRef(env, jarrayObj);
2507 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2508 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2510 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2512 OIC_LOG(ERROR, TAG, "List removal failed.");
2513 ca_mutex_unlock(g_gattObjectMutex);
2514 return CA_STATUS_FAILED;
2516 ca_mutex_unlock(g_gattObjectMutex);
2517 return CA_STATUS_OK;
2519 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2520 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2523 ca_mutex_unlock(g_gattObjectMutex);
2524 OIC_LOG(DEBUG, TAG, "there are no target object");
2525 return CA_STATUS_OK;
2528 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2530 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2531 VERIFY_NON_NULL(addr, TAG, "addr is null");
2532 VERIFY_NON_NULL(env, TAG, "env is null");
2534 ca_mutex_lock(g_gattObjectMutex);
2535 if (!g_gattObjectList)
2537 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2538 ca_mutex_unlock(g_gattObjectMutex);
2539 return CA_STATUS_FAILED;
2542 uint32_t length = u_arraylist_length(g_gattObjectList);
2543 for (uint32_t index = 0; index < length; index++)
2545 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2548 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2549 ca_mutex_unlock(g_gattObjectMutex);
2550 return CA_STATUS_FAILED;
2553 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2554 if (!jni_setAddress)
2556 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2557 ca_mutex_unlock(g_gattObjectMutex);
2558 return CA_STATUS_FAILED;
2561 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2564 OIC_LOG(ERROR, TAG, "setAddress is null");
2565 ca_mutex_unlock(g_gattObjectMutex);
2566 return CA_STATUS_FAILED;
2569 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2572 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2573 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2574 ca_mutex_unlock(g_gattObjectMutex);
2575 return CA_STATUS_FAILED;
2578 if (!strcmp(setAddress, remoteAddress))
2580 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2581 (*env)->DeleteGlobalRef(env, jarrayObj);
2583 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2584 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2585 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2587 OIC_LOG(ERROR, TAG, "List removal failed.");
2588 ca_mutex_unlock(g_gattObjectMutex);
2589 return CA_STATUS_FAILED;
2591 ca_mutex_unlock(g_gattObjectMutex);
2592 return CA_STATUS_OK;
2594 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2595 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2598 ca_mutex_unlock(g_gattObjectMutex);
2599 OIC_LOG(DEBUG, TAG, "there are no target object");
2600 return CA_STATUS_FAILED;
2607 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2608 uint16_t notificationState, uint16_t sendState)
2610 VERIFY_NON_NULL(address, TAG, "address is null");
2612 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2615 OIC_LOG(ERROR, TAG, "out of memory");
2616 return CA_MEMORY_ALLOC_FAILED;
2619 if (strlen(address) > CA_MACADDR_SIZE)
2621 OIC_LOG(ERROR, TAG, "address is not proper");
2623 return CA_STATUS_FAILED;
2626 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2627 newstate->connectedState = connectedState;
2628 newstate->notificationState = notificationState;
2629 newstate->sendState = sendState;
2630 return CALEClientAddDeviceStateToList(newstate);
2633 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2635 VERIFY_NON_NULL(state, TAG, "state is null");
2637 ca_mutex_lock(g_deviceStateListMutex);
2639 if (!g_deviceStateList)
2641 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2642 ca_mutex_unlock(g_deviceStateListMutex);
2643 return CA_STATUS_FAILED;
2646 if (CALEClientIsDeviceInList(state->address))
2648 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2651 OIC_LOG(ERROR, TAG, "curState is null");
2652 ca_mutex_unlock(g_deviceStateListMutex);
2653 return CA_STATUS_FAILED;
2656 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2658 state->notificationState = curState->notificationState;
2661 // delete previous state for update new state
2662 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2663 if (CA_STATUS_OK != res)
2665 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2666 ca_mutex_unlock(g_deviceStateListMutex);
2670 u_arraylist_add(g_deviceStateList, state); // update new state
2671 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2672 state->connectedState, state->notificationState);
2674 ca_mutex_unlock(g_deviceStateListMutex);
2675 return CA_STATUS_OK;
2678 bool CALEClientIsDeviceInList(const char* remoteAddress)
2680 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2682 if (!g_deviceStateList)
2684 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2688 uint32_t length = u_arraylist_length(g_deviceStateList);
2689 for (uint32_t index = 0; index < length; index++)
2691 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2694 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2698 if (!strcmp(remoteAddress, state->address))
2700 OIC_LOG(DEBUG, TAG, "the device is already set");
2709 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2713 CAResult_t CALEClientRemoveAllDeviceState()
2715 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2717 ca_mutex_lock(g_deviceStateListMutex);
2718 if (!g_deviceStateList)
2720 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2721 ca_mutex_unlock(g_deviceStateListMutex);
2722 return CA_STATUS_FAILED;
2725 uint32_t length = u_arraylist_length(g_deviceStateList);
2726 for (uint32_t index = 0; index < length; index++)
2728 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2731 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2737 OICFree(g_deviceStateList);
2738 g_deviceStateList = NULL;
2739 ca_mutex_unlock(g_deviceStateListMutex);
2741 return CA_STATUS_OK;
2744 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2746 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2747 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2749 if (!g_deviceStateList)
2751 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2752 return CA_STATUS_FAILED;
2755 uint32_t length = u_arraylist_length(g_deviceStateList);
2756 for (uint32_t index = 0; index < length; index++)
2758 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2761 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2765 if (!strcmp(state->address, remoteAddress))
2767 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2770 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2772 OIC_LOG(ERROR, TAG, "List removal failed.");
2773 return CA_STATUS_FAILED;
2776 return CA_STATUS_OK;
2780 return CA_STATUS_FAILED;
2783 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2785 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2786 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2788 if (!g_deviceStateList)
2790 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2794 uint32_t length = u_arraylist_length(g_deviceStateList);
2795 for (uint32_t index = 0; index < length; index++)
2797 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2800 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2804 if (!strcmp(state->address, remoteAddress))
2806 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2813 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2815 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2816 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2818 ca_mutex_lock(g_deviceStateListMutex);
2819 if (!g_deviceStateList)
2821 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2822 ca_mutex_unlock(g_deviceStateListMutex);
2826 uint32_t length = u_arraylist_length(g_deviceStateList);
2827 for (uint32_t index = 0; index < length; index++)
2829 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2832 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2836 if (!strcmp(state->address, remoteAddress))
2838 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2840 if (STATE_CONNECTED == state->connectedState)
2842 ca_mutex_unlock(g_deviceStateListMutex);
2847 ca_mutex_unlock(g_deviceStateListMutex);
2852 ca_mutex_unlock(g_deviceStateListMutex);
2856 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2858 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2859 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2861 ca_mutex_lock(g_deviceStateListMutex);
2862 if (!g_deviceStateList)
2864 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2865 ca_mutex_unlock(g_deviceStateListMutex);
2869 uint32_t length = u_arraylist_length(g_deviceStateList);
2870 for (uint32_t index = 0; index < length; index++)
2872 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2875 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2879 if (!strcmp(state->address, remoteAddress))
2881 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2883 if (STATE_CHARACTER_SET == state->notificationState)
2885 ca_mutex_unlock(g_deviceStateListMutex);
2890 ca_mutex_unlock(g_deviceStateListMutex);
2896 ca_mutex_unlock(g_deviceStateListMutex);
2900 void CALEClientCreateDeviceList()
2902 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2904 // create new object array
2905 if (!g_gattObjectList)
2907 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2909 g_gattObjectList = u_arraylist_create();
2912 if (!g_deviceStateList)
2914 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2916 g_deviceStateList = u_arraylist_create();
2921 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2923 g_deviceList = u_arraylist_create();
2928 * Check Sent Count for remove g_sendBuffer
2930 void CALEClientUpdateSendCnt(JNIEnv *env)
2932 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2934 ca_mutex_lock(g_threadMutex);
2938 if (g_targetCnt <= g_currentSentCnt)
2941 g_currentSentCnt = 0;
2945 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2946 g_sendBuffer = NULL;
2948 // notity the thread
2949 ca_cond_signal(g_threadCond);
2950 CALEClientSetSendFinishFlag(true);
2951 OIC_LOG(DEBUG, TAG, "set signal for send data");
2954 ca_mutex_unlock(g_threadMutex);
2957 CAResult_t CALEClientInitGattMutexVaraibles()
2959 OIC_LOG(DEBUG, TAG, "IN");
2961 if (NULL == g_bleReqRespClientCbMutex)
2963 g_bleReqRespClientCbMutex = ca_mutex_new();
2964 if (NULL == g_bleReqRespClientCbMutex)
2966 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2967 return CA_STATUS_FAILED;
2971 if (NULL == g_bleServerBDAddressMutex)
2973 g_bleServerBDAddressMutex = ca_mutex_new();
2974 if (NULL == g_bleServerBDAddressMutex)
2976 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2977 return CA_STATUS_FAILED;
2981 if (NULL == g_threadMutex)
2983 g_threadMutex = ca_mutex_new();
2984 if (NULL == g_threadMutex)
2986 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2987 return CA_STATUS_FAILED;
2991 if (NULL == g_threadSendMutex)
2993 g_threadSendMutex = ca_mutex_new();
2994 if (NULL == g_threadSendMutex)
2996 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2997 return CA_STATUS_FAILED;
3001 if (NULL == g_deviceListMutex)
3003 g_deviceListMutex = ca_mutex_new();
3004 if (NULL == g_deviceListMutex)
3006 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3007 return CA_STATUS_FAILED;
3011 if (NULL == g_gattObjectMutex)
3013 g_gattObjectMutex = ca_mutex_new();
3014 if (NULL == g_gattObjectMutex)
3016 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3017 return CA_STATUS_FAILED;
3021 if (NULL == g_deviceStateListMutex)
3023 g_deviceStateListMutex = ca_mutex_new();
3024 if (NULL == g_deviceStateListMutex)
3026 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3027 return CA_STATUS_FAILED;
3031 if (NULL == g_SendFinishMutex)
3033 g_SendFinishMutex = ca_mutex_new();
3034 if (NULL == g_SendFinishMutex)
3036 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3037 return CA_STATUS_FAILED;
3041 OIC_LOG(DEBUG, TAG, "OUT");
3042 return CA_STATUS_OK;
3045 void CALEClientTerminateGattMutexVariables()
3047 OIC_LOG(DEBUG, TAG, "IN");
3049 ca_mutex_free(g_bleReqRespClientCbMutex);
3050 g_bleReqRespClientCbMutex = NULL;
3052 ca_mutex_free(g_bleServerBDAddressMutex);
3053 g_bleServerBDAddressMutex = NULL;
3055 ca_mutex_free(g_threadMutex);
3056 g_threadMutex = NULL;
3058 ca_mutex_free(g_threadSendMutex);
3059 g_threadSendMutex = NULL;
3061 ca_mutex_free(g_deviceListMutex);
3062 g_deviceListMutex = NULL;
3064 ca_mutex_free(g_SendFinishMutex);
3065 g_SendFinishMutex = NULL;
3067 OIC_LOG(DEBUG, TAG, "OUT");
3070 void CALEClientSetSendFinishFlag(bool flag)
3072 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3074 ca_mutex_lock(g_SendFinishMutex);
3075 g_isFinishedSendData = flag;
3076 ca_mutex_unlock(g_SendFinishMutex);
3083 CAResult_t CAStartLEGattClient()
3085 CAResult_t res = CALEClientStartMulticastServer();
3086 if (CA_STATUS_OK != res)
3088 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3092 g_isStartedLEClient = true;
3098 void CAStopLEGattClient()
3100 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3104 OIC_LOG(ERROR, TAG, "g_jvm is null");
3108 bool isAttached = false;
3110 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3113 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3114 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3118 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3124 CAResult_t ret = CALEClientDisconnectAll(env);
3125 if (CA_STATUS_OK != ret)
3127 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3130 ret = CALEClientStopScan();
3131 if(CA_STATUS_OK != ret)
3133 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3136 ca_cond_signal(g_threadCond);
3140 (*g_jvm)->DetachCurrentThread(g_jvm);
3145 void CATerminateLEGattClient()
3147 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3148 CALEClientTerminate();
3151 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3152 uint32_t dataLen, CALETransferType_t type,
3155 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3156 VERIFY_NON_NULL(data, TAG, "data is null");
3157 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3159 if (LE_UNICAST != type || position < 0)
3161 OIC_LOG(ERROR, TAG, "this request is not unicast");
3162 return CA_STATUS_INVALID_PARAM;
3165 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3168 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3170 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3171 VERIFY_NON_NULL(data, TAG, "data is null");
3173 return CALEClientSendMulticastMessage(data, dataLen);
3176 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3178 OIC_LOG(DEBUG, TAG, "IN");
3180 ca_mutex_lock(g_bleReqRespClientCbMutex);
3181 g_CABLEClientDataReceivedCallback = callback;
3182 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3184 OIC_LOG(DEBUG, TAG, "OUT");
3187 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3189 OIC_LOG(DEBUG, TAG, "IN");
3191 CALEClientInitialize(handle);
3193 OIC_LOG(DEBUG, TAG, "OUT");
3196 CAResult_t CAGetLEAddress(char **local_address)
3198 VERIFY_NON_NULL(local_address, TAG, "local_address");
3199 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3200 return CA_NOT_SUPPORTED;
3203 JNIEXPORT void JNICALL
3204 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3207 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3208 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3209 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3210 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3212 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3215 JNIEXPORT void JNICALL
3216 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3219 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3220 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3221 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3222 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3224 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3227 JNIEXPORT void JNICALL
3228 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3231 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3232 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3233 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3235 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3236 if (CA_STATUS_OK != res)
3238 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3243 * Class: org_iotivity_ca_jar_caleinterface
3244 * Method: CALeGattConnectionStateChangeCallback
3245 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3247 JNIEXPORT void JNICALL
3248 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3254 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3256 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3257 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3258 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3260 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3262 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3268 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3271 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3272 STATE_CHARACTER_NO_CHANGE,
3274 if (CA_STATUS_OK != res)
3276 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3277 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3280 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3283 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3284 if (CA_STATUS_OK != res)
3286 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3290 res = CALEClientDiscoverServices(env, gatt);
3291 if (CA_STATUS_OK != res)
3293 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3297 else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
3299 CAResult_t res = CALEClientStartScan();
3300 if (CA_STATUS_OK != res)
3302 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3305 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3308 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3311 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3314 res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3315 STATE_CHARACTER_NO_CHANGE,
3317 if (CA_STATUS_OK != res)
3319 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3321 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3324 res = CALEClientGattClose(env, gatt);
3325 if (CA_STATUS_OK != res)
3327 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3333 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3336 OIC_LOG(ERROR, TAG, "jni_address is null");
3341 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3344 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3345 STATE_CHARACTER_NO_CHANGE,
3347 if (CA_STATUS_OK != res)
3349 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3352 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3354 CAResult_t res = CALEClientGattClose(env, gatt);
3355 if (CA_STATUS_OK != res)
3357 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3367 CALEClientSendFinish(env, gatt);
3372 * Class: org_iotivity_ca_jar_caleinterface
3373 * Method: CALeGattServicesDiscoveredCallback
3374 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3376 JNIEXPORT void JNICALL
3377 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3382 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3383 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3384 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3385 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3387 if (0 != status) // discovery error
3389 CALEClientSendFinish(env, gatt);
3393 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3396 CALEClientSendFinish(env, gatt);
3400 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3403 CALEClientSendFinish(env, gatt);
3407 if (!CALEClientIsSetCharacteristic(address))
3409 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3412 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3416 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3417 if (!jni_obj_GattCharacteristic)
3419 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3423 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3424 jni_obj_GattCharacteristic);
3425 if (CA_STATUS_OK != res)
3427 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3431 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3432 if (CA_STATUS_OK != res)
3434 OIC_LOG(INFO, TAG, "Descriptor of the uuid is not found");
3435 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3436 if (CA_STATUS_OK != res)
3438 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3443 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3445 if (CA_STATUS_OK != res)
3447 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3453 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3454 if (CA_STATUS_OK != res)
3456 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3460 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3465 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3466 CALEClientSendFinish(env, gatt);
3471 * Class: org_iotivity_ca_jar_caleinterface
3472 * Method: CALeGattCharacteristicWritjclasseCallback
3473 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3475 JNIEXPORT void JNICALL
3476 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3477 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3480 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3481 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3482 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3483 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3486 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3488 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3490 // send success & signal
3491 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3497 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3503 if (GATT_SUCCESS != status) // error case
3505 OIC_LOG(ERROR, TAG, "send failure");
3506 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3508 if (CA_STATUS_OK != res)
3510 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3513 if (g_clientErrorCallback)
3515 jint length = (*env)->GetArrayLength(env, data);
3516 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
3519 CALEClientSendFinish(env, gatt);
3523 OIC_LOG(DEBUG, TAG, "send success");
3524 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3525 STATE_SEND_SUCCESS);
3526 if (CA_STATUS_OK != res)
3528 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3530 CALEClientUpdateSendCnt(env);
3533 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3539 CALEClientSendFinish(env, gatt);
3544 * Class: org_iotivity_ca_jar_caleinterface
3545 * Method: CALeGattCharacteristicChangedCallback
3546 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3548 JNIEXPORT void JNICALL
3549 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3550 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3552 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3553 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3554 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3555 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3556 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3558 // get Byte Array and convert to uint8_t*
3559 jint length = (*env)->GetArrayLength(env, data);
3562 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3564 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3565 jni_byte_responseData);
3567 uint8_t* receivedData = OICMalloc(length);
3570 OIC_LOG(ERROR, TAG, "receivedData is null");
3574 memcpy(receivedData, jni_byte_responseData, length);
3575 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3577 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3580 OIC_LOG(ERROR, TAG, "jni_address is null");
3581 OICFree(receivedData);
3585 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3588 OIC_LOG(ERROR, TAG, "address is null");
3589 OICFree(receivedData);
3593 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3594 receivedData, length);
3596 ca_mutex_lock(g_bleServerBDAddressMutex);
3597 uint32_t sentLength = 0;
3598 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3600 ca_mutex_unlock(g_bleServerBDAddressMutex);
3602 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3606 * Class: org_iotivity_ca_jar_caleinterface
3607 * Method: CALeGattDescriptorWriteCallback
3608 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3610 JNIEXPORT void JNICALL
3611 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3615 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3616 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3617 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3618 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3620 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3621 if (CA_STATUS_OK != res)
3623 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3631 CALEClientSendFinish(env, gatt);