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 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
43 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
44 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
45 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
48 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
49 static u_arraylist_t *g_gattObjectList = NULL;
50 static u_arraylist_t *g_deviceStateList = NULL;
52 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
53 static CABLEErrorHandleCallback g_clientErrorCallback;
54 static ca_thread_pool_t g_threadPoolHandle = NULL;
55 static jobject g_leScanCallback = NULL;
56 static jobject g_leGattCallback = NULL;
57 static jobject g_context = NULL;
58 static jobjectArray g_uuidList = NULL;
60 // it will be prevent to start send logic when adapter has stopped.
61 static bool g_isStartedLEClient = false;
62 static bool g_isStartedMulticastServer = false;
63 static bool g_isStartedScan = false;
65 static jbyteArray g_sendBuffer = NULL;
66 static uint32_t g_targetCnt = 0;
67 static uint32_t g_currentSentCnt = 0;
68 static bool g_isFinishedSendData = false;
69 static ca_mutex g_SendFinishMutex = NULL;
70 static ca_mutex g_threadMutex = NULL;
71 static ca_cond g_threadCond = NULL;
73 static ca_mutex g_threadSendMutex = NULL;
75 static ca_mutex g_bleReqRespClientCbMutex = NULL;
76 static ca_mutex g_bleServerBDAddressMutex = NULL;
78 static ca_mutex g_deviceListMutex = NULL;
79 static ca_mutex g_gattObjectMutex = NULL;
80 static ca_mutex g_deviceStateListMutex = NULL;
82 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
85 void CALEClientJniInit()
87 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
88 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
91 void CALEClientJNISetContext()
93 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
94 g_context = (jobject) CANativeJNIGetContext();
97 CAResult_t CALECreateJniInterfaceObject()
99 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
103 OIC_LOG(ERROR, TAG, "g_context is null");
104 return CA_STATUS_FAILED;
109 OIC_LOG(ERROR, TAG, "g_jvm is null");
110 return CA_STATUS_FAILED;
113 bool isAttached = false;
115 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
118 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
119 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
123 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
124 return CA_STATUS_FAILED;
129 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
130 if (!jni_LEInterface)
132 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
136 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
137 "(Landroid/content/Context;)V");
138 if (!LeInterfaceConstructorMethod)
140 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
144 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
145 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
149 (*g_jvm)->DetachCurrentThread(g_jvm);
158 (*g_jvm)->DetachCurrentThread(g_jvm);
161 return CA_STATUS_FAILED;
164 CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
166 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
172 OIC_LOG(ERROR, TAG, "g_jvm is null");
173 return CA_STATUS_FAILED;
176 bool isAttached = false;
178 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
181 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
182 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
186 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
187 return CA_STATUS_FAILED;
192 CAResult_t ret = CALECheckPlatformVersion(env, 18);
193 if (CA_STATUS_OK != ret)
195 OIC_LOG(ERROR, TAG, "it is not supported");
199 (*g_jvm)->DetachCurrentThread(g_jvm);
205 g_threadPoolHandle = handle;
207 ret = CALEClientInitGattMutexVaraibles();
208 if (CA_STATUS_OK != ret)
210 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
211 CALEClientTerminateGattMutexVariables();
215 (*g_jvm)->DetachCurrentThread(g_jvm);
221 // init mutex for send logic
222 g_threadCond = ca_cond_new();
224 CALEClientCreateDeviceList();
225 CALEClientJNISetContext();
227 ret = CALEClientCreateUUIDList();
228 if (CA_STATUS_OK != ret)
230 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
234 (*g_jvm)->DetachCurrentThread(g_jvm);
240 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
241 if (CA_STATUS_OK != ret)
243 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
247 (*g_jvm)->DetachCurrentThread(g_jvm);
252 g_isStartedLEClient = true;
257 void CALEClientTerminate()
259 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
263 OIC_LOG(ERROR, TAG, "g_jvm is null");
267 bool isAttached = false;
269 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
272 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
273 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
277 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
283 if (g_leScanCallback)
285 (*env)->DeleteGlobalRef(env, g_leScanCallback);
288 if (g_leGattCallback)
290 (*env)->DeleteGlobalRef(env, g_leGattCallback);
295 (*env)->DeleteGlobalRef(env, g_sendBuffer);
300 (*env)->DeleteGlobalRef(env, g_uuidList);
303 CAResult_t ret = CALEClientRemoveAllDeviceState();
304 if (CA_STATUS_OK != ret)
306 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
309 ret = CALEClientRemoveAllScanDevices(env);
310 if (CA_STATUS_OK != ret)
312 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
315 ret = CALEClientRemoveAllGattObjs(env);
316 if (CA_STATUS_OK != ret)
318 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
321 g_isStartedMulticastServer = false;
322 g_isStartedScan = false;
323 CALEClientSetSendFinishFlag(false);
325 CALEClientTerminateGattMutexVariables();
327 ca_cond_free(g_threadCond);
331 (*g_jvm)->DetachCurrentThread(g_jvm);
335 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
337 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
338 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
342 CAResult_t res = CALEClientDisconnect(env, gatt);
343 if (CA_STATUS_OK != res)
345 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
348 CALEClientUpdateSendCnt(env);
351 CAResult_t CALEClientSendUnicastMessage(const char* address, const char* data,
352 const uint32_t dataLen)
354 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %s)", address, data);
355 VERIFY_NON_NULL(address, TAG, "address is null");
356 VERIFY_NON_NULL(data, TAG, "data is null");
358 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
361 CAResult_t CALEClientSendMulticastMessage(const char* data, const uint32_t dataLen)
363 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%s)", data);
364 VERIFY_NON_NULL(data, TAG, "data is null");
368 OIC_LOG(ERROR, TAG, "g_jvm is null");
369 return CA_STATUS_FAILED;
372 bool isAttached = false;
374 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
377 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
378 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
382 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
383 return CA_STATUS_FAILED;
388 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
389 if (CA_STATUS_OK != ret)
391 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
396 (*g_jvm)->DetachCurrentThread(g_jvm);
402 CAResult_t CALEClientStartUnicastServer(const char* address)
404 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
406 return CA_NOT_SUPPORTED;
409 CAResult_t CALEClientStartMulticastServer()
411 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
413 if (g_isStartedMulticastServer)
415 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
416 return CA_STATUS_FAILED;
421 OIC_LOG(ERROR, TAG, "g_jvm is null");
422 return CA_STATUS_FAILED;
425 bool isAttached = false;
427 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
430 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
431 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
435 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
436 return CA_STATUS_FAILED;
441 g_isStartedMulticastServer = true;
442 CAResult_t ret = CALEClientStartScan();
443 if (CA_STATUS_OK != ret)
445 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
450 (*g_jvm)->DetachCurrentThread(g_jvm);
456 void CALEClientStopUnicastServer()
458 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
461 void CALEClientStopMulticastServer()
463 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
464 g_isStartedMulticastServer = false;
465 CAResult_t res = CALEClientStopScan();
466 if (CA_STATUS_OK != res)
468 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
473 void CALEClientSetCallback(CAPacketReceiveCallback callback)
475 g_packetReceiveCallback = callback;
478 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
480 g_clientErrorCallback = callback;
483 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const char* data,
484 const uint32_t dataLen)
486 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %s", address,
488 VERIFY_NON_NULL(address, TAG, "address is null");
489 VERIFY_NON_NULL(data, TAG, "data is null");
493 OIC_LOG(ERROR, TAG, "g_jvm is null");
494 return CA_STATUS_FAILED;
497 bool isAttached = false;
499 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
502 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
503 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
506 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
507 return CA_STATUS_FAILED;
512 ca_mutex_lock(g_threadSendMutex);
514 CAResult_t ret = CA_STATUS_OK;
515 if (g_context && g_deviceList)
517 uint32_t length = u_arraylist_length(g_deviceList);
518 for (uint32_t index = 0; index < length; index++)
520 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
523 OIC_LOG(ERROR, TAG, "jarrayObj is null");
527 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
530 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
534 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
537 OIC_LOG(ERROR, TAG, "setAddress is null");
541 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
543 if (!strcmp(setAddress, address))
545 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
547 // connect to gatt server
548 ret = CALEClientStopScan();
549 if (CA_STATUS_OK != ret)
551 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
557 (*env)->DeleteGlobalRef(env, g_sendBuffer);
559 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
560 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
561 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
563 ret = CALEClientSendData(env, jarrayObj);
564 if (CA_STATUS_OK != ret)
566 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
570 OIC_LOG(INFO, TAG, "wake up");
573 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
579 (*g_jvm)->DetachCurrentThread(g_jvm);
582 ret = CALECheckSendState(address);
583 if(CA_STATUS_OK != ret)
585 OIC_LOG(ERROR, TAG, "send has failed");
589 // start LE Scan again
590 ret = CALEClientStartScan();
591 if (CA_STATUS_OK != ret)
593 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
594 ca_mutex_unlock(g_threadSendMutex);
598 ca_mutex_unlock(g_threadSendMutex);
599 OIC_LOG(INFO, TAG, "unicast - send success");
605 // start LE Scan again
606 ret = CALEClientStartScan();
607 if (CA_STATUS_OK != ret)
609 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
610 ca_mutex_unlock(g_threadSendMutex);
616 (*g_jvm)->DetachCurrentThread(g_jvm);
618 ca_mutex_unlock(g_threadSendMutex);
619 return CA_SEND_FAILED;
622 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char* data,
623 const uint32_t dataLen)
625 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
626 VERIFY_NON_NULL(data, TAG, "data is null");
627 VERIFY_NON_NULL(env, TAG, "env is null");
631 OIC_LOG(ERROR, TAG, "g_deviceList is null");
632 return CA_STATUS_FAILED;
635 ca_mutex_lock(g_threadSendMutex);
637 CALEClientSetSendFinishFlag(false);
639 OIC_LOG(DEBUG, TAG, "set byteArray for data");
642 (*env)->DeleteGlobalRef(env, g_sendBuffer);
644 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
645 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
646 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
648 // connect to gatt server
649 CAResult_t res = CALEClientStopScan();
650 if (CA_STATUS_OK != res)
652 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
653 ca_mutex_unlock(g_threadSendMutex);
657 uint32_t length = u_arraylist_length(g_deviceList);
658 g_targetCnt = length;
664 for (uint32_t index = 0; index < length; index++)
666 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
669 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
673 res = CALEClientSendData(env, jarrayObj);
674 if (res != CA_STATUS_OK)
676 OIC_LOG(ERROR, TAG, "BT device[%d] - send has failed");
679 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
682 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
686 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
689 OIC_LOG(ERROR, TAG, "address is not available");
693 res = CALECheckSendState(address);
694 if (CA_STATUS_OK != res)
696 OIC_LOG_V(INFO, TAG, "multicast : send has failed for this device[%s]", address);
697 g_clientErrorCallback(address, data, dataLen, res);
698 (*env)->ReleaseStringUTFChars(env, jni_address, address);
702 (*env)->ReleaseStringUTFChars(env, jni_address, address);
705 OIC_LOG(DEBUG, TAG, "connection routine is finished");
707 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
708 if (!g_isFinishedSendData)
710 ca_mutex_lock(g_threadMutex);
711 ca_cond_wait(g_threadCond, g_threadMutex);
712 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
713 ca_mutex_unlock(g_threadMutex);
716 // start LE Scan again
717 res = CALEClientStartScan();
718 if (CA_STATUS_OK != res)
720 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
721 ca_mutex_unlock(g_threadSendMutex);
725 ca_mutex_unlock(g_threadSendMutex);
726 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
730 res = CALEClientStartScan();
731 if (CA_STATUS_OK != res)
733 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
734 ca_mutex_unlock(g_threadSendMutex);
738 ca_mutex_unlock(g_threadSendMutex);
739 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
740 return CA_SEND_FAILED;
743 CAResult_t CALECheckSendState(const char* address)
745 VERIFY_NON_NULL(address, TAG, "address is null");
747 ca_mutex_lock(g_deviceStateListMutex);
748 CALEState_t* state = CALEClientGetStateInfo(address);
751 OIC_LOG(ERROR, TAG, "state is null");
752 ca_mutex_unlock(g_deviceStateListMutex);
753 return CA_SEND_FAILED;
756 if (STATE_SEND_SUCCESS != state->sendState)
758 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
759 ca_mutex_unlock(g_deviceStateListMutex);
760 return CA_SEND_FAILED;
762 ca_mutex_unlock(g_deviceStateListMutex);
766 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
768 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
769 VERIFY_NON_NULL(device, TAG, "device is null");
770 VERIFY_NON_NULL(env, TAG, "env is null");
772 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
775 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
776 return CA_STATUS_FAILED;
779 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
782 OIC_LOG(ERROR, TAG, "address is not available");
783 return CA_STATUS_FAILED;
786 ca_mutex_lock(g_deviceStateListMutex);
787 CALEState_t* state = CALEClientGetStateInfo(address);
788 ca_mutex_unlock(g_deviceStateListMutex);
791 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
792 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
793 if (CA_STATUS_OK != ret)
795 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
796 (*env)->ReleaseStringUTFChars(env, jni_address, address);
802 if (STATE_CONNECTED == state->connectedState)
804 OIC_LOG(INFO, TAG, "GATT has already connected");
805 jobject gatt = CALEClientGetGattObjInList(env, address);
808 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
809 (*env)->ReleaseStringUTFChars(env, jni_address, address);
810 return CA_STATUS_FAILED;
813 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
814 if (CA_STATUS_OK != ret)
816 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
817 (*env)->ReleaseStringUTFChars(env, jni_address, address);
823 OIC_LOG(DEBUG, TAG, "start to connect LE");
824 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
825 if (CA_STATUS_OK != ret)
827 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
828 (*env)->ReleaseStringUTFChars(env, jni_address, address);
834 (*env)->ReleaseStringUTFChars(env, jni_address, address);
838 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
840 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
841 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
843 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
844 if (!jni_cid_gattdevice_list)
846 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
850 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
851 "()Landroid/bluetooth/BluetoothDevice;");
852 if (!jni_mid_getDevice)
854 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
858 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
861 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
865 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
868 OIC_LOG(ERROR, TAG, "jni_address is null");
878 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
881 OIC_LOG(DEBUG, TAG, "Gatt Close");
882 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
883 VERIFY_NON_NULL(env, TAG, "env is null");
885 // get BluetoothGatt class
886 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
887 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
888 if (!jni_cid_BluetoothGatt)
890 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
891 return CA_STATUS_FAILED;
894 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
895 if (!jni_mid_closeGatt)
897 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
901 // call disconnect gatt method
902 OIC_LOG(DEBUG, TAG, "request to close GATT");
903 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
905 if ((*env)->ExceptionCheck(env))
907 OIC_LOG(ERROR, TAG, "closeGATT has failed");
908 (*env)->ExceptionDescribe(env);
909 (*env)->ExceptionClear(env);
910 return CA_STATUS_FAILED;
916 CAResult_t CALEClientStartScan()
918 if (!g_isStartedMulticastServer)
920 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
921 return CA_STATUS_FAILED;
924 if (!g_isStartedLEClient)
926 OIC_LOG(ERROR, TAG, "LE client is not started");
927 return CA_STATUS_FAILED;
932 OIC_LOG(ERROR, TAG, "g_jvm is null");
933 return CA_STATUS_FAILED;
938 OIC_LOG(INFO, TAG, "scanning is already started");
942 bool isAttached = false;
944 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
947 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
949 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
952 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
953 return CA_STATUS_FAILED;
958 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
960 CAResult_t ret = CA_STATUS_OK;
961 // scan gatt server with UUID
962 if (g_leScanCallback && g_uuidList)
965 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
966 if(CA_STATUS_OK != ret)
968 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
971 ret = CALEClientStartScanImpl(env, g_leScanCallback);
972 if (CA_STATUS_OK != ret)
974 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
981 (*g_jvm)->DetachCurrentThread(g_jvm);
987 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
989 VERIFY_NON_NULL(callback, TAG, "callback is null");
990 VERIFY_NON_NULL(env, TAG, "env is null");
992 if (!CALEIsEnableBTAdapter(env))
994 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
995 return CA_ADAPTER_NOT_ENABLED;
998 // get default bt adapter class
999 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1000 if (!jni_cid_BTAdapter)
1002 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1003 return CA_STATUS_FAILED;
1006 // get remote bt adapter method
1007 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1008 "getDefaultAdapter",
1009 METHODID_OBJECTNONPARAM);
1010 if (!jni_mid_getDefaultAdapter)
1012 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1013 return CA_STATUS_FAILED;
1016 // get start le scan method
1017 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1018 "(Landroid/bluetooth/BluetoothAdapter$"
1019 "LeScanCallback;)Z");
1020 if (!jni_mid_startLeScan)
1022 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1023 return CA_STATUS_FAILED;
1026 // gat bt adapter object
1027 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1028 jni_mid_getDefaultAdapter);
1029 if (!jni_obj_BTAdapter)
1031 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1032 return CA_STATUS_FAILED;
1035 // call start le scan method
1036 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1037 jni_mid_startLeScan, callback);
1038 if (!jni_obj_startLeScan)
1040 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1041 return CA_STATUS_FAILED;
1045 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1046 g_isStartedScan = true;
1049 return CA_STATUS_OK;
1052 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1054 VERIFY_NON_NULL(callback, TAG, "callback is null");
1055 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1056 VERIFY_NON_NULL(env, TAG, "env is null");
1058 if (!CALEIsEnableBTAdapter(env))
1060 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1061 return CA_ADAPTER_NOT_ENABLED;
1064 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1065 if (!jni_cid_BTAdapter)
1067 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1068 return CA_STATUS_FAILED;
1071 // get remote bt adapter method
1072 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1073 "getDefaultAdapter",
1074 METHODID_OBJECTNONPARAM);
1075 if (!jni_mid_getDefaultAdapter)
1077 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1078 return CA_STATUS_FAILED;
1081 // get start le scan method
1082 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1083 "([Ljava/util/UUID;Landroid/bluetooth/"
1084 "BluetoothAdapter$LeScanCallback;)Z");
1085 if (!jni_mid_startLeScan)
1087 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1088 return CA_STATUS_FAILED;
1091 // get bt adapter object
1092 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1093 jni_mid_getDefaultAdapter);
1094 if (!jni_obj_BTAdapter)
1096 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1097 return CA_STATUS_FAILED;
1100 // call start le scan method
1101 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1102 jni_mid_startLeScan, uuids, callback);
1103 if (!jni_obj_startLeScan)
1105 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1106 return CA_STATUS_FAILED;
1110 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1111 g_isStartedScan = true;
1114 return CA_STATUS_OK;
1117 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1119 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1120 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1123 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1126 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1130 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1131 "(Ljava/lang/String;)"
1132 "Ljava/util/UUID;");
1133 if (!jni_mid_fromString)
1135 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1139 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1140 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1144 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1148 return jni_obj_uuid;
1151 CAResult_t CALEClientStopScan()
1155 OIC_LOG(ERROR, TAG, "g_jvm is null");
1156 return CA_STATUS_FAILED;
1159 if (!g_isStartedScan)
1161 OIC_LOG(INFO, TAG, "scanning is already stopped");
1162 return CA_STATUS_OK;
1165 bool isAttached = false;
1167 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1170 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1171 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1174 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1175 return CA_STATUS_FAILED;
1180 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1181 if (CA_STATUS_OK != ret)
1183 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1187 g_isStartedScan = false;
1192 (*g_jvm)->DetachCurrentThread(g_jvm);
1198 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1200 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1201 VERIFY_NON_NULL(callback, TAG, "callback is null");
1202 VERIFY_NON_NULL(env, TAG, "env is null");
1204 if (!CALEIsEnableBTAdapter(env))
1206 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1207 return CA_ADAPTER_NOT_ENABLED;
1210 // get default bt adapter class
1211 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1212 if (!jni_cid_BTAdapter)
1214 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1215 return CA_STATUS_FAILED;
1218 // get remote bt adapter method
1219 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1220 "getDefaultAdapter",
1221 METHODID_OBJECTNONPARAM);
1222 if (!jni_mid_getDefaultAdapter)
1224 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1225 return CA_STATUS_FAILED;
1228 // get start le scan method
1229 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1230 "(Landroid/bluetooth/"
1231 "BluetoothAdapter$LeScanCallback;)V");
1232 if (!jni_mid_stopLeScan)
1234 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1235 return CA_STATUS_FAILED;
1238 // gat bt adapter object
1239 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1240 jni_mid_getDefaultAdapter);
1241 if (!jni_obj_BTAdapter)
1243 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1244 return CA_STATUS_FAILED;
1247 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1248 // call start le scan method
1249 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1250 if ((*env)->ExceptionCheck(env))
1252 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1253 (*env)->ExceptionDescribe(env);
1254 (*env)->ExceptionClear(env);
1255 return CA_STATUS_FAILED;
1258 return CA_STATUS_OK;
1261 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1264 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1265 VERIFY_NON_NULL(env, TAG, "env is null");
1266 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1267 VERIFY_NON_NULL(callback, TAG, "callback is null");
1269 if (!CALEIsEnableBTAdapter(env))
1271 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1272 return CA_ADAPTER_NOT_ENABLED;
1275 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1278 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1279 return CA_STATUS_FAILED;
1282 // get BluetoothDevice class
1283 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1284 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1285 if (!jni_cid_BluetoothDevice)
1287 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1288 return CA_STATUS_FAILED;
1291 // get connectGatt method
1292 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1293 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1294 "(Landroid/content/Context;ZLandroid/"
1295 "bluetooth/BluetoothGattCallback;)"
1296 "Landroid/bluetooth/BluetoothGatt;");
1297 if (!jni_mid_connectGatt)
1299 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1300 return CA_STATUS_FAILED;
1303 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1304 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1305 jni_mid_connectGatt,
1307 autoconnect, callback);
1308 if (!jni_obj_connectGatt)
1310 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1311 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1312 CALEClientUpdateSendCnt(env);
1313 return CA_STATUS_FAILED;
1317 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1319 return CA_STATUS_OK;
1322 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1324 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1325 VERIFY_NON_NULL(env, TAG, "env is null");
1326 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1328 if (!CALEIsEnableBTAdapter(env))
1330 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1331 return CA_ADAPTER_NOT_ENABLED;
1334 // get BluetoothGatt class
1335 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1336 if (!jni_cid_BluetoothGatt)
1338 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1339 return CA_STATUS_FAILED;
1342 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1343 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1344 "disconnect", "()V");
1345 if (!jni_mid_disconnectGatt)
1347 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1348 return CA_STATUS_FAILED;
1351 // call disconnect gatt method
1352 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1353 if ((*env)->ExceptionCheck(env))
1355 OIC_LOG(ERROR, TAG, "disconnect has failed");
1356 (*env)->ExceptionDescribe(env);
1357 (*env)->ExceptionClear(env);
1358 return CA_STATUS_FAILED;
1361 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1363 return CA_STATUS_OK;
1366 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1368 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1369 VERIFY_NON_NULL(env, TAG, "env is null");
1371 if (!g_gattObjectList)
1373 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1374 return CA_STATUS_FAILED;
1377 uint32_t length = u_arraylist_length(g_gattObjectList);
1378 for (uint32_t index = 0; index < length; index++)
1380 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1383 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1386 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1387 if (CA_STATUS_OK != res)
1389 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1394 OICFree(g_gattObjectList);
1395 g_gattObjectList = NULL;
1397 return CA_STATUS_OK;
1400 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1402 VERIFY_NON_NULL(env, TAG, "env is null");
1403 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1405 if (!CALEIsEnableBTAdapter(env))
1407 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1408 return CA_ADAPTER_NOT_ENABLED;
1411 // get BluetoothGatt class
1412 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1413 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1414 if (!jni_cid_BluetoothGatt)
1416 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1417 return CA_STATUS_FAILED;
1420 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1421 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1422 "discoverServices", "()Z");
1423 if (!jni_mid_discoverServices)
1425 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1426 return CA_STATUS_FAILED;
1428 // call disconnect gatt method
1429 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1430 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1433 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1434 return CA_STATUS_FAILED;
1437 return CA_STATUS_OK;
1440 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1442 VERIFY_NON_NULL(env, TAG, "env is null");
1443 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1446 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1447 if (!jni_obj_character)
1449 CALEClientSendFinish(env, gatt);
1450 return CA_STATUS_FAILED;
1453 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1454 if (CA_STATUS_OK != ret)
1456 CALEClientSendFinish(env, gatt);
1460 return CA_STATUS_OK;
1463 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1464 jobject gattCharacteristic)
1466 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1467 VERIFY_NON_NULL(env, TAG, "env is null");
1468 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1469 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1471 if (!CALEIsEnableBTAdapter(env))
1473 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1474 return CA_STATUS_FAILED;
1477 // get BluetoothGatt class
1478 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1479 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1480 if (!jni_cid_BluetoothGatt)
1482 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1483 return CA_STATUS_FAILED;
1486 OIC_LOG(DEBUG, TAG, "write characteristic method");
1487 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1488 "writeCharacteristic",
1489 "(Landroid/bluetooth/"
1490 "BluetoothGattCharacteristic;)Z");
1491 if (!jni_mid_writeCharacteristic)
1493 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1494 return CA_STATUS_FAILED;
1497 // call disconnect gatt method
1498 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1499 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1500 jni_mid_writeCharacteristic,
1501 gattCharacteristic);
1504 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1508 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1509 return CA_STATUS_FAILED;
1512 return CA_STATUS_OK;
1515 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1517 VERIFY_NON_NULL(env, TAG, "env is null");
1518 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1520 if (!CALEIsEnableBTAdapter(env))
1522 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1523 return CA_STATUS_FAILED;
1526 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1527 if (!jni_cid_BluetoothGatt)
1529 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1530 return CA_STATUS_FAILED;
1533 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1536 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1537 return CA_STATUS_FAILED;
1540 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1541 if (!jni_obj_GattCharacteristic)
1543 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1544 return CA_STATUS_FAILED;
1547 OIC_LOG(DEBUG, TAG, "read characteristic method");
1548 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1549 "readCharacteristic",
1550 "(Landroid/bluetooth/"
1551 "BluetoothGattCharacteristic;)Z");
1552 if (!jni_mid_readCharacteristic)
1554 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1555 return CA_STATUS_FAILED;
1558 // call disconnect gatt method
1559 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1560 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1561 jni_obj_GattCharacteristic);
1564 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1568 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1569 return CA_STATUS_FAILED;
1572 return CA_STATUS_OK;
1575 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1576 jobject characteristic)
1578 VERIFY_NON_NULL(env, TAG, "env is null");
1579 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1580 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1582 if (!CALEIsEnableBTAdapter(env))
1584 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1585 return CA_ADAPTER_NOT_ENABLED;
1588 // get BluetoothGatt class
1589 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1590 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1591 if (!jni_cid_BluetoothGatt)
1593 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1594 return CA_STATUS_FAILED;
1597 // set Characteristic Notification
1598 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1599 "setCharacteristicNotification",
1600 "(Landroid/bluetooth/"
1601 "BluetoothGattCharacteristic;Z)Z");
1602 if (!jni_mid_setNotification)
1604 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1605 return CA_STATUS_FAILED;
1608 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1609 characteristic, JNI_TRUE);
1610 if (JNI_TRUE == ret)
1612 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1616 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1617 return CA_STATUS_FAILED;
1620 return CA_STATUS_OK;
1623 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1625 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1626 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1627 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1629 if (!CALEIsEnableBTAdapter(env))
1631 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1635 // get BluetoothGatt class
1636 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1637 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1638 if (!jni_cid_BluetoothGatt)
1640 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1644 jmethodID jni_mid_getService = (*env)->GetMethodID(
1645 env, jni_cid_BluetoothGatt, "getService",
1646 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1647 if (!jni_mid_getService)
1649 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1653 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1654 if (!jni_obj_service_uuid)
1656 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1660 // get bluetooth gatt service
1661 OIC_LOG(DEBUG, TAG, "request to get service");
1662 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1663 jni_obj_service_uuid);
1664 if (!jni_obj_gattService)
1666 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1670 // get bluetooth gatt service class
1671 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1672 env, "android/bluetooth/BluetoothGattService");
1673 if (!jni_cid_BluetoothGattService)
1675 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1679 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1680 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1681 "getCharacteristic",
1682 "(Ljava/util/UUID;)"
1683 "Landroid/bluetooth/"
1684 "BluetoothGattCharacteristic;");
1685 if (!jni_mid_getCharacteristic)
1687 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1691 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1694 OIC_LOG(ERROR, TAG, "uuid is null");
1698 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1699 if (!jni_obj_tx_uuid)
1701 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1702 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1706 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1707 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1708 jni_mid_getCharacteristic,
1711 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1712 return jni_obj_GattCharacteristic;
1715 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1717 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1718 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1719 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1720 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1722 if (!CALEIsEnableBTAdapter(env))
1724 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1728 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1731 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1735 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1736 if (!jni_obj_GattCharacteristic)
1738 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1742 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1743 "/BluetoothGattCharacteristic");
1744 if (!jni_cid_BTGattCharacteristic)
1746 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1750 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1751 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1753 if (!jni_mid_setValue)
1755 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1759 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1761 if (JNI_TRUE == ret)
1763 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1767 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1772 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1773 "setWriteType", "(I)V");
1774 if (!jni_mid_setWriteType)
1776 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1780 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1781 "WRITE_TYPE_NO_RESPONSE", "I");
1782 if (!jni_fid_no_response)
1784 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1788 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1789 jni_fid_no_response);
1791 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1793 return jni_obj_GattCharacteristic;
1796 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1798 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1799 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1801 if (!CALEIsEnableBTAdapter(env))
1803 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1807 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1808 "BluetoothGattCharacteristic");
1809 if (!jni_cid_BTGattCharacteristic)
1811 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1815 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1816 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1818 if (!jni_mid_getValue)
1820 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1824 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1826 return jni_obj_data_array;
1829 CAResult_t CALEClientCreateUUIDList()
1833 OIC_LOG(ERROR, TAG, "g_jvm is null");
1834 return CA_STATUS_FAILED;
1837 bool isAttached = false;
1839 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1842 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1843 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1847 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1848 return CA_STATUS_FAILED;
1853 // create new object array
1854 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1855 if (!jni_cid_uuid_list)
1857 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1861 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1862 jni_cid_uuid_list, NULL);
1863 if (!jni_obj_uuid_list)
1865 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1870 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1873 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1876 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1878 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1882 (*g_jvm)->DetachCurrentThread(g_jvm);
1885 return CA_STATUS_OK;
1892 (*g_jvm)->DetachCurrentThread(g_jvm);
1894 return CA_STATUS_FAILED;
1897 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
1898 jobject characteristic)
1900 VERIFY_NON_NULL(env, TAG, "env is null");
1901 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1902 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1904 if (!CALEIsEnableBTAdapter(env))
1906 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1907 return CA_ADAPTER_NOT_ENABLED;
1910 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
1911 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1912 "BluetoothGattCharacteristic");
1913 if (!jni_cid_BTGattCharacteristic)
1915 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1916 return CA_STATUS_FAILED;
1919 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1920 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1922 "(Ljava/util/UUID;)Landroid/bluetooth/"
1923 "BluetoothGattDescriptor;");
1924 if (!jni_mid_getDescriptor)
1926 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
1927 return CA_STATUS_FAILED;
1930 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1931 if (!jni_obj_cc_uuid)
1933 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
1934 return CA_STATUS_FAILED;
1937 OIC_LOG(DEBUG, TAG, "request to get descriptor");
1938 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
1939 jni_mid_getDescriptor, jni_obj_cc_uuid);
1940 if (!jni_obj_descriptor)
1942 OIC_LOG(ERROR, TAG, "jni_obj_descriptor is null");
1943 return CA_STATUS_FAILED;
1946 OIC_LOG(DEBUG, TAG, "set value in descriptor");
1947 jclass jni_cid_descriptor = (*env)->FindClass(env,
1948 "android/bluetooth/BluetoothGattDescriptor");
1949 if (!jni_cid_descriptor)
1951 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
1952 return CA_STATUS_FAILED;
1955 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
1956 if (!jni_mid_setValue)
1958 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1959 return CA_STATUS_FAILED;
1962 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
1963 "ENABLE_NOTIFICATION_VALUE", "[B");
1964 if (!jni_fid_NotiValue)
1966 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
1967 return CA_STATUS_FAILED;
1970 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
1972 jboolean jni_setvalue = (*env)->CallBooleanMethod(
1973 env, jni_obj_descriptor, jni_mid_setValue,
1974 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
1977 OIC_LOG(DEBUG, TAG, "setValue success");
1981 OIC_LOG(ERROR, TAG, "setValue has failed");
1982 return CA_STATUS_FAILED;
1985 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
1988 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
1989 return CA_STATUS_FAILED;
1992 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
1993 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
1994 "(Landroid/bluetooth/"
1995 "BluetoothGattDescriptor;)Z");
1996 if (!jni_mid_writeDescriptor)
1998 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
1999 return CA_STATUS_FAILED;
2002 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2003 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2004 jni_obj_descriptor);
2007 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2011 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2012 return CA_STATUS_FAILED;
2015 return CA_STATUS_OK;
2018 void CALEClientCreateScanDeviceList(JNIEnv *env)
2020 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2021 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2023 ca_mutex_lock(g_deviceListMutex);
2024 // create new object array
2025 if (g_deviceList == NULL)
2027 OIC_LOG(DEBUG, TAG, "Create device list");
2029 g_deviceList = u_arraylist_create();
2031 ca_mutex_unlock(g_deviceListMutex);
2034 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2036 OIC_LOG(DEBUG, TAG, "IN - CALEClientAddScanDeviceToList");
2037 VERIFY_NON_NULL(device, TAG, "device is null");
2038 VERIFY_NON_NULL(env, TAG, "env is null");
2040 ca_mutex_lock(g_deviceListMutex);
2044 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2045 ca_mutex_unlock(g_deviceListMutex);
2046 return CA_STATUS_FAILED;
2049 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2050 if (!jni_remoteAddress)
2052 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2053 ca_mutex_unlock(g_deviceListMutex);
2054 return CA_STATUS_FAILED;
2057 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2060 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2061 ca_mutex_unlock(g_deviceListMutex);
2062 return CA_STATUS_FAILED;
2065 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2067 jobject gdevice = (*env)->NewGlobalRef(env, device);
2068 u_arraylist_add(g_deviceList, gdevice);
2069 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
2071 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2073 ca_mutex_unlock(g_deviceListMutex);
2075 OIC_LOG(DEBUG, TAG, "OUT - CALEClientAddScanDeviceToList");
2076 return CA_STATUS_OK;
2079 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2081 OIC_LOG(DEBUG, TAG, "IN - CALEClientIsDeviceInScanDeviceList");
2082 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2083 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2087 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2091 uint32_t length = u_arraylist_length(g_deviceList);
2092 for (uint32_t index = 0; index < length; index++)
2094 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2097 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2101 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2102 if (!jni_setAddress)
2104 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2108 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2111 OIC_LOG(ERROR, TAG, "setAddress is null");
2115 if (!strcmp(remoteAddress, setAddress))
2117 OIC_LOG(DEBUG, TAG, "the device is already set");
2118 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2122 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2125 OIC_LOG(DEBUG, TAG, "OUT - CALEClientIsDeviceInScanDeviceList");
2126 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2131 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2133 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2134 VERIFY_NON_NULL(env, TAG, "env is null");
2136 ca_mutex_lock(g_deviceListMutex);
2140 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2141 ca_mutex_unlock(g_deviceListMutex);
2142 return CA_STATUS_FAILED;
2145 uint32_t length = u_arraylist_length(g_deviceList);
2146 for (uint32_t index = 0; index < length; index++)
2148 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2151 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2154 (*env)->DeleteGlobalRef(env, jarrayObj);
2157 OICFree(g_deviceList);
2158 g_deviceList = NULL;
2160 ca_mutex_unlock(g_deviceListMutex);
2161 return CA_STATUS_OK;
2164 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2166 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2167 VERIFY_NON_NULL(address, TAG, "address is null");
2168 VERIFY_NON_NULL(env, TAG, "env is null");
2170 ca_mutex_lock(g_deviceListMutex);
2174 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2175 ca_mutex_unlock(g_deviceListMutex);
2176 return CA_STATUS_FAILED;
2179 uint32_t length = u_arraylist_length(g_deviceList);
2180 for (uint32_t index = 0; index < length; index++)
2182 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2185 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2186 ca_mutex_unlock(g_deviceListMutex);
2187 return CA_STATUS_FAILED;
2190 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2191 if (!jni_setAddress)
2193 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2194 ca_mutex_unlock(g_deviceListMutex);
2195 return CA_STATUS_FAILED;
2198 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2201 OIC_LOG(ERROR, TAG, "setAddress is null");
2202 ca_mutex_unlock(g_deviceListMutex);
2203 return CA_STATUS_FAILED;
2206 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2209 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2210 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2211 ca_mutex_unlock(g_deviceListMutex);
2212 return CA_STATUS_FAILED;
2215 if (!strcmp(setAddress, remoteAddress))
2217 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2218 (*env)->DeleteGlobalRef(env, jarrayObj);
2219 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2220 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2222 CALEClientReorderingList(index, g_deviceList);
2223 ca_mutex_unlock(g_deviceListMutex);
2224 return CA_STATUS_OK;
2226 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2227 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2230 ca_mutex_unlock(g_deviceListMutex);
2231 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2233 return CA_STATUS_OK;
2240 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2242 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2243 VERIFY_NON_NULL(env, TAG, "env is null");
2244 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2246 ca_mutex_lock(g_gattObjectMutex);
2248 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2249 if (!jni_remoteAddress)
2251 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2252 ca_mutex_unlock(g_gattObjectMutex);
2253 return CA_STATUS_FAILED;
2256 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2259 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2260 ca_mutex_unlock(g_gattObjectMutex);
2261 return CA_STATUS_FAILED;
2264 if (!CALEClientIsGattObjInList(env, remoteAddress))
2266 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2267 u_arraylist_add(g_gattObjectList, newGatt);
2268 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2271 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2272 ca_mutex_unlock(g_gattObjectMutex);
2273 return CA_STATUS_OK;
2276 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2278 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2279 VERIFY_NON_NULL(env, TAG, "env is null");
2280 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2282 uint32_t length = u_arraylist_length(g_gattObjectList);
2283 for (uint32_t index = 0; index < length; index++)
2286 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2289 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2293 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2294 if (!jni_setAddress)
2296 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2300 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2303 OIC_LOG(ERROR, TAG, "setAddress is null");
2307 if (!strcmp(remoteAddress, setAddress))
2309 OIC_LOG(DEBUG, TAG, "the device is already set");
2310 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2315 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2320 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2324 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2326 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2327 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2328 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2330 ca_mutex_lock(g_gattObjectMutex);
2331 uint32_t length = u_arraylist_length(g_gattObjectList);
2332 for (uint32_t index = 0; index < length; index++)
2334 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2337 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2338 ca_mutex_unlock(g_gattObjectMutex);
2342 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2343 if (!jni_setAddress)
2345 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2346 ca_mutex_unlock(g_gattObjectMutex);
2350 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2353 OIC_LOG(ERROR, TAG, "setAddress is null");
2354 ca_mutex_unlock(g_gattObjectMutex);
2358 if (!strcmp(remoteAddress, setAddress))
2360 OIC_LOG(DEBUG, TAG, "the device is already set");
2361 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2362 ca_mutex_unlock(g_gattObjectMutex);
2365 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2368 ca_mutex_unlock(g_gattObjectMutex);
2369 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2373 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2375 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2376 VERIFY_NON_NULL(env, TAG, "env is null");
2378 ca_mutex_lock(g_gattObjectMutex);
2379 if (!g_gattObjectList)
2381 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2382 ca_mutex_unlock(g_gattObjectMutex);
2383 return CA_STATUS_FAILED;
2386 uint32_t length = u_arraylist_length(g_gattObjectList);
2387 for (uint32_t index = 0; index < length; index++)
2389 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2392 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2395 (*env)->DeleteGlobalRef(env, jarrayObj);
2398 OICFree(g_gattObjectList);
2399 g_gattObjectList = NULL;
2400 ca_mutex_unlock(g_gattObjectMutex);
2401 return CA_STATUS_OK;
2404 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2406 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2407 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2408 VERIFY_NON_NULL(env, TAG, "env is null");
2410 ca_mutex_lock(g_gattObjectMutex);
2411 if (!g_gattObjectList)
2413 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2414 ca_mutex_unlock(g_gattObjectMutex);
2415 return CA_STATUS_FAILED;
2418 uint32_t length = u_arraylist_length(g_gattObjectList);
2419 for (uint32_t index = 0; index < length; index++)
2421 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2424 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2425 ca_mutex_unlock(g_gattObjectMutex);
2426 return CA_STATUS_FAILED;
2429 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2430 if (!jni_setAddress)
2432 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2433 ca_mutex_unlock(g_gattObjectMutex);
2434 return CA_STATUS_FAILED;
2437 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2440 OIC_LOG(ERROR, TAG, "setAddress is null");
2441 ca_mutex_unlock(g_gattObjectMutex);
2442 return CA_STATUS_FAILED;
2445 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2446 if (!jni_remoteAddress)
2448 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2449 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2450 ca_mutex_unlock(g_gattObjectMutex);
2451 return CA_STATUS_FAILED;
2454 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2457 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2458 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2459 ca_mutex_unlock(g_gattObjectMutex);
2460 return CA_STATUS_FAILED;
2463 if (!strcmp(setAddress, remoteAddress))
2465 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2466 (*env)->DeleteGlobalRef(env, jarrayObj);
2467 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2468 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2469 ca_mutex_unlock(g_gattObjectMutex);
2470 return CALEClientReorderingList(index, g_gattObjectList);
2472 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2473 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2476 ca_mutex_unlock(g_gattObjectMutex);
2477 OIC_LOG(DEBUG, TAG, "there are no target object");
2478 return CA_STATUS_OK;
2481 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2483 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2484 VERIFY_NON_NULL(addr, TAG, "addr is null");
2485 VERIFY_NON_NULL(env, TAG, "env is null");
2487 ca_mutex_lock(g_gattObjectMutex);
2488 if (!g_gattObjectList)
2490 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2491 ca_mutex_unlock(g_gattObjectMutex);
2492 return CA_STATUS_FAILED;
2495 uint32_t length = u_arraylist_length(g_gattObjectList);
2496 for (uint32_t index = 0; index < length; index++)
2498 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2501 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2502 ca_mutex_unlock(g_gattObjectMutex);
2503 return CA_STATUS_FAILED;
2506 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2507 if (!jni_setAddress)
2509 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2510 ca_mutex_unlock(g_gattObjectMutex);
2511 return CA_STATUS_FAILED;
2514 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2517 OIC_LOG(ERROR, TAG, "setAddress is null");
2518 ca_mutex_unlock(g_gattObjectMutex);
2519 return CA_STATUS_FAILED;
2522 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2525 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2526 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2527 ca_mutex_unlock(g_gattObjectMutex);
2528 return CA_STATUS_FAILED;
2531 if (!strcmp(setAddress, remoteAddress))
2533 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2534 (*env)->DeleteGlobalRef(env, jarrayObj);
2536 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2537 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2538 ca_mutex_unlock(g_gattObjectMutex);
2539 return CALEClientReorderingList(index, g_gattObjectList);
2541 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2542 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2545 ca_mutex_unlock(g_gattObjectMutex);
2546 OIC_LOG(DEBUG, TAG, "there are no target object");
2547 return CA_STATUS_FAILED;
2554 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2555 uint16_t notificationState, uint16_t sendState)
2557 VERIFY_NON_NULL(address, TAG, "address is null");
2559 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2562 OIC_LOG(ERROR, TAG, "out of memory");
2563 return CA_MEMORY_ALLOC_FAILED;
2566 if (strlen(address) > CA_MACADDR_SIZE)
2568 OIC_LOG(ERROR, TAG, "address is not proper");
2570 return CA_STATUS_FAILED;
2573 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2574 newstate->connectedState = connectedState;
2575 newstate->notificationState = notificationState;
2576 newstate->sendState = sendState;
2577 return CALEClientAddDeviceStateToList(newstate);
2580 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2582 VERIFY_NON_NULL(state, TAG, "state is null");
2584 ca_mutex_lock(g_deviceStateListMutex);
2586 if (!g_deviceStateList)
2588 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2589 ca_mutex_unlock(g_deviceStateListMutex);
2590 return CA_STATUS_FAILED;
2593 if (CALEClientIsDeviceInList(state->address))
2595 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2598 OIC_LOG(ERROR, TAG, "curState is null");
2599 ca_mutex_unlock(g_deviceStateListMutex);
2600 return CA_STATUS_FAILED;
2603 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2605 state->notificationState = curState->notificationState;
2608 // delete previous state for update new state
2609 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2610 if (CA_STATUS_OK != res)
2612 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2613 ca_mutex_unlock(g_deviceStateListMutex);
2617 u_arraylist_add(g_deviceStateList, state); // update new state
2618 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2619 state->connectedState, state->notificationState);
2621 ca_mutex_unlock(g_deviceStateListMutex);
2622 return CA_STATUS_OK;
2625 bool CALEClientIsDeviceInList(const char* remoteAddress)
2627 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2629 if (!g_deviceStateList)
2631 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2635 uint32_t length = u_arraylist_length(g_deviceStateList);
2636 for (uint32_t index = 0; index < length; index++)
2638 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2641 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2645 if (!strcmp(remoteAddress, state->address))
2647 OIC_LOG(DEBUG, TAG, "the device is already set");
2656 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2660 CAResult_t CALEClientRemoveAllDeviceState()
2662 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2664 ca_mutex_lock(g_deviceStateListMutex);
2665 if (!g_deviceStateList)
2667 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2668 ca_mutex_unlock(g_deviceStateListMutex);
2669 return CA_STATUS_FAILED;
2672 uint32_t length = u_arraylist_length(g_deviceStateList);
2673 for (uint32_t index = 0; index < length; index++)
2675 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2678 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2684 OICFree(g_deviceStateList);
2685 g_deviceStateList = NULL;
2686 ca_mutex_unlock(g_deviceStateListMutex);
2688 return CA_STATUS_OK;
2691 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2693 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2694 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2696 if (!g_deviceStateList)
2698 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2699 return CA_STATUS_FAILED;
2702 uint32_t length = u_arraylist_length(g_deviceStateList);
2703 for (uint32_t index = 0; index < length; index++)
2705 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2708 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2712 if (!strcmp(state->address, remoteAddress))
2714 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2717 CAResult_t res = CALEClientReorderingList(index, g_deviceStateList);
2718 if(CA_STATUS_OK != res)
2720 OIC_LOG(ERROR, TAG, "CALEClientReorderingList has failed");
2723 return CA_STATUS_OK;
2727 return CA_STATUS_FAILED;
2730 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2732 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2733 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2735 if (!g_deviceStateList)
2737 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2741 uint32_t length = u_arraylist_length(g_deviceStateList);
2742 for (uint32_t index = 0; index < length; index++)
2744 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2747 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2751 if (!strcmp(state->address, remoteAddress))
2753 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2760 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2762 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2763 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2765 ca_mutex_lock(g_deviceStateListMutex);
2766 if (!g_deviceStateList)
2768 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2769 ca_mutex_unlock(g_deviceStateListMutex);
2773 uint32_t length = u_arraylist_length(g_deviceStateList);
2774 for (uint32_t index = 0; index < length; index++)
2776 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2779 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2783 if (!strcmp(state->address, remoteAddress))
2785 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2787 if (STATE_CONNECTED == state->connectedState)
2789 ca_mutex_unlock(g_deviceStateListMutex);
2794 ca_mutex_unlock(g_deviceStateListMutex);
2799 ca_mutex_unlock(g_deviceStateListMutex);
2803 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2805 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2806 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2808 ca_mutex_lock(g_deviceStateListMutex);
2809 if (!g_deviceStateList)
2811 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2812 ca_mutex_unlock(g_deviceStateListMutex);
2816 uint32_t length = u_arraylist_length(g_deviceStateList);
2817 for (uint32_t index = 0; index < length; index++)
2819 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2822 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2826 if (!strcmp(state->address, remoteAddress))
2828 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2830 if (STATE_CHARACTER_SET == state->notificationState)
2832 ca_mutex_unlock(g_deviceStateListMutex);
2837 ca_mutex_unlock(g_deviceStateListMutex);
2843 ca_mutex_unlock(g_deviceStateListMutex);
2847 void CALEClientCreateDeviceList()
2849 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2851 // create new object array
2852 if (!g_gattObjectList)
2854 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2856 g_gattObjectList = u_arraylist_create();
2859 if (!g_deviceStateList)
2861 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2863 g_deviceStateList = u_arraylist_create();
2868 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2870 g_deviceList = u_arraylist_create();
2874 CAResult_t CALEClientReorderingList(uint32_t index, u_arraylist_t *list)
2878 OIC_LOG(ERROR, TAG, "list is null");
2879 return CA_STATUS_FAILED;
2882 if (index >= list->length)
2884 OIC_LOG(ERROR, TAG, "index is not available");
2885 return CA_STATUS_FAILED;
2888 if (index < list->length - 1)
2890 memmove(&list->data[index], &list->data[index + 1],
2891 (list->length - index - 1) * sizeof(void *));
2897 return CA_STATUS_OK;
2901 * Check Sent Count for remove g_sendBuffer
2903 void CALEClientUpdateSendCnt(JNIEnv *env)
2905 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2907 ca_mutex_lock(g_threadMutex);
2911 if (g_targetCnt <= g_currentSentCnt)
2914 g_currentSentCnt = 0;
2918 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2919 g_sendBuffer = NULL;
2921 // notity the thread
2922 ca_cond_signal(g_threadCond);
2923 CALEClientSetSendFinishFlag(true);
2924 OIC_LOG(DEBUG, TAG, "set signal for send data");
2927 ca_mutex_unlock(g_threadMutex);
2930 CAResult_t CALEClientInitGattMutexVaraibles()
2932 OIC_LOG(DEBUG, TAG, "IN");
2934 if (NULL == g_bleReqRespClientCbMutex)
2936 g_bleReqRespClientCbMutex = ca_mutex_new();
2937 if (NULL == g_bleReqRespClientCbMutex)
2939 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2940 return CA_STATUS_FAILED;
2944 if (NULL == g_bleServerBDAddressMutex)
2946 g_bleServerBDAddressMutex = ca_mutex_new();
2947 if (NULL == g_bleServerBDAddressMutex)
2949 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2950 return CA_STATUS_FAILED;
2954 if (NULL == g_threadMutex)
2956 g_threadMutex = ca_mutex_new();
2957 if (NULL == g_threadMutex)
2959 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2960 return CA_STATUS_FAILED;
2964 if (NULL == g_threadSendMutex)
2966 g_threadSendMutex = ca_mutex_new();
2967 if (NULL == g_threadSendMutex)
2969 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2970 return CA_STATUS_FAILED;
2974 if (NULL == g_deviceListMutex)
2976 g_deviceListMutex = ca_mutex_new();
2977 if (NULL == g_deviceListMutex)
2979 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2980 return CA_STATUS_FAILED;
2984 if (NULL == g_gattObjectMutex)
2986 g_gattObjectMutex = ca_mutex_new();
2987 if (NULL == g_gattObjectMutex)
2989 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2990 return CA_STATUS_FAILED;
2994 if (NULL == g_deviceStateListMutex)
2996 g_deviceStateListMutex = ca_mutex_new();
2997 if (NULL == g_deviceStateListMutex)
2999 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3000 return CA_STATUS_FAILED;
3004 if (NULL == g_SendFinishMutex)
3006 g_SendFinishMutex = ca_mutex_new();
3007 if (NULL == g_SendFinishMutex)
3009 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3010 return CA_STATUS_FAILED;
3014 OIC_LOG(DEBUG, TAG, "OUT");
3015 return CA_STATUS_OK;
3018 void CALEClientTerminateGattMutexVariables()
3020 OIC_LOG(DEBUG, TAG, "IN");
3022 ca_mutex_free(g_bleReqRespClientCbMutex);
3023 g_bleReqRespClientCbMutex = NULL;
3025 ca_mutex_free(g_bleServerBDAddressMutex);
3026 g_bleServerBDAddressMutex = NULL;
3028 ca_mutex_free(g_threadMutex);
3029 g_threadMutex = NULL;
3031 ca_mutex_free(g_threadSendMutex);
3032 g_threadSendMutex = NULL;
3034 ca_mutex_free(g_deviceListMutex);
3035 g_deviceListMutex = NULL;
3037 ca_mutex_free(g_SendFinishMutex);
3038 g_SendFinishMutex = NULL;
3040 OIC_LOG(DEBUG, TAG, "OUT");
3043 void CALEClientSetSendFinishFlag(bool flag)
3045 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3047 ca_mutex_lock(g_SendFinishMutex);
3048 g_isFinishedSendData = flag;
3049 ca_mutex_unlock(g_SendFinishMutex);
3056 CAResult_t CAStartLEGattClient()
3058 CAResult_t res = CALEClientStartMulticastServer();
3059 if (CA_STATUS_OK != res)
3061 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3065 g_isStartedLEClient = true;
3071 void CAStopLEGattClient()
3073 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3077 OIC_LOG(ERROR, TAG, "g_jvm is null");
3081 bool isAttached = false;
3083 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3086 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3087 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3091 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3097 CAResult_t ret = CALEClientDisconnectAll(env);
3098 if (CA_STATUS_OK != ret)
3100 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3103 ret = CALEClientStopScan();
3104 if(CA_STATUS_OK != ret)
3106 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3109 ca_cond_signal(g_threadCond);
3113 (*g_jvm)->DetachCurrentThread(g_jvm);
3118 void CATerminateLEGattClient()
3120 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3121 CALEClientTerminate();
3124 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
3125 uint32_t dataLen, CALETransferType_t type,
3128 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3129 VERIFY_NON_NULL(data, TAG, "data is null");
3130 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3132 if (LE_UNICAST != type || position < 0)
3134 OIC_LOG(ERROR, TAG, "this request is not unicast");
3135 return CA_STATUS_INVALID_PARAM;
3138 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3141 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t dataLen)
3143 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3144 VERIFY_NON_NULL(data, TAG, "data is null");
3146 return CALEClientSendMulticastMessage(data, dataLen);
3149 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3151 OIC_LOG(DEBUG, TAG, "IN");
3153 ca_mutex_lock(g_bleReqRespClientCbMutex);
3154 g_CABLEClientDataReceivedCallback = callback;
3155 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3157 OIC_LOG(DEBUG, TAG, "OUT");
3160 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3162 OIC_LOG(DEBUG, TAG, "IN");
3164 CALEClientInitialize(handle);
3166 OIC_LOG(DEBUG, TAG, "OUT");
3169 CAResult_t CAGetLEAddress(char **local_address)
3171 VERIFY_NON_NULL(local_address, TAG, "local_address");
3172 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3173 return CA_NOT_SUPPORTED;
3176 JNIEXPORT void JNICALL
3177 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3180 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3181 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3182 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3183 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3185 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3188 JNIEXPORT void JNICALL
3189 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3192 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3193 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3194 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3195 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3197 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3200 JNIEXPORT void JNICALL
3201 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3204 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3205 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3206 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3208 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3209 if (CA_STATUS_OK != res)
3211 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3216 * Class: org_iotivity_ca_jar_caleinterface
3217 * Method: CALeGattConnectionStateChangeCallback
3218 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3220 JNIEXPORT void JNICALL
3221 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3227 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3229 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3230 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3231 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3233 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3235 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3241 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3244 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3245 STATE_CHARACTER_NO_CHANGE,
3247 if (CA_STATUS_OK != res)
3249 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3250 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3253 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3256 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3257 if (CA_STATUS_OK != res)
3259 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3263 res = CALEClientDiscoverServices(env, gatt);
3264 if (CA_STATUS_OK != res)
3266 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3270 else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
3272 CAResult_t res = CALEClientStartScan();
3273 if (CA_STATUS_OK != res)
3275 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3278 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3281 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3284 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3287 res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3288 STATE_CHARACTER_NO_CHANGE,
3290 if (CA_STATUS_OK != res)
3292 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3294 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3297 res = CALEClientGattClose(env, gatt);
3298 if (CA_STATUS_OK != res)
3300 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3306 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3309 OIC_LOG(ERROR, TAG, "jni_address is null");
3314 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3317 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3318 STATE_CHARACTER_NO_CHANGE,
3320 if (CA_STATUS_OK != res)
3322 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3325 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3327 CAResult_t res = CALEClientGattClose(env, gatt);
3328 if (CA_STATUS_OK != res)
3330 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3340 CALEClientSendFinish(env, gatt);
3345 * Class: org_iotivity_ca_jar_caleinterface
3346 * Method: CALeGattServicesDiscoveredCallback
3347 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3349 JNIEXPORT void JNICALL
3350 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3355 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3356 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3357 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3358 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3360 if (0 != status) // discovery error
3362 CALEClientSendFinish(env, gatt);
3366 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3369 CALEClientSendFinish(env, gatt);
3373 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3376 CALEClientSendFinish(env, gatt);
3380 if (!CALEClientIsSetCharacteristic(address))
3382 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3385 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3389 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3390 if (!jni_obj_GattCharacteristic)
3392 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3396 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3397 jni_obj_GattCharacteristic);
3398 if (CA_STATUS_OK != res)
3400 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3404 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3405 if (CA_STATUS_OK != res)
3407 OIC_LOG(INFO, TAG, "Descriptor of the uuid is not found");
3408 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3409 if (CA_STATUS_OK != res)
3411 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3416 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3418 if (CA_STATUS_OK != res)
3420 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3426 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3427 if (CA_STATUS_OK != res)
3429 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3433 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3438 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3439 CALEClientSendFinish(env, gatt);
3444 * Class: org_iotivity_ca_jar_caleinterface
3445 * Method: CALeGattCharacteristicWritjclasseCallback
3446 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3448 JNIEXPORT void JNICALL
3449 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3450 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3453 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3454 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3455 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3456 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3459 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3461 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3463 // send success & signal
3464 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3470 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3476 if (GATT_SUCCESS != status) // error case
3478 OIC_LOG(ERROR, TAG, "send failure");
3479 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3481 if (CA_STATUS_OK != res)
3483 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3485 CALEClientSendFinish(env, gatt);
3489 OIC_LOG(DEBUG, TAG, "send success");
3490 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3491 STATE_SEND_SUCCESS);
3492 if (CA_STATUS_OK != res)
3494 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3496 CALEClientUpdateSendCnt(env);
3499 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3505 CALEClientSendFinish(env, gatt);
3510 * Class: org_iotivity_ca_jar_caleinterface
3511 * Method: CALeGattCharacteristicChangedCallback
3512 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3514 JNIEXPORT void JNICALL
3515 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3516 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3518 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3519 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3520 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3521 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3522 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3524 // get Byte Array and covert to char*
3525 jint length = (*env)->GetArrayLength(env, data);
3528 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3530 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %s",
3531 jni_byte_responseData);
3533 char* receivedData = (char*) OICMalloc(sizeof(char) * length + 1);
3536 OIC_LOG(ERROR, TAG, "recevicedData is null");
3540 memcpy(receivedData, (const char*) jni_byte_responseData, length);
3541 receivedData[length] = '\0';
3542 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3544 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3547 OIC_LOG(ERROR, TAG, "jni_address is null");
3548 OICFree(receivedData);
3552 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3555 OIC_LOG(ERROR, TAG, "address is null");
3556 OICFree(receivedData);
3560 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d",
3561 receivedData, length);
3563 ca_mutex_lock(g_bleServerBDAddressMutex);
3564 uint32_t sentLength = 0;
3565 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3567 ca_mutex_unlock(g_bleServerBDAddressMutex);
3569 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3573 * Class: org_iotivity_ca_jar_caleinterface
3574 * Method: CALeGattDescriptorWriteCallback
3575 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3577 JNIEXPORT void JNICALL
3578 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3582 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3583 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3584 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3585 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3587 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3588 if (CA_STATUS_OK != res)
3590 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3598 CALEClientSendFinish(env, gatt);