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 "cathreadpool.h" /* for thread pool */
36 #include "uarraylist.h"
37 #include "org_iotivity_ca_CaLeClientInterface.h"
39 #define TAG PCF("CA_LE_CLIENT")
41 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
42 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
43 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
44 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
47 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
48 static u_arraylist_t *g_gattObjectList = NULL;
49 static u_arraylist_t *g_deviceStateList = NULL;
51 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
52 static CABLEErrorHandleCallback g_clientErrorCallback;
53 static ca_thread_pool_t g_threadPoolHandle = NULL;
54 static jobject g_leScanCallback = NULL;
55 static jobject g_leGattCallback = NULL;
56 static jobject g_context = NULL;
57 static jobjectArray g_uuidList = NULL;
59 // it will be prevent to start send logic when adapter has stopped.
60 static bool g_isStartedLEClient = false;
61 static bool g_isStartedMulticastServer = false;
62 static bool g_isStartedScan = false;
64 static jbyteArray g_sendBuffer = NULL;
65 static uint32_t g_targetCnt = 0;
66 static uint32_t g_currentSentCnt = 0;
67 static bool g_isFinishedSendData = false;
68 static ca_mutex g_SendFinishMutex = NULL;
69 static ca_mutex g_threadMutex = NULL;
70 static ca_cond g_threadCond = NULL;
72 static ca_mutex g_threadSendMutex = NULL;
74 static ca_mutex g_bleReqRespClientCbMutex = NULL;
75 static ca_mutex g_bleServerBDAddressMutex = NULL;
77 static ca_mutex g_deviceListMutex = NULL;
78 static ca_mutex g_gattObjectMutex = NULL;
79 static ca_mutex g_deviceStateListMutex = NULL;
81 static CABLEClientDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
84 void CALEClientJniInit()
86 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
87 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
90 void CALEClientJNISetContext()
92 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
93 g_context = (jobject) CANativeJNIGetContext();
96 CAResult_t CALECreateJniInterfaceObject()
98 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
102 OIC_LOG(ERROR, TAG, "g_context is null");
103 return CA_STATUS_FAILED;
108 OIC_LOG(ERROR, TAG, "g_jvm is null");
109 return CA_STATUS_FAILED;
112 bool isAttached = false;
114 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
117 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
118 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
122 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
123 return CA_STATUS_FAILED;
128 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
129 if (!jni_LEInterface)
131 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
135 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
136 "(Landroid/content/Context;)V");
137 if (!LeInterfaceConstructorMethod)
139 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
143 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
144 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
148 (*g_jvm)->DetachCurrentThread(g_jvm);
157 (*g_jvm)->DetachCurrentThread(g_jvm);
160 return CA_STATUS_FAILED;
163 CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
165 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
171 OIC_LOG(ERROR, TAG, "g_jvm is null");
172 return CA_STATUS_FAILED;
175 bool isAttached = false;
177 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
180 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
181 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
185 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
186 return CA_STATUS_FAILED;
191 CAResult_t ret = CALECheckPlatformVersion(env, 18);
192 if (CA_STATUS_OK != ret)
194 OIC_LOG(ERROR, TAG, "it is not supported");
198 (*g_jvm)->DetachCurrentThread(g_jvm);
204 g_threadPoolHandle = handle;
206 ret = CALEClientInitGattMutexVaraibles();
207 if (CA_STATUS_OK != ret)
209 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
210 CALEClientTerminateGattMutexVariables();
214 (*g_jvm)->DetachCurrentThread(g_jvm);
220 // init mutex for send logic
221 g_threadCond = ca_cond_new();
223 CALEClientCreateDeviceList();
224 CALEClientJNISetContext();
226 ret = CALEClientCreateUUIDList();
227 if (CA_STATUS_OK != ret)
229 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
233 (*g_jvm)->DetachCurrentThread(g_jvm);
239 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
240 if (CA_STATUS_OK != ret)
242 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
246 (*g_jvm)->DetachCurrentThread(g_jvm);
251 g_isStartedLEClient = true;
256 void CALEClientTerminate()
258 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
262 OIC_LOG(ERROR, TAG, "g_jvm is null");
266 bool isAttached = false;
268 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
271 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
272 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
276 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
282 if (g_leScanCallback)
284 (*env)->DeleteGlobalRef(env, g_leScanCallback);
287 if (g_leGattCallback)
289 (*env)->DeleteGlobalRef(env, g_leGattCallback);
294 (*env)->DeleteGlobalRef(env, g_sendBuffer);
299 (*env)->DeleteGlobalRef(env, g_uuidList);
302 CAResult_t ret = CALEClientRemoveAllDeviceState();
303 if (CA_STATUS_OK != ret)
305 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
308 ret = CALEClientRemoveAllScanDevices(env);
309 if (CA_STATUS_OK != ret)
311 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
314 ret = CALEClientRemoveAllGattObjs(env);
315 if (CA_STATUS_OK != ret)
317 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
320 g_isStartedMulticastServer = false;
321 g_isStartedScan = false;
322 CALEClientSetSendFinishFlag(false);
324 CALEClientTerminateGattMutexVariables();
326 ca_cond_free(g_threadCond);
330 (*g_jvm)->DetachCurrentThread(g_jvm);
334 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
336 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
337 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
341 CAResult_t res = CALEClientDisconnect(env, gatt);
342 if (CA_STATUS_OK != res)
344 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
347 CALEClientUpdateSendCnt(env);
350 CAResult_t CALEClientSendUnicastMessage(const char* address, const char* data,
351 const uint32_t dataLen)
353 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %s)", address, data);
354 VERIFY_NON_NULL(address, TAG, "address is null");
355 VERIFY_NON_NULL(data, TAG, "data is null");
357 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
360 CAResult_t CALEClientSendMulticastMessage(const char* data, const uint32_t dataLen)
362 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%s)", data);
363 VERIFY_NON_NULL(data, TAG, "data is null");
367 OIC_LOG(ERROR, TAG, "g_jvm is null");
368 return CA_STATUS_FAILED;
371 bool isAttached = false;
373 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
376 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
377 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
381 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
382 return CA_STATUS_FAILED;
387 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
388 if (CA_STATUS_OK != ret)
390 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
395 (*g_jvm)->DetachCurrentThread(g_jvm);
401 CAResult_t CALEClientStartUnicastServer(const char* address)
403 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
405 return CA_NOT_SUPPORTED;
408 CAResult_t CALEClientStartMulticastServer()
410 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
412 if (g_isStartedMulticastServer)
414 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
415 return CA_STATUS_FAILED;
420 OIC_LOG(ERROR, TAG, "g_jvm is null");
421 return CA_STATUS_FAILED;
424 bool isAttached = false;
426 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
429 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
430 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
434 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
435 return CA_STATUS_FAILED;
440 g_isStartedMulticastServer = true;
441 CAResult_t ret = CALEClientStartScan();
442 if (CA_STATUS_OK != ret)
444 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
449 (*g_jvm)->DetachCurrentThread(g_jvm);
455 void CALEClientStopUnicastServer()
457 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
460 void CALEClientStopMulticastServer()
462 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
463 g_isStartedMulticastServer = false;
464 CAResult_t res = CALEClientStopScan();
465 if (CA_STATUS_OK != res)
467 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
472 void CALEClientSetCallback(CAPacketReceiveCallback callback)
474 g_packetReceiveCallback = callback;
477 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
479 g_clientErrorCallback = callback;
482 CAResult_t CALEClientGetInterfaceInfo(char **address)
484 OIC_LOG(INFO, TAG, "CALEClientGetInterfaceInfo is not supported");
485 return CA_NOT_SUPPORTED;
488 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const char* data,
489 const uint32_t dataLen)
491 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %s", address,
493 VERIFY_NON_NULL(address, TAG, "address is null");
494 VERIFY_NON_NULL(data, TAG, "data is null");
498 OIC_LOG(ERROR, TAG, "g_jvm is null");
499 return CA_STATUS_FAILED;
502 bool isAttached = false;
504 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
507 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
508 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
511 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
512 return CA_STATUS_FAILED;
517 ca_mutex_lock(g_threadSendMutex);
519 CAResult_t ret = CA_STATUS_OK;
520 if (g_context && g_deviceList)
522 uint32_t length = u_arraylist_length(g_deviceList);
523 for (uint32_t index = 0; index < length; index++)
525 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
528 OIC_LOG(ERROR, TAG, "jarrayObj is null");
532 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
535 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
539 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
542 OIC_LOG(ERROR, TAG, "setAddress is null");
546 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
548 if (!strcmp(setAddress, address))
550 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
552 // connect to gatt server
553 ret = CALEClientStopScan();
554 if (CA_STATUS_OK != ret)
556 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
562 (*env)->DeleteGlobalRef(env, g_sendBuffer);
564 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
565 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
566 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
568 ret = CALEClientSendData(env, jarrayObj);
569 if (CA_STATUS_OK != ret)
571 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
575 OIC_LOG(INFO, TAG, "wake up");
578 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
584 (*g_jvm)->DetachCurrentThread(g_jvm);
587 ret = CALECheckSendState(address);
588 if(CA_STATUS_OK != ret)
590 OIC_LOG(ERROR, TAG, "send has failed");
594 // start LE Scan again
595 ret = CALEClientStartScan();
596 if (CA_STATUS_OK != ret)
598 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
599 ca_mutex_unlock(g_threadSendMutex);
603 ca_mutex_unlock(g_threadSendMutex);
604 OIC_LOG(INFO, TAG, "unicast - send success");
610 // start LE Scan again
611 ret = CALEClientStartScan();
612 if (CA_STATUS_OK != ret)
614 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
615 ca_mutex_unlock(g_threadSendMutex);
621 (*g_jvm)->DetachCurrentThread(g_jvm);
623 ca_mutex_unlock(g_threadSendMutex);
624 return CA_SEND_FAILED;
627 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const char* data,
628 const uint32_t dataLen)
630 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s, %d", data, dataLen);
631 VERIFY_NON_NULL(data, TAG, "data is null");
632 VERIFY_NON_NULL(env, TAG, "env is null");
636 OIC_LOG(ERROR, TAG, "g_deviceList is null");
637 return CA_STATUS_FAILED;
640 ca_mutex_lock(g_threadSendMutex);
642 CALEClientSetSendFinishFlag(false);
644 OIC_LOG(DEBUG, TAG, "set byteArray for data");
647 (*env)->DeleteGlobalRef(env, g_sendBuffer);
649 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
650 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
651 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
653 // connect to gatt server
654 CAResult_t res = CALEClientStopScan();
655 if (CA_STATUS_OK != res)
657 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
658 ca_mutex_unlock(g_threadSendMutex);
662 uint32_t length = u_arraylist_length(g_deviceList);
663 g_targetCnt = length;
669 for (uint32_t index = 0; index < length; index++)
671 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
674 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
678 res = CALEClientSendData(env, jarrayObj);
679 if (res != CA_STATUS_OK)
681 OIC_LOG(ERROR, TAG, "BT device[%d] - send has failed");
684 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
687 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
691 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
694 OIC_LOG(ERROR, TAG, "address is not available");
698 res = CALECheckSendState(address);
699 if (CA_STATUS_OK != res)
701 OIC_LOG_V(INFO, TAG, "multicast : send has failed for this device[%s]", address);
702 g_clientErrorCallback(address, data, dataLen, res);
703 (*env)->ReleaseStringUTFChars(env, jni_address, address);
707 (*env)->ReleaseStringUTFChars(env, jni_address, address);
710 OIC_LOG(DEBUG, TAG, "connection routine is finished");
712 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
713 if (!g_isFinishedSendData)
715 ca_mutex_lock(g_threadMutex);
716 ca_cond_wait(g_threadCond, g_threadMutex);
717 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
718 ca_mutex_unlock(g_threadMutex);
721 // start LE Scan again
722 res = CALEClientStartScan();
723 if (CA_STATUS_OK != res)
725 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
726 ca_mutex_unlock(g_threadSendMutex);
730 ca_mutex_unlock(g_threadSendMutex);
731 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
735 res = CALEClientStartScan();
736 if (CA_STATUS_OK != res)
738 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
739 ca_mutex_unlock(g_threadSendMutex);
743 ca_mutex_unlock(g_threadSendMutex);
744 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
745 return CA_SEND_FAILED;
748 CAResult_t CALECheckSendState(const char* address)
750 VERIFY_NON_NULL(address, TAG, "address is null");
752 ca_mutex_lock(g_deviceStateListMutex);
753 CALEState_t* state = CALEClientGetStateInfo(address);
756 OIC_LOG(ERROR, TAG, "state is null");
757 ca_mutex_unlock(g_deviceStateListMutex);
758 return CA_SEND_FAILED;
761 if (STATE_SEND_SUCCESS != state->sendState)
763 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
764 ca_mutex_unlock(g_deviceStateListMutex);
765 return CA_SEND_FAILED;
767 ca_mutex_unlock(g_deviceStateListMutex);
771 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
773 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
774 VERIFY_NON_NULL(device, TAG, "device is null");
775 VERIFY_NON_NULL(env, TAG, "env is null");
777 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
780 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
781 return CA_STATUS_FAILED;
784 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
787 OIC_LOG(ERROR, TAG, "address is not available");
788 return CA_STATUS_FAILED;
791 ca_mutex_lock(g_deviceStateListMutex);
792 CALEState_t* state = CALEClientGetStateInfo(address);
793 ca_mutex_unlock(g_deviceStateListMutex);
796 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
797 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
798 if (CA_STATUS_OK != ret)
800 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
801 (*env)->ReleaseStringUTFChars(env, jni_address, address);
807 if (STATE_CONNECTED == state->connectedState)
809 OIC_LOG(INFO, TAG, "GATT has already connected");
810 jobject gatt = CALEClientGetGattObjInList(env, address);
813 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
814 (*env)->ReleaseStringUTFChars(env, jni_address, address);
815 return CA_STATUS_FAILED;
818 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
819 if (CA_STATUS_OK != ret)
821 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
822 (*env)->ReleaseStringUTFChars(env, jni_address, address);
828 OIC_LOG(DEBUG, TAG, "start to connect LE");
829 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
830 if (CA_STATUS_OK != ret)
832 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
833 (*env)->ReleaseStringUTFChars(env, jni_address, address);
839 (*env)->ReleaseStringUTFChars(env, jni_address, address);
843 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
845 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
846 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
848 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
849 if (!jni_cid_gattdevice_list)
851 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
855 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
856 "()Landroid/bluetooth/BluetoothDevice;");
857 if (!jni_mid_getDevice)
859 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
863 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
866 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
870 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
873 OIC_LOG(ERROR, TAG, "jni_address is null");
883 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
886 OIC_LOG(DEBUG, TAG, "Gatt Close");
887 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
888 VERIFY_NON_NULL(env, TAG, "env is null");
890 // get BluetoothGatt class
891 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
892 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
893 if (!jni_cid_BluetoothGatt)
895 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
896 return CA_STATUS_FAILED;
899 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
900 if (!jni_mid_closeGatt)
902 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
906 // call disconnect gatt method
907 OIC_LOG(DEBUG, TAG, "request to close GATT");
908 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
910 if ((*env)->ExceptionCheck(env))
912 OIC_LOG(ERROR, TAG, "closeGATT has failed");
913 (*env)->ExceptionDescribe(env);
914 (*env)->ExceptionClear(env);
915 return CA_STATUS_FAILED;
921 CAResult_t CALEClientStartScan()
923 if (!g_isStartedMulticastServer)
925 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
926 return CA_STATUS_FAILED;
929 if (!g_isStartedLEClient)
931 OIC_LOG(ERROR, TAG, "LE client is not started");
932 return CA_STATUS_FAILED;
937 OIC_LOG(ERROR, TAG, "g_jvm is null");
938 return CA_STATUS_FAILED;
943 OIC_LOG(INFO, TAG, "scanning is already started");
947 bool isAttached = false;
949 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
952 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
954 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
957 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
958 return CA_STATUS_FAILED;
963 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
965 CAResult_t ret = CA_STATUS_OK;
966 // scan gatt server with UUID
967 if (g_leScanCallback && g_uuidList)
970 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
971 if(CA_STATUS_OK != ret)
973 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
976 ret = CALEClientStartScanImpl(env, g_leScanCallback);
977 if (CA_STATUS_OK != ret)
979 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
986 (*g_jvm)->DetachCurrentThread(g_jvm);
992 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
994 VERIFY_NON_NULL(callback, TAG, "callback is null");
995 VERIFY_NON_NULL(env, TAG, "env is null");
997 if (!CALEIsEnableBTAdapter(env))
999 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1000 return CA_ADAPTER_NOT_ENABLED;
1003 // get default bt adapter class
1004 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1005 if (!jni_cid_BTAdapter)
1007 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1008 return CA_STATUS_FAILED;
1011 // get remote bt adapter method
1012 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1013 "getDefaultAdapter",
1014 METHODID_OBJECTNONPARAM);
1015 if (!jni_mid_getDefaultAdapter)
1017 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1018 return CA_STATUS_FAILED;
1021 // get start le scan method
1022 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1023 "(Landroid/bluetooth/BluetoothAdapter$"
1024 "LeScanCallback;)Z");
1025 if (!jni_mid_startLeScan)
1027 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1028 return CA_STATUS_FAILED;
1031 // gat bt adapter object
1032 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1033 jni_mid_getDefaultAdapter);
1034 if (!jni_obj_BTAdapter)
1036 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1037 return CA_STATUS_FAILED;
1040 // call start le scan method
1041 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1042 jni_mid_startLeScan, callback);
1043 if (!jni_obj_startLeScan)
1045 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1046 return CA_STATUS_FAILED;
1050 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1051 g_isStartedScan = true;
1054 return CA_STATUS_OK;
1057 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1059 VERIFY_NON_NULL(callback, TAG, "callback is null");
1060 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1061 VERIFY_NON_NULL(env, TAG, "env is null");
1063 if (!CALEIsEnableBTAdapter(env))
1065 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1066 return CA_ADAPTER_NOT_ENABLED;
1069 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1070 if (!jni_cid_BTAdapter)
1072 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1073 return CA_STATUS_FAILED;
1076 // get remote bt adapter method
1077 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1078 "getDefaultAdapter",
1079 METHODID_OBJECTNONPARAM);
1080 if (!jni_mid_getDefaultAdapter)
1082 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1083 return CA_STATUS_FAILED;
1086 // get start le scan method
1087 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1088 "([Ljava/util/UUID;Landroid/bluetooth/"
1089 "BluetoothAdapter$LeScanCallback;)Z");
1090 if (!jni_mid_startLeScan)
1092 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1093 return CA_STATUS_FAILED;
1096 // get bt adapter object
1097 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1098 jni_mid_getDefaultAdapter);
1099 if (!jni_obj_BTAdapter)
1101 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1102 return CA_STATUS_FAILED;
1105 // call start le scan method
1106 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1107 jni_mid_startLeScan, uuids, callback);
1108 if (!jni_obj_startLeScan)
1110 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1111 return CA_STATUS_FAILED;
1115 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1116 g_isStartedScan = true;
1119 return CA_STATUS_OK;
1122 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1124 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1125 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1128 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1131 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1135 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1136 "(Ljava/lang/String;)"
1137 "Ljava/util/UUID;");
1138 if (!jni_mid_fromString)
1140 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1144 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1145 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1149 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1153 return jni_obj_uuid;
1156 CAResult_t CALEClientStopScan()
1160 OIC_LOG(ERROR, TAG, "g_jvm is null");
1161 return CA_STATUS_FAILED;
1164 if (!g_isStartedScan)
1166 OIC_LOG(INFO, TAG, "scanning is already stopped");
1167 return CA_STATUS_OK;
1170 bool isAttached = false;
1172 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1175 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1176 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1179 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1180 return CA_STATUS_FAILED;
1185 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1186 if (CA_STATUS_OK != ret)
1188 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1192 g_isStartedScan = false;
1197 (*g_jvm)->DetachCurrentThread(g_jvm);
1203 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1205 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1206 VERIFY_NON_NULL(callback, TAG, "callback is null");
1207 VERIFY_NON_NULL(env, TAG, "env is null");
1209 if (!CALEIsEnableBTAdapter(env))
1211 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1212 return CA_ADAPTER_NOT_ENABLED;
1215 // get default bt adapter class
1216 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1217 if (!jni_cid_BTAdapter)
1219 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1220 return CA_STATUS_FAILED;
1223 // get remote bt adapter method
1224 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1225 "getDefaultAdapter",
1226 METHODID_OBJECTNONPARAM);
1227 if (!jni_mid_getDefaultAdapter)
1229 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1230 return CA_STATUS_FAILED;
1233 // get start le scan method
1234 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1235 "(Landroid/bluetooth/"
1236 "BluetoothAdapter$LeScanCallback;)V");
1237 if (!jni_mid_stopLeScan)
1239 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1240 return CA_STATUS_FAILED;
1243 // gat bt adapter object
1244 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1245 jni_mid_getDefaultAdapter);
1246 if (!jni_obj_BTAdapter)
1248 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1249 return CA_STATUS_FAILED;
1252 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1253 // call start le scan method
1254 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1255 if ((*env)->ExceptionCheck(env))
1257 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1258 (*env)->ExceptionDescribe(env);
1259 (*env)->ExceptionClear(env);
1260 return CA_STATUS_FAILED;
1263 return CA_STATUS_OK;
1266 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1269 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1270 VERIFY_NON_NULL(env, TAG, "env is null");
1271 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1272 VERIFY_NON_NULL(callback, TAG, "callback is null");
1274 if (!CALEIsEnableBTAdapter(env))
1276 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1277 return CA_ADAPTER_NOT_ENABLED;
1280 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1283 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1284 return CA_STATUS_FAILED;
1287 // get BluetoothDevice class
1288 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1289 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1290 if (!jni_cid_BluetoothDevice)
1292 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1293 return CA_STATUS_FAILED;
1296 // get connectGatt method
1297 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1298 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1299 "(Landroid/content/Context;ZLandroid/"
1300 "bluetooth/BluetoothGattCallback;)"
1301 "Landroid/bluetooth/BluetoothGatt;");
1302 if (!jni_mid_connectGatt)
1304 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1305 return CA_STATUS_FAILED;
1308 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1309 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1310 jni_mid_connectGatt,
1312 autoconnect, callback);
1313 if (!jni_obj_connectGatt)
1315 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1316 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1317 CALEClientUpdateSendCnt(env);
1318 return CA_STATUS_FAILED;
1322 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1324 return CA_STATUS_OK;
1327 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1329 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1330 VERIFY_NON_NULL(env, TAG, "env is null");
1331 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1333 if (!CALEIsEnableBTAdapter(env))
1335 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1336 return CA_ADAPTER_NOT_ENABLED;
1339 // get BluetoothGatt class
1340 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1341 if (!jni_cid_BluetoothGatt)
1343 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1344 return CA_STATUS_FAILED;
1347 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1348 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1349 "disconnect", "()V");
1350 if (!jni_mid_disconnectGatt)
1352 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1353 return CA_STATUS_FAILED;
1356 // call disconnect gatt method
1357 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1358 if ((*env)->ExceptionCheck(env))
1360 OIC_LOG(ERROR, TAG, "disconnect has failed");
1361 (*env)->ExceptionDescribe(env);
1362 (*env)->ExceptionClear(env);
1363 return CA_STATUS_FAILED;
1366 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1368 return CA_STATUS_OK;
1371 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1373 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1374 VERIFY_NON_NULL(env, TAG, "env is null");
1376 if (!g_gattObjectList)
1378 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1379 return CA_STATUS_FAILED;
1382 uint32_t length = u_arraylist_length(g_gattObjectList);
1383 for (uint32_t index = 0; index < length; index++)
1385 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1388 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1391 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1392 if (CA_STATUS_OK != res)
1394 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1399 OICFree(g_gattObjectList);
1400 g_gattObjectList = NULL;
1402 return CA_STATUS_OK;
1405 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1407 VERIFY_NON_NULL(env, TAG, "env is null");
1408 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1410 if (!CALEIsEnableBTAdapter(env))
1412 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1413 return CA_ADAPTER_NOT_ENABLED;
1416 // get BluetoothGatt class
1417 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1418 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1419 if (!jni_cid_BluetoothGatt)
1421 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1422 return CA_STATUS_FAILED;
1425 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1426 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1427 "discoverServices", "()Z");
1428 if (!jni_mid_discoverServices)
1430 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1431 return CA_STATUS_FAILED;
1433 // call disconnect gatt method
1434 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1435 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1438 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1439 return CA_STATUS_FAILED;
1442 return CA_STATUS_OK;
1445 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1447 VERIFY_NON_NULL(env, TAG, "env is null");
1448 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1451 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1452 if (!jni_obj_character)
1454 CALEClientSendFinish(env, gatt);
1455 return CA_STATUS_FAILED;
1458 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1459 if (CA_STATUS_OK != ret)
1461 CALEClientSendFinish(env, gatt);
1465 return CA_STATUS_OK;
1468 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1469 jobject gattCharacteristic)
1471 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1472 VERIFY_NON_NULL(env, TAG, "env is null");
1473 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1474 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1476 if (!CALEIsEnableBTAdapter(env))
1478 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1479 return CA_STATUS_FAILED;
1482 // get BluetoothGatt class
1483 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1484 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1485 if (!jni_cid_BluetoothGatt)
1487 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1488 return CA_STATUS_FAILED;
1491 OIC_LOG(DEBUG, TAG, "write characteristic method");
1492 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1493 "writeCharacteristic",
1494 "(Landroid/bluetooth/"
1495 "BluetoothGattCharacteristic;)Z");
1496 if (!jni_mid_writeCharacteristic)
1498 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1499 return CA_STATUS_FAILED;
1502 // call disconnect gatt method
1503 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1504 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1505 jni_mid_writeCharacteristic,
1506 gattCharacteristic);
1509 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1513 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1514 return CA_STATUS_FAILED;
1517 return CA_STATUS_OK;
1520 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1522 VERIFY_NON_NULL(env, TAG, "env is null");
1523 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1525 if (!CALEIsEnableBTAdapter(env))
1527 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1528 return CA_STATUS_FAILED;
1531 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1532 if (!jni_cid_BluetoothGatt)
1534 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1535 return CA_STATUS_FAILED;
1538 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1541 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1542 return CA_STATUS_FAILED;
1545 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1546 if (!jni_obj_GattCharacteristic)
1548 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1549 return CA_STATUS_FAILED;
1552 OIC_LOG(DEBUG, TAG, "read characteristic method");
1553 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1554 "readCharacteristic",
1555 "(Landroid/bluetooth/"
1556 "BluetoothGattCharacteristic;)Z");
1557 if (!jni_mid_readCharacteristic)
1559 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1560 return CA_STATUS_FAILED;
1563 // call disconnect gatt method
1564 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1565 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1566 jni_obj_GattCharacteristic);
1569 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1573 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1574 return CA_STATUS_FAILED;
1577 return CA_STATUS_OK;
1580 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1581 jobject characteristic)
1583 VERIFY_NON_NULL(env, TAG, "env is null");
1584 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1585 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1587 if (!CALEIsEnableBTAdapter(env))
1589 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1590 return CA_ADAPTER_NOT_ENABLED;
1593 // get BluetoothGatt class
1594 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1595 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1596 if (!jni_cid_BluetoothGatt)
1598 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1599 return CA_STATUS_FAILED;
1602 // set Characteristic Notification
1603 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1604 "setCharacteristicNotification",
1605 "(Landroid/bluetooth/"
1606 "BluetoothGattCharacteristic;Z)Z");
1607 if (!jni_mid_setNotification)
1609 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1610 return CA_STATUS_FAILED;
1613 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1614 characteristic, JNI_TRUE);
1615 if (JNI_TRUE == ret)
1617 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1621 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1622 return CA_STATUS_FAILED;
1625 return CA_STATUS_OK;
1628 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1630 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1631 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1632 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1634 if (!CALEIsEnableBTAdapter(env))
1636 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1640 // get BluetoothGatt class
1641 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1642 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1643 if (!jni_cid_BluetoothGatt)
1645 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1649 jmethodID jni_mid_getService = (*env)->GetMethodID(
1650 env, jni_cid_BluetoothGatt, "getService",
1651 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1652 if (!jni_mid_getService)
1654 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1658 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1659 if (!jni_obj_service_uuid)
1661 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1665 // get bluetooth gatt service
1666 OIC_LOG(DEBUG, TAG, "request to get service");
1667 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1668 jni_obj_service_uuid);
1669 if (!jni_obj_gattService)
1671 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1675 // get bluetooth gatt service class
1676 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1677 env, "android/bluetooth/BluetoothGattService");
1678 if (!jni_cid_BluetoothGattService)
1680 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1684 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1685 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1686 "getCharacteristic",
1687 "(Ljava/util/UUID;)"
1688 "Landroid/bluetooth/"
1689 "BluetoothGattCharacteristic;");
1690 if (!jni_mid_getCharacteristic)
1692 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1696 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1699 OIC_LOG(ERROR, TAG, "uuid is null");
1703 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1704 if (!jni_obj_tx_uuid)
1706 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1707 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1711 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1712 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1713 jni_mid_getCharacteristic,
1716 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1717 return jni_obj_GattCharacteristic;
1720 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1722 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1723 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1724 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1725 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1727 if (!CALEIsEnableBTAdapter(env))
1729 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1733 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1736 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1740 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1741 if (!jni_obj_GattCharacteristic)
1743 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1747 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1748 "/BluetoothGattCharacteristic");
1749 if (!jni_cid_BTGattCharacteristic)
1751 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1755 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1756 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1758 if (!jni_mid_setValue)
1760 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1764 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1766 if (JNI_TRUE == ret)
1768 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1772 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1777 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1778 "setWriteType", "(I)V");
1779 if (!jni_mid_setWriteType)
1781 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1785 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1786 "WRITE_TYPE_NO_RESPONSE", "I");
1787 if (!jni_fid_no_response)
1789 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1793 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1794 jni_fid_no_response);
1796 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1798 return jni_obj_GattCharacteristic;
1801 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1803 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1804 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1806 if (!CALEIsEnableBTAdapter(env))
1808 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1812 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1813 "BluetoothGattCharacteristic");
1814 if (!jni_cid_BTGattCharacteristic)
1816 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1820 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1821 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1823 if (!jni_mid_getValue)
1825 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1829 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1831 return jni_obj_data_array;
1834 CAResult_t CALEClientCreateUUIDList()
1838 OIC_LOG(ERROR, TAG, "g_jvm is null");
1839 return CA_STATUS_FAILED;
1842 bool isAttached = false;
1844 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1847 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1848 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1852 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1853 return CA_STATUS_FAILED;
1858 // create new object array
1859 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1860 if (!jni_cid_uuid_list)
1862 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1866 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1867 jni_cid_uuid_list, NULL);
1868 if (!jni_obj_uuid_list)
1870 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1875 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1878 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1881 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1883 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1887 (*g_jvm)->DetachCurrentThread(g_jvm);
1890 return CA_STATUS_OK;
1897 (*g_jvm)->DetachCurrentThread(g_jvm);
1899 return CA_STATUS_FAILED;
1902 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
1903 jobject characteristic)
1905 VERIFY_NON_NULL(env, TAG, "env is null");
1906 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1907 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1909 if (!CALEIsEnableBTAdapter(env))
1911 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1912 return CA_ADAPTER_NOT_ENABLED;
1915 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
1916 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1917 "BluetoothGattCharacteristic");
1918 if (!jni_cid_BTGattCharacteristic)
1920 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1921 return CA_STATUS_FAILED;
1924 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1925 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1927 "(Ljava/util/UUID;)Landroid/bluetooth/"
1928 "BluetoothGattDescriptor;");
1929 if (!jni_mid_getDescriptor)
1931 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
1932 return CA_STATUS_FAILED;
1935 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1936 if (!jni_obj_cc_uuid)
1938 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
1939 return CA_STATUS_FAILED;
1942 OIC_LOG(DEBUG, TAG, "request to get descriptor");
1943 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
1944 jni_mid_getDescriptor, jni_obj_cc_uuid);
1945 if (!jni_obj_descriptor)
1947 OIC_LOG(ERROR, TAG, "jni_obj_descriptor is null");
1948 return CA_STATUS_FAILED;
1951 OIC_LOG(DEBUG, TAG, "set value in descriptor");
1952 jclass jni_cid_descriptor = (*env)->FindClass(env,
1953 "android/bluetooth/BluetoothGattDescriptor");
1954 if (!jni_cid_descriptor)
1956 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
1957 return CA_STATUS_FAILED;
1960 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
1961 if (!jni_mid_setValue)
1963 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1964 return CA_STATUS_FAILED;
1967 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
1968 "ENABLE_NOTIFICATION_VALUE", "[B");
1969 if (!jni_fid_NotiValue)
1971 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
1972 return CA_STATUS_FAILED;
1975 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
1977 jboolean jni_setvalue = (*env)->CallBooleanMethod(
1978 env, jni_obj_descriptor, jni_mid_setValue,
1979 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
1982 OIC_LOG(DEBUG, TAG, "setValue success");
1986 OIC_LOG(ERROR, TAG, "setValue has failed");
1987 return CA_STATUS_FAILED;
1990 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
1993 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
1994 return CA_STATUS_FAILED;
1997 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
1998 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
1999 "(Landroid/bluetooth/"
2000 "BluetoothGattDescriptor;)Z");
2001 if (!jni_mid_writeDescriptor)
2003 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2004 return CA_STATUS_FAILED;
2007 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2008 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2009 jni_obj_descriptor);
2012 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2016 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2017 return CA_STATUS_FAILED;
2020 return CA_STATUS_OK;
2023 void CALEClientCreateScanDeviceList(JNIEnv *env)
2025 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2026 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2028 ca_mutex_lock(g_deviceListMutex);
2029 // create new object array
2030 if (g_deviceList == NULL)
2032 OIC_LOG(DEBUG, TAG, "Create device list");
2034 g_deviceList = u_arraylist_create();
2036 ca_mutex_unlock(g_deviceListMutex);
2039 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2041 OIC_LOG(DEBUG, TAG, "IN - CALEClientAddScanDeviceToList");
2042 VERIFY_NON_NULL(device, TAG, "device is null");
2043 VERIFY_NON_NULL(env, TAG, "env is null");
2045 ca_mutex_lock(g_deviceListMutex);
2049 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2050 ca_mutex_unlock(g_deviceListMutex);
2051 return CA_STATUS_FAILED;
2054 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2055 if (!jni_remoteAddress)
2057 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2058 ca_mutex_unlock(g_deviceListMutex);
2059 return CA_STATUS_FAILED;
2062 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2065 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2066 ca_mutex_unlock(g_deviceListMutex);
2067 return CA_STATUS_FAILED;
2070 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2072 jobject gdevice = (*env)->NewGlobalRef(env, device);
2073 u_arraylist_add(g_deviceList, gdevice);
2074 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
2076 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2078 ca_mutex_unlock(g_deviceListMutex);
2080 OIC_LOG(DEBUG, TAG, "OUT - CALEClientAddScanDeviceToList");
2081 return CA_STATUS_OK;
2084 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2086 OIC_LOG(DEBUG, TAG, "IN - CALEClientIsDeviceInScanDeviceList");
2087 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2088 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2092 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2096 uint32_t length = u_arraylist_length(g_deviceList);
2097 for (uint32_t index = 0; index < length; index++)
2099 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2102 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2106 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2107 if (!jni_setAddress)
2109 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2113 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2116 OIC_LOG(ERROR, TAG, "setAddress is null");
2120 if (!strcmp(remoteAddress, setAddress))
2122 OIC_LOG(DEBUG, TAG, "the device is already set");
2123 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2127 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2130 OIC_LOG(DEBUG, TAG, "OUT - CALEClientIsDeviceInScanDeviceList");
2131 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2136 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2138 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2139 VERIFY_NON_NULL(env, TAG, "env is null");
2141 ca_mutex_lock(g_deviceListMutex);
2145 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2146 ca_mutex_unlock(g_deviceListMutex);
2147 return CA_STATUS_FAILED;
2150 uint32_t length = u_arraylist_length(g_deviceList);
2151 for (uint32_t index = 0; index < length; index++)
2153 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2156 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2159 (*env)->DeleteGlobalRef(env, jarrayObj);
2162 OICFree(g_deviceList);
2163 g_deviceList = NULL;
2165 ca_mutex_unlock(g_deviceListMutex);
2166 return CA_STATUS_OK;
2169 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2171 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2172 VERIFY_NON_NULL(address, TAG, "address is null");
2173 VERIFY_NON_NULL(env, TAG, "env is null");
2175 ca_mutex_lock(g_deviceListMutex);
2179 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2180 ca_mutex_unlock(g_deviceListMutex);
2181 return CA_STATUS_FAILED;
2184 uint32_t length = u_arraylist_length(g_deviceList);
2185 for (uint32_t index = 0; index < length; index++)
2187 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2190 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2191 ca_mutex_unlock(g_deviceListMutex);
2192 return CA_STATUS_FAILED;
2195 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2196 if (!jni_setAddress)
2198 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2199 ca_mutex_unlock(g_deviceListMutex);
2200 return CA_STATUS_FAILED;
2203 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2206 OIC_LOG(ERROR, TAG, "setAddress is null");
2207 ca_mutex_unlock(g_deviceListMutex);
2208 return CA_STATUS_FAILED;
2211 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2214 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2215 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2216 ca_mutex_unlock(g_deviceListMutex);
2217 return CA_STATUS_FAILED;
2220 if (!strcmp(setAddress, remoteAddress))
2222 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2223 (*env)->DeleteGlobalRef(env, jarrayObj);
2224 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2225 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2227 CALEClientReorderingList(index, g_deviceList);
2228 ca_mutex_unlock(g_deviceListMutex);
2229 return CA_STATUS_OK;
2231 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2232 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2235 ca_mutex_unlock(g_deviceListMutex);
2236 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2238 return CA_STATUS_OK;
2245 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2247 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2248 VERIFY_NON_NULL(env, TAG, "env is null");
2249 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2251 ca_mutex_lock(g_gattObjectMutex);
2253 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2254 if (!jni_remoteAddress)
2256 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2257 ca_mutex_unlock(g_gattObjectMutex);
2258 return CA_STATUS_FAILED;
2261 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2264 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2265 ca_mutex_unlock(g_gattObjectMutex);
2266 return CA_STATUS_FAILED;
2269 if (!CALEClientIsGattObjInList(env, remoteAddress))
2271 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2272 u_arraylist_add(g_gattObjectList, newGatt);
2273 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2276 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2277 ca_mutex_unlock(g_gattObjectMutex);
2278 return CA_STATUS_OK;
2281 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2283 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2284 VERIFY_NON_NULL(env, TAG, "env is null");
2285 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2287 uint32_t length = u_arraylist_length(g_gattObjectList);
2288 for (uint32_t index = 0; index < length; index++)
2291 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2294 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2298 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2299 if (!jni_setAddress)
2301 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2305 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2308 OIC_LOG(ERROR, TAG, "setAddress is null");
2312 if (!strcmp(remoteAddress, setAddress))
2314 OIC_LOG(DEBUG, TAG, "the device is already set");
2315 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2320 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2325 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2329 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2331 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2332 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2333 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2335 ca_mutex_lock(g_gattObjectMutex);
2336 uint32_t length = u_arraylist_length(g_gattObjectList);
2337 for (uint32_t index = 0; index < length; index++)
2339 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2342 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2343 ca_mutex_unlock(g_gattObjectMutex);
2347 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2348 if (!jni_setAddress)
2350 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2351 ca_mutex_unlock(g_gattObjectMutex);
2355 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2358 OIC_LOG(ERROR, TAG, "setAddress is null");
2359 ca_mutex_unlock(g_gattObjectMutex);
2363 if (!strcmp(remoteAddress, setAddress))
2365 OIC_LOG(DEBUG, TAG, "the device is already set");
2366 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2367 ca_mutex_unlock(g_gattObjectMutex);
2370 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2373 ca_mutex_unlock(g_gattObjectMutex);
2374 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2378 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2380 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2381 VERIFY_NON_NULL(env, TAG, "env is null");
2383 ca_mutex_lock(g_gattObjectMutex);
2384 if (!g_gattObjectList)
2386 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2387 ca_mutex_unlock(g_gattObjectMutex);
2388 return CA_STATUS_FAILED;
2391 uint32_t length = u_arraylist_length(g_gattObjectList);
2392 for (uint32_t index = 0; index < length; index++)
2394 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2397 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2400 (*env)->DeleteGlobalRef(env, jarrayObj);
2403 OICFree(g_gattObjectList);
2404 g_gattObjectList = NULL;
2405 ca_mutex_unlock(g_gattObjectMutex);
2406 return CA_STATUS_OK;
2409 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2411 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2412 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2413 VERIFY_NON_NULL(env, TAG, "env is null");
2415 ca_mutex_lock(g_gattObjectMutex);
2416 if (!g_gattObjectList)
2418 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2419 ca_mutex_unlock(g_gattObjectMutex);
2420 return CA_STATUS_FAILED;
2423 uint32_t length = u_arraylist_length(g_gattObjectList);
2424 for (uint32_t index = 0; index < length; index++)
2426 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2429 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2430 ca_mutex_unlock(g_gattObjectMutex);
2431 return CA_STATUS_FAILED;
2434 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2435 if (!jni_setAddress)
2437 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2438 ca_mutex_unlock(g_gattObjectMutex);
2439 return CA_STATUS_FAILED;
2442 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2445 OIC_LOG(ERROR, TAG, "setAddress is null");
2446 ca_mutex_unlock(g_gattObjectMutex);
2447 return CA_STATUS_FAILED;
2450 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2451 if (!jni_remoteAddress)
2453 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2454 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2455 ca_mutex_unlock(g_gattObjectMutex);
2456 return CA_STATUS_FAILED;
2459 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2462 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2463 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2464 ca_mutex_unlock(g_gattObjectMutex);
2465 return CA_STATUS_FAILED;
2468 if (!strcmp(setAddress, remoteAddress))
2470 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2471 (*env)->DeleteGlobalRef(env, jarrayObj);
2472 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2473 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2474 ca_mutex_unlock(g_gattObjectMutex);
2475 return CALEClientReorderingList(index, g_gattObjectList);
2477 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2478 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2481 ca_mutex_unlock(g_gattObjectMutex);
2482 OIC_LOG(DEBUG, TAG, "there are no target object");
2483 return CA_STATUS_OK;
2486 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2488 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2489 VERIFY_NON_NULL(addr, TAG, "addr is null");
2490 VERIFY_NON_NULL(env, TAG, "env is null");
2492 ca_mutex_lock(g_gattObjectMutex);
2493 if (!g_gattObjectList)
2495 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2496 ca_mutex_unlock(g_gattObjectMutex);
2497 return CA_STATUS_FAILED;
2500 uint32_t length = u_arraylist_length(g_gattObjectList);
2501 for (uint32_t index = 0; index < length; index++)
2503 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2506 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2507 ca_mutex_unlock(g_gattObjectMutex);
2508 return CA_STATUS_FAILED;
2511 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2512 if (!jni_setAddress)
2514 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2515 ca_mutex_unlock(g_gattObjectMutex);
2516 return CA_STATUS_FAILED;
2519 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2522 OIC_LOG(ERROR, TAG, "setAddress is null");
2523 ca_mutex_unlock(g_gattObjectMutex);
2524 return CA_STATUS_FAILED;
2527 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2530 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2531 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2532 ca_mutex_unlock(g_gattObjectMutex);
2533 return CA_STATUS_FAILED;
2536 if (!strcmp(setAddress, remoteAddress))
2538 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2539 (*env)->DeleteGlobalRef(env, jarrayObj);
2541 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2542 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2543 ca_mutex_unlock(g_gattObjectMutex);
2544 return CALEClientReorderingList(index, g_gattObjectList);
2546 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2547 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2550 ca_mutex_unlock(g_gattObjectMutex);
2551 OIC_LOG(DEBUG, TAG, "there are no target object");
2552 return CA_STATUS_FAILED;
2559 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2560 uint16_t notificationState, uint16_t sendState)
2562 VERIFY_NON_NULL(address, TAG, "address is null");
2564 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2567 OIC_LOG(ERROR, TAG, "out of memory");
2568 return CA_MEMORY_ALLOC_FAILED;
2571 if (strlen(address) > CA_MACADDR_SIZE)
2573 OIC_LOG(ERROR, TAG, "address is not proper");
2575 return CA_STATUS_FAILED;
2578 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2579 newstate->connectedState = connectedState;
2580 newstate->notificationState = notificationState;
2581 newstate->sendState = sendState;
2582 return CALEClientAddDeviceStateToList(newstate);
2585 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2587 VERIFY_NON_NULL(state, TAG, "state is null");
2589 ca_mutex_lock(g_deviceStateListMutex);
2591 if (!g_deviceStateList)
2593 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2594 ca_mutex_unlock(g_deviceStateListMutex);
2595 return CA_STATUS_FAILED;
2598 if (CALEClientIsDeviceInList(state->address))
2600 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2603 OIC_LOG(ERROR, TAG, "curState is null");
2604 ca_mutex_unlock(g_deviceStateListMutex);
2605 return CA_STATUS_FAILED;
2608 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2610 state->notificationState = curState->notificationState;
2613 // delete previous state for update new state
2614 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2615 if (CA_STATUS_OK != res)
2617 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2618 ca_mutex_unlock(g_deviceStateListMutex);
2622 u_arraylist_add(g_deviceStateList, state); // update new state
2623 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2624 state->connectedState, state->notificationState);
2626 ca_mutex_unlock(g_deviceStateListMutex);
2627 return CA_STATUS_OK;
2630 bool CALEClientIsDeviceInList(const char* remoteAddress)
2632 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2634 if (!g_deviceStateList)
2636 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2640 uint32_t length = u_arraylist_length(g_deviceStateList);
2641 for (uint32_t index = 0; index < length; index++)
2643 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2646 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2650 if (!strcmp(remoteAddress, state->address))
2652 OIC_LOG(DEBUG, TAG, "the device is already set");
2661 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2665 CAResult_t CALEClientRemoveAllDeviceState()
2667 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2669 ca_mutex_lock(g_deviceStateListMutex);
2670 if (!g_deviceStateList)
2672 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2673 ca_mutex_unlock(g_deviceStateListMutex);
2674 return CA_STATUS_FAILED;
2677 uint32_t length = u_arraylist_length(g_deviceStateList);
2678 for (uint32_t index = 0; index < length; index++)
2680 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2683 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2689 OICFree(g_deviceStateList);
2690 g_deviceStateList = NULL;
2691 ca_mutex_unlock(g_deviceStateListMutex);
2693 return CA_STATUS_OK;
2696 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2698 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2699 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2701 if (!g_deviceStateList)
2703 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2704 return CA_STATUS_FAILED;
2707 uint32_t length = u_arraylist_length(g_deviceStateList);
2708 for (uint32_t index = 0; index < length; index++)
2710 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2713 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2717 if (!strcmp(state->address, remoteAddress))
2719 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2722 CAResult_t res = CALEClientReorderingList(index, g_deviceStateList);
2723 if(CA_STATUS_OK != res)
2725 OIC_LOG(ERROR, TAG, "CALEClientReorderingList has failed");
2728 return CA_STATUS_OK;
2732 return CA_STATUS_FAILED;
2735 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2737 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2738 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2740 if (!g_deviceStateList)
2742 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2746 uint32_t length = u_arraylist_length(g_deviceStateList);
2747 for (uint32_t index = 0; index < length; index++)
2749 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2752 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2756 if (!strcmp(state->address, remoteAddress))
2758 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2765 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2767 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2768 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2770 ca_mutex_lock(g_deviceStateListMutex);
2771 if (!g_deviceStateList)
2773 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2774 ca_mutex_unlock(g_deviceStateListMutex);
2778 uint32_t length = u_arraylist_length(g_deviceStateList);
2779 for (uint32_t index = 0; index < length; index++)
2781 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2784 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2788 if (!strcmp(state->address, remoteAddress))
2790 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2792 if (STATE_CONNECTED == state->connectedState)
2794 ca_mutex_unlock(g_deviceStateListMutex);
2799 ca_mutex_unlock(g_deviceStateListMutex);
2804 ca_mutex_unlock(g_deviceStateListMutex);
2808 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2810 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2811 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2813 ca_mutex_lock(g_deviceStateListMutex);
2814 if (!g_deviceStateList)
2816 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2817 ca_mutex_unlock(g_deviceStateListMutex);
2821 uint32_t length = u_arraylist_length(g_deviceStateList);
2822 for (uint32_t index = 0; index < length; index++)
2824 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2827 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2831 if (!strcmp(state->address, remoteAddress))
2833 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2835 if (STATE_CHARACTER_SET == state->notificationState)
2837 ca_mutex_unlock(g_deviceStateListMutex);
2842 ca_mutex_unlock(g_deviceStateListMutex);
2848 ca_mutex_unlock(g_deviceStateListMutex);
2852 void CALEClientCreateDeviceList()
2854 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2856 // create new object array
2857 if (!g_gattObjectList)
2859 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2861 g_gattObjectList = u_arraylist_create();
2864 if (!g_deviceStateList)
2866 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2868 g_deviceStateList = u_arraylist_create();
2873 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2875 g_deviceList = u_arraylist_create();
2879 CAResult_t CALEClientReorderingList(uint32_t index, u_arraylist_t *list)
2883 OIC_LOG(ERROR, TAG, "list is null");
2884 return CA_STATUS_FAILED;
2887 if (index >= list->length)
2889 OIC_LOG(ERROR, TAG, "index is not available");
2890 return CA_STATUS_FAILED;
2893 if (index < list->length - 1)
2895 memmove(&list->data[index], &list->data[index + 1],
2896 (list->length - index - 1) * sizeof(void *));
2902 return CA_STATUS_OK;
2906 * Check Sent Count for remove g_sendBuffer
2908 void CALEClientUpdateSendCnt(JNIEnv *env)
2910 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2912 ca_mutex_lock(g_threadMutex);
2916 if (g_targetCnt <= g_currentSentCnt)
2919 g_currentSentCnt = 0;
2923 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2924 g_sendBuffer = NULL;
2926 // notity the thread
2927 ca_cond_signal(g_threadCond);
2928 CALEClientSetSendFinishFlag(true);
2929 OIC_LOG(DEBUG, TAG, "set signal for send data");
2932 ca_mutex_unlock(g_threadMutex);
2935 CAResult_t CALEClientInitGattMutexVaraibles()
2937 OIC_LOG(DEBUG, TAG, "IN");
2939 if (NULL == g_bleReqRespClientCbMutex)
2941 g_bleReqRespClientCbMutex = ca_mutex_new();
2942 if (NULL == g_bleReqRespClientCbMutex)
2944 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2945 return CA_STATUS_FAILED;
2949 if (NULL == g_bleServerBDAddressMutex)
2951 g_bleServerBDAddressMutex = ca_mutex_new();
2952 if (NULL == g_bleServerBDAddressMutex)
2954 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2955 return CA_STATUS_FAILED;
2959 if (NULL == g_threadMutex)
2961 g_threadMutex = ca_mutex_new();
2962 if (NULL == g_threadMutex)
2964 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2965 return CA_STATUS_FAILED;
2969 if (NULL == g_threadSendMutex)
2971 g_threadSendMutex = ca_mutex_new();
2972 if (NULL == g_threadSendMutex)
2974 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2975 return CA_STATUS_FAILED;
2979 if (NULL == g_deviceListMutex)
2981 g_deviceListMutex = ca_mutex_new();
2982 if (NULL == g_deviceListMutex)
2984 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2985 return CA_STATUS_FAILED;
2989 if (NULL == g_gattObjectMutex)
2991 g_gattObjectMutex = ca_mutex_new();
2992 if (NULL == g_gattObjectMutex)
2994 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2995 return CA_STATUS_FAILED;
2999 if (NULL == g_deviceStateListMutex)
3001 g_deviceStateListMutex = ca_mutex_new();
3002 if (NULL == g_deviceStateListMutex)
3004 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3005 return CA_STATUS_FAILED;
3009 if (NULL == g_SendFinishMutex)
3011 g_SendFinishMutex = ca_mutex_new();
3012 if (NULL == g_SendFinishMutex)
3014 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3015 return CA_STATUS_FAILED;
3019 OIC_LOG(DEBUG, TAG, "OUT");
3020 return CA_STATUS_OK;
3023 void CALEClientTerminateGattMutexVariables()
3025 OIC_LOG(DEBUG, TAG, "IN");
3027 ca_mutex_free(g_bleReqRespClientCbMutex);
3028 g_bleReqRespClientCbMutex = NULL;
3030 ca_mutex_free(g_bleServerBDAddressMutex);
3031 g_bleServerBDAddressMutex = NULL;
3033 ca_mutex_free(g_threadMutex);
3034 g_threadMutex = NULL;
3036 ca_mutex_free(g_threadSendMutex);
3037 g_threadSendMutex = NULL;
3039 ca_mutex_free(g_deviceListMutex);
3040 g_deviceListMutex = NULL;
3042 ca_mutex_free(g_SendFinishMutex);
3043 g_SendFinishMutex = NULL;
3045 OIC_LOG(DEBUG, TAG, "OUT");
3048 void CALEClientSetSendFinishFlag(bool flag)
3050 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3052 ca_mutex_lock(g_SendFinishMutex);
3053 g_isFinishedSendData = flag;
3054 ca_mutex_unlock(g_SendFinishMutex);
3061 CAResult_t CAStartLEGattClient()
3063 CAResult_t res = CALEClientStartMulticastServer();
3064 if (CA_STATUS_OK != res)
3066 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3070 g_isStartedLEClient = true;
3076 void CAStopLEGattClient()
3078 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3082 OIC_LOG(ERROR, TAG, "g_jvm is null");
3086 bool isAttached = false;
3088 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3091 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3092 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3096 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3102 CAResult_t ret = CALEClientDisconnectAll(env);
3103 if (CA_STATUS_OK != ret)
3105 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3108 ret = CALEClientStopScan();
3109 if(CA_STATUS_OK != ret)
3111 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3114 ca_cond_signal(g_threadCond);
3118 (*g_jvm)->DetachCurrentThread(g_jvm);
3123 void CATerminateLEGattClient()
3125 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3126 CALEClientTerminate();
3129 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
3130 const uint32_t dataLen, CALETransferType_t type,
3131 const int32_t position)
3133 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3134 VERIFY_NON_NULL(data, TAG, "data is null");
3135 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3137 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3140 CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, uint32_t dataLen)
3142 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3143 VERIFY_NON_NULL(data, TAG, "data is null");
3145 return CALEClientSendMulticastMessage(data, dataLen);
3148 void CASetLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
3150 OIC_LOG(DEBUG, TAG, "IN");
3152 ca_mutex_lock(g_bleReqRespClientCbMutex);
3153 g_CABLEClientDataReceivedCallback = callback;
3154 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3156 OIC_LOG(DEBUG, TAG, "OUT");
3159 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3161 OIC_LOG(DEBUG, TAG, "IN");
3163 CALEClientInitialize(handle);
3165 OIC_LOG(DEBUG, TAG, "OUT");
3168 CAResult_t CAGetLEAddress(char **local_address)
3170 OIC_LOG(DEBUG, TAG, "IN");
3172 VERIFY_NON_NULL(local_address, TAG, "local_address is null");
3173 CAResult_t res = CALEClientGetInterfaceInfo(local_address);
3174 if (CA_STATUS_OK != res)
3176 OIC_LOG(INFO, TAG, "it didn't get local address");
3179 OIC_LOG(DEBUG, TAG, "OUT");
3180 return CA_STATUS_OK;
3183 JNIEXPORT void JNICALL
3184 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3187 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3188 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3189 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3191 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3194 JNIEXPORT void JNICALL
3195 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3198 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3199 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3200 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3202 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3205 JNIEXPORT void JNICALL
3206 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3207 jobject device, jint rssi,
3208 jbyteArray scanRecord)
3210 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3211 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3213 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3214 if (CA_STATUS_OK != res)
3216 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3221 * Class: org_iotivity_ca_jar_caleinterface
3222 * Method: CALeGattConnectionStateChangeCallback
3223 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3225 JNIEXPORT void JNICALL
3226 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3232 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3234 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3235 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3237 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3239 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3245 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3248 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3249 STATE_CHARACTER_NO_CHANGE,
3251 if (CA_STATUS_OK != res)
3253 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3254 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3257 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3260 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3261 if (CA_STATUS_OK != res)
3263 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3267 res = CALEClientDiscoverServices(env, gatt);
3268 if (CA_STATUS_OK != res)
3270 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3274 else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
3276 CAResult_t res = CALEClientStartScan();
3277 if (CA_STATUS_OK != res)
3279 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3282 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3285 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3288 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3291 res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3292 STATE_CHARACTER_NO_CHANGE,
3294 if (CA_STATUS_OK != res)
3296 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3298 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3301 res = CALEClientGattClose(env, gatt);
3302 if (CA_STATUS_OK != res)
3304 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3310 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3313 OIC_LOG(ERROR, TAG, "jni_address is null");
3318 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3321 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3322 STATE_CHARACTER_NO_CHANGE,
3324 if (CA_STATUS_OK != res)
3326 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3329 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3331 CAResult_t res = CALEClientGattClose(env, gatt);
3332 if (CA_STATUS_OK != res)
3334 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3344 CALEClientSendFinish(env, gatt);
3349 * Class: org_iotivity_ca_jar_caleinterface
3350 * Method: CALeGattServicesDiscoveredCallback
3351 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3353 JNIEXPORT void JNICALL
3354 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3359 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3360 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3361 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3363 if (0 != status) // discovery error
3365 CALEClientSendFinish(env, gatt);
3369 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3372 CALEClientSendFinish(env, gatt);
3376 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3379 CALEClientSendFinish(env, gatt);
3383 if (!CALEClientIsSetCharacteristic(address))
3385 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3388 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3392 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3393 if (!jni_obj_GattCharacteristic)
3395 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3399 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3400 jni_obj_GattCharacteristic);
3401 if (CA_STATUS_OK != res)
3403 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3407 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3408 if (CA_STATUS_OK != res)
3410 OIC_LOG(ERROR, TAG, "CALEClientSetUUIDToDescriptor has failed");
3414 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3416 if (CA_STATUS_OK != res)
3418 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3424 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3425 if (CA_STATUS_OK != res)
3427 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3431 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3436 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3437 CALEClientSendFinish(env, gatt);
3442 * Class: org_iotivity_ca_jar_caleinterface
3443 * Method: CALeGattCharacteristicReadCallback
3444 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3446 JNIEXPORT void JNICALL
3447 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicReadCallback(JNIEnv *env,
3450 jobject characteristic,
3454 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - status : %d", status);
3458 * Class: org_iotivity_ca_jar_caleinterface
3459 * Method: CALeGattCharacteristicWritjclasseCallback
3460 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3462 JNIEXPORT void JNICALL
3463 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3464 JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data,
3467 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3468 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3469 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3472 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3474 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3476 // send success & signal
3477 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3483 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3489 if (GATT_SUCCESS != status) // error case
3491 OIC_LOG(ERROR, TAG, "send failure");
3492 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3494 if (CA_STATUS_OK != res)
3496 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3498 CALEClientSendFinish(env, gatt);
3502 OIC_LOG(DEBUG, TAG, "send success");
3503 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3504 STATE_SEND_SUCCESS);
3505 if (CA_STATUS_OK != res)
3507 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3509 CALEClientUpdateSendCnt(env);
3512 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3518 CALEClientSendFinish(env, gatt);
3523 * Class: org_iotivity_ca_jar_caleinterface
3524 * Method: CALeGattCharacteristicChangedCallback
3525 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3527 JNIEXPORT void JNICALL
3528 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3529 JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jbyteArray data)
3531 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3532 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3533 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3534 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3536 // get Byte Array and covert to char*
3537 jint length = (*env)->GetArrayLength(env, data);
3540 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3542 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %s",
3543 jni_byte_responseData);
3545 char* receivedData = (char*) OICMalloc(sizeof(char) * length + 1);
3548 OIC_LOG(ERROR, TAG, "recevicedData is null");
3552 memcpy(receivedData, (const char*) jni_byte_responseData, length);
3553 receivedData[length] = '\0';
3554 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3556 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3559 OIC_LOG(ERROR, TAG, "jni_address is null");
3560 OICFree(receivedData);
3564 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3567 OIC_LOG(ERROR, TAG, "address is null");
3568 OICFree(receivedData);
3572 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %s, %d",
3573 receivedData, length);
3575 ca_mutex_lock(g_bleServerBDAddressMutex);
3576 uint32_t sentLength = 0;
3577 g_CABLEClientDataReceivedCallback(address, OIC_GATT_SERVICE_UUID, receivedData, length,
3579 ca_mutex_unlock(g_bleServerBDAddressMutex);
3581 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3585 * Class: org_iotivity_ca_jar_caleinterface
3586 * Method: CALeGattDescriptorReadCallback
3587 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3589 JNIEXPORT void JNICALL
3590 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorReadCallback(JNIEnv *env, jobject obj,
3595 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorReadCallback - status %d: ", status);
3599 * Class: org_iotivity_ca_jar_caleinterface
3600 * Method: CALeGattDescriptorWriteCallback
3601 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3603 JNIEXPORT void JNICALL
3604 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3609 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3610 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3611 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3613 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3614 if (CA_STATUS_OK != res)
3616 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3624 CALEClientSendFinish(env, gatt);
3629 * Class: org_iotivity_ca_jar_caleinterface
3630 * Method: CALeGattReliableWriteCompletedCallback
3631 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3633 JNIEXPORT void JNICALL
3634 Java_org_iotivity_ca_CaLeClientInterface_caLeGattReliableWriteCompletedCallback(JNIEnv *env,
3639 OIC_LOG_V(DEBUG, TAG, "CALeGattReliableWriteCompletedCallback - status %d: ", status);
3643 * Class: org_iotivity_ca_jar_caleinterface
3644 * Method: CALeGattReadRemoteRssiCallback
3645 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3647 JNIEXPORT void JNICALL
3648 Java_org_iotivity_ca_CaLeClientInterface_caLeGattReadRemoteRssiCallback(JNIEnv *env, jobject obj,
3649 jobject gatt, jint rssi,
3652 OIC_LOG_V(DEBUG, TAG, "CALeGattReadRemoteRssiCallback - rssi %d, status %d: ", rssi, status);