1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
26 #include "caleclient.h"
27 #include "caleserver.h"
28 #include "caleutils.h"
29 #include "caleinterface.h"
30 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "cathreadpool.h" /* for thread pool */
37 #include "uarraylist.h"
38 #include "org_iotivity_ca_CaLeClientInterface.h"
40 #define TAG PCF("OIC_CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
43 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
45 static ca_thread_pool_t g_threadPoolHandle = NULL;
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 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;
71 static ca_cond g_deviceDescCond = NULL;
73 static ca_mutex g_threadSendMutex = NULL;
74 static ca_mutex g_threadWriteCharacteristicMutex = NULL;
75 static ca_cond g_threadWriteCharacteristicCond = NULL;
76 static bool g_isSignalSetFlag = false;
78 static ca_mutex g_bleReqRespClientCbMutex = NULL;
79 static ca_mutex g_bleServerBDAddressMutex = NULL;
81 static ca_mutex g_deviceListMutex = NULL;
82 static ca_mutex g_gattObjectMutex = NULL;
83 static ca_mutex g_deviceStateListMutex = NULL;
85 static ca_mutex g_scanMutex = NULL;
87 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
89 static jboolean g_autoConnectFlag = JNI_FALSE;
92 void CALEClientJniInit()
94 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
95 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
98 void CALEClientJNISetContext()
100 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
101 g_context = (jobject) CANativeJNIGetContext();
104 CAResult_t CALECreateJniInterfaceObject()
106 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
110 OIC_LOG(ERROR, TAG, "g_context is null");
111 return CA_STATUS_FAILED;
116 OIC_LOG(ERROR, TAG, "g_jvm is null");
117 return CA_STATUS_FAILED;
120 bool isAttached = false;
122 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
125 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
126 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
130 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
131 return CA_STATUS_FAILED;
136 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
137 if (!jni_LEInterface)
139 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
143 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
144 "(Landroid/content/Context;)V");
145 if (!LeInterfaceConstructorMethod)
147 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
151 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
152 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
156 (*g_jvm)->DetachCurrentThread(g_jvm);
165 (*g_jvm)->DetachCurrentThread(g_jvm);
168 return CA_STATUS_FAILED;
171 CAResult_t CALEClientInitialize()
173 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
179 OIC_LOG(ERROR, TAG, "g_jvm is null");
180 return CA_STATUS_FAILED;
183 bool isAttached = false;
185 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
188 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
189 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
193 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
194 return CA_STATUS_FAILED;
199 CAResult_t ret = CALECheckPlatformVersion(env, 18);
200 if (CA_STATUS_OK != ret)
202 OIC_LOG(ERROR, TAG, "it is not supported");
206 (*g_jvm)->DetachCurrentThread(g_jvm);
212 ret = CALEClientInitGattMutexVaraibles();
213 if (CA_STATUS_OK != ret)
215 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
216 CALEClientTerminateGattMutexVariables();
220 (*g_jvm)->DetachCurrentThread(g_jvm);
226 g_deviceDescCond = ca_cond_new();
228 // init mutex for send logic
229 g_threadCond = ca_cond_new();
230 g_threadWriteCharacteristicCond = ca_cond_new();
232 CALEClientCreateDeviceList();
233 CALEClientJNISetContext();
235 ret = CALEClientCreateUUIDList();
236 if (CA_STATUS_OK != ret)
238 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
242 (*g_jvm)->DetachCurrentThread(g_jvm);
248 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
249 if (CA_STATUS_OK != ret)
251 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
255 (*g_jvm)->DetachCurrentThread(g_jvm);
260 g_isStartedLEClient = true;
264 (*g_jvm)->DetachCurrentThread(g_jvm);
270 void CALEClientTerminate()
272 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
276 OIC_LOG(ERROR, TAG, "g_jvm is null");
280 bool isAttached = false;
282 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
285 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
286 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
290 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
296 if (g_leScanCallback)
298 (*env)->DeleteGlobalRef(env, g_leScanCallback);
301 if (g_leGattCallback)
303 (*env)->DeleteGlobalRef(env, g_leGattCallback);
308 (*env)->DeleteGlobalRef(env, g_sendBuffer);
313 (*env)->DeleteGlobalRef(env, g_uuidList);
316 CAResult_t ret = CALEClientRemoveAllDeviceState();
317 if (CA_STATUS_OK != ret)
319 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
322 ret = CALEClientRemoveAllScanDevices(env);
323 if (CA_STATUS_OK != ret)
325 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
328 ret = CALEClientRemoveAllGattObjs(env);
329 if (CA_STATUS_OK != ret)
331 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
334 g_isStartedMulticastServer = false;
335 CALEClientSetScanFlag(false);
336 CALEClientSetSendFinishFlag(false);
338 CALEClientTerminateGattMutexVariables();
339 CALEClientDestroyJniInterface();
341 ca_cond_free(g_deviceDescCond);
342 ca_cond_free(g_threadCond);
343 ca_cond_free(g_threadWriteCharacteristicCond);
345 g_deviceDescCond = NULL;
347 g_threadWriteCharacteristicCond = NULL;
348 g_isSignalSetFlag = false;
349 CALEClientSetAutoConnectFlag(JNI_FALSE);
353 (*g_jvm)->DetachCurrentThread(g_jvm);
357 CAResult_t CALEClientDestroyJniInterface()
359 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
363 OIC_LOG(ERROR, TAG, "g_jvm is null");
364 return CA_STATUS_FAILED;
367 bool isAttached = false;
369 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
372 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
373 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
377 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
378 return CA_STATUS_FAILED;
383 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
384 if (!jni_LeInterface)
386 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
390 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
391 "destroyLeInterface",
393 if (!jni_InterfaceDestroyMethod)
395 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
399 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
401 if ((*env)->ExceptionCheck(env))
403 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
404 (*env)->ExceptionDescribe(env);
405 (*env)->ExceptionClear(env);
409 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
413 (*g_jvm)->DetachCurrentThread(g_jvm);
422 (*g_jvm)->DetachCurrentThread(g_jvm);
425 return CA_STATUS_FAILED;
428 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
430 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
431 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
435 CAResult_t res = CALEClientDisconnect(env, gatt);
436 if (CA_STATUS_OK != res)
438 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
441 CALEClientUpdateSendCnt(env);
444 CAResult_t CALEClientSendUnicastMessage(const char* address,
446 const uint32_t dataLen)
448 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
449 VERIFY_NON_NULL(address, TAG, "address is null");
450 VERIFY_NON_NULL(data, TAG, "data is null");
452 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
455 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
456 const uint32_t dataLen)
458 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
459 VERIFY_NON_NULL(data, TAG, "data is null");
463 OIC_LOG(ERROR, TAG, "g_jvm is null");
464 return CA_STATUS_FAILED;
467 bool isAttached = false;
469 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
472 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
473 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
477 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
478 return CA_STATUS_FAILED;
483 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
484 if (CA_STATUS_OK != ret)
486 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
491 (*g_jvm)->DetachCurrentThread(g_jvm);
497 CAResult_t CALEClientStartUnicastServer(const char* address)
499 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
501 return CA_NOT_SUPPORTED;
504 CAResult_t CALEClientStartMulticastServer()
506 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
508 if (g_isStartedMulticastServer)
510 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
511 return CA_STATUS_FAILED;
516 OIC_LOG(ERROR, TAG, "g_jvm is null");
517 return CA_STATUS_FAILED;
520 bool isAttached = false;
522 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
525 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
526 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
530 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
531 return CA_STATUS_FAILED;
536 g_isStartedMulticastServer = true;
537 CAResult_t ret = CALEClientStartScan();
538 if (CA_STATUS_OK != ret)
540 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
545 (*g_jvm)->DetachCurrentThread(g_jvm);
551 void CALEClientStopUnicastServer()
553 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
556 void CALEClientStopMulticastServer()
558 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
559 g_isStartedMulticastServer = false;
560 CAResult_t res = CALEClientStopScan();
561 if (CA_STATUS_OK != res)
563 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
568 void CALEClientSetCallback(CAPacketReceiveCallback callback)
570 g_packetReceiveCallback = callback;
573 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
575 g_clientErrorCallback = callback;
578 CAResult_t CALEClientIsThereScannedDevices()
582 return CA_STATUS_FAILED;
585 if (0 == u_arraylist_length(g_deviceList))
587 // Wait for LE peripherals to be discovered.
589 // Number of times to wait for discovery to complete.
590 static size_t const RETRIES = 5;
592 static uint64_t const TIMEOUT =
593 2 * MICROSECS_PER_SEC; // Microseconds
595 bool devicesDiscovered = false;
597 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
600 if (ca_cond_wait_for(g_deviceDescCond,
602 TIMEOUT) == CA_WAIT_SUCCESS)
604 devicesDiscovered = true;
609 // time out for scanning devices
610 if (!devicesDiscovered)
612 return CA_STATUS_FAILED;
619 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
620 const uint32_t dataLen)
622 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
624 VERIFY_NON_NULL(address, TAG, "address is null");
625 VERIFY_NON_NULL(data, TAG, "data is null");
629 OIC_LOG(ERROR, TAG, "g_jvm is null");
630 return CA_STATUS_FAILED;
633 bool isAttached = false;
635 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
638 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
639 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
642 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
643 return CA_STATUS_FAILED;
648 ca_mutex_lock(g_threadSendMutex);
650 CALEClientSetSendFinishFlag(false);
652 CAResult_t ret = CALEClientIsThereScannedDevices();
653 if (CA_STATUS_OK != ret)
655 OIC_LOG(INFO, TAG, "there is no scanned device");
659 if (g_context && g_deviceList)
661 uint32_t length = u_arraylist_length(g_deviceList);
662 for (uint32_t index = 0; index < length; index++)
664 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
667 OIC_LOG(ERROR, TAG, "jarrayObj is null");
671 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
674 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
678 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
681 OIC_LOG(ERROR, TAG, "setAddress is null");
685 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
687 if (!strcmp(setAddress, address))
689 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
691 // connect to gatt server
692 ret = CALEClientStopScan();
693 if (CA_STATUS_OK != ret)
695 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
701 (*env)->DeleteGlobalRef(env, g_sendBuffer);
704 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
705 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
706 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
708 // Target device to send message is just one.
711 ret = CALEClientSendData(env, jarrayObj);
712 if (CA_STATUS_OK != ret)
714 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
718 OIC_LOG(INFO, TAG, "wake up");
721 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
725 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
727 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
728 // if there is no connection state.
729 ca_mutex_lock(g_threadMutex);
730 if (!g_isFinishedSendData)
732 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
733 ca_cond_wait(g_threadCond, g_threadMutex);
734 OIC_LOG(DEBUG, TAG, "the data was sent");
736 ca_mutex_unlock(g_threadMutex);
740 (*g_jvm)->DetachCurrentThread(g_jvm);
743 // start LE Scan again
744 ret = CALEClientStartScan();
745 if (CA_STATUS_OK != ret)
747 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
748 ca_mutex_unlock(g_threadSendMutex);
752 ca_mutex_unlock(g_threadSendMutex);
753 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
754 return CALECheckSendState(address);
759 // start LE Scan again
760 ret = CALEClientStartScan();
761 if (CA_STATUS_OK != ret)
763 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
764 ca_mutex_unlock(g_threadSendMutex);
767 (*g_jvm)->DetachCurrentThread(g_jvm);
774 (*g_jvm)->DetachCurrentThread(g_jvm);
777 if (g_clientErrorCallback)
779 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
781 ca_mutex_unlock(g_threadSendMutex);
782 return CA_SEND_FAILED;
785 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
786 const uint32_t dataLen)
788 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
789 VERIFY_NON_NULL(data, TAG, "data is null");
790 VERIFY_NON_NULL(env, TAG, "env is null");
794 OIC_LOG(ERROR, TAG, "g_deviceList is null");
795 return CA_STATUS_FAILED;
798 ca_mutex_lock(g_threadSendMutex);
800 CALEClientSetSendFinishFlag(false);
802 OIC_LOG(DEBUG, TAG, "set byteArray for data");
805 (*env)->DeleteGlobalRef(env, g_sendBuffer);
809 CAResult_t res = CALEClientIsThereScannedDevices();
810 if (CA_STATUS_OK != res)
812 OIC_LOG(INFO, TAG, "there is no scanned device");
816 // connect to gatt server
817 res = CALEClientStopScan();
818 if (CA_STATUS_OK != res)
820 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
821 ca_mutex_unlock(g_threadSendMutex);
824 uint32_t length = u_arraylist_length(g_deviceList);
825 g_targetCnt = length;
827 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
828 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
829 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
831 for (uint32_t index = 0; index < length; index++)
833 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
836 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
840 res = CALEClientSendData(env, jarrayObj);
841 if (res != CA_STATUS_OK)
843 OIC_LOG(ERROR, TAG, "BT device - send has failed");
846 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
849 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
853 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
856 OIC_LOG(ERROR, TAG, "address is not available");
860 (*env)->ReleaseStringUTFChars(env, jni_address, address);
863 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
865 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
866 ca_mutex_lock(g_threadMutex);
867 if (!g_isFinishedSendData)
869 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
870 ca_cond_wait(g_threadCond, g_threadMutex);
871 OIC_LOG(DEBUG, TAG, "the data was sent");
873 ca_mutex_unlock(g_threadMutex);
875 // start LE Scan again
876 res = CALEClientStartScan();
877 if (CA_STATUS_OK != res)
879 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
880 ca_mutex_unlock(g_threadSendMutex);
884 ca_mutex_unlock(g_threadSendMutex);
885 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
889 res = CALEClientStartScan();
890 if (CA_STATUS_OK != res)
892 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
893 ca_mutex_unlock(g_threadSendMutex);
897 ca_mutex_unlock(g_threadSendMutex);
898 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
899 return CA_SEND_FAILED;
902 CAResult_t CALECheckSendState(const char* address)
904 VERIFY_NON_NULL(address, TAG, "address is null");
906 ca_mutex_lock(g_deviceStateListMutex);
907 CALEState_t* state = CALEClientGetStateInfo(address);
910 OIC_LOG(ERROR, TAG, "state is null");
911 ca_mutex_unlock(g_deviceStateListMutex);
912 return CA_SEND_FAILED;
915 if (STATE_SEND_SUCCESS != state->sendState)
917 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
918 ca_mutex_unlock(g_deviceStateListMutex);
919 return CA_SEND_FAILED;
922 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
923 ca_mutex_unlock(g_deviceStateListMutex);
927 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
929 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
930 VERIFY_NON_NULL(device, TAG, "device is null");
931 VERIFY_NON_NULL(env, TAG, "env is null");
933 // get BLE address from bluetooth device object.
934 char* address = NULL;
935 CALEState_t* state = NULL;
936 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
939 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
940 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
943 OIC_LOG(ERROR, TAG, "address is not available");
944 return CA_STATUS_FAILED;
946 ca_mutex_lock(g_deviceStateListMutex);
947 state = CALEClientGetStateInfo(address);
948 ca_mutex_unlock(g_deviceStateListMutex);
949 (*env)->ReleaseStringUTFChars(env, jni_address, address);
954 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
956 // cancel previous connection request before connection
957 // if there is gatt object in g_gattObjectList.
960 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
963 OIC_LOG(ERROR, TAG, "address is not available");
964 return CA_STATUS_FAILED;
967 jobject gatt = CALEClientGetGattObjInList(env, address);
970 CAResult_t res = CALEClientDisconnect(env, gatt);
971 if (CA_STATUS_OK != res)
973 OIC_LOG(INFO, TAG, "there is no gatt object");
976 (*env)->ReleaseStringUTFChars(env, jni_address, address);
979 // connection request
980 jobject newGatt = CALEClientConnect(env, device, CALEClientGetAutoConnectFlag());
983 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
984 return CA_STATUS_FAILED;
989 if (STATE_CONNECTED == state->connectedState)
991 OIC_LOG(INFO, TAG, "GATT has already connected");
994 OIC_LOG(ERROR, TAG, "jni_address is not available");
995 return CA_STATUS_FAILED;
998 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1001 OIC_LOG(ERROR, TAG, "address is not available");
1002 return CA_STATUS_FAILED;
1005 jobject gatt = CALEClientGetGattObjInList(env, address);
1008 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1009 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1010 return CA_STATUS_FAILED;
1013 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1014 if (CA_STATUS_OK != ret)
1016 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1017 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1020 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1024 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1026 // cancel previous connection request before connection
1027 // if there is gatt object in g_gattObjectList.
1030 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1033 OIC_LOG(ERROR, TAG, "address is not available");
1034 return CA_STATUS_FAILED;
1037 jobject gatt = CALEClientGetGattObjInList(env, address);
1040 CAResult_t res = CALEClientDisconnect(env, gatt);
1041 if (CA_STATUS_OK != res)
1043 OIC_LOG(INFO, TAG, "there is no gatt object");
1046 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1049 OIC_LOG(DEBUG, TAG, "start to connect LE");
1050 jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
1053 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1054 return CA_STATUS_FAILED;
1059 return CA_STATUS_OK;
1062 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1064 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1065 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1067 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1068 if (!jni_cid_gattdevice_list)
1070 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1074 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1075 "()Landroid/bluetooth/BluetoothDevice;");
1076 if (!jni_mid_getDevice)
1078 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1082 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1083 if (!jni_obj_device)
1085 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1089 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1092 OIC_LOG(ERROR, TAG, "jni_address is null");
1102 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1105 OIC_LOG(DEBUG, TAG, "Gatt Close");
1106 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1107 VERIFY_NON_NULL(env, TAG, "env is null");
1109 // get BluetoothGatt class
1110 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1111 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1112 if (!jni_cid_BluetoothGatt)
1114 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1115 return CA_STATUS_FAILED;
1118 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1119 if (!jni_mid_closeGatt)
1121 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1122 return CA_STATUS_OK;
1125 // call disconnect gatt method
1126 OIC_LOG(DEBUG, TAG, "request to close GATT");
1127 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1129 if ((*env)->ExceptionCheck(env))
1131 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1132 (*env)->ExceptionDescribe(env);
1133 (*env)->ExceptionClear(env);
1134 return CA_STATUS_FAILED;
1137 return CA_STATUS_OK;
1140 CAResult_t CALEClientStartScan()
1142 if (!g_isStartedMulticastServer)
1144 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1145 return CA_STATUS_FAILED;
1148 if (!g_isStartedLEClient)
1150 OIC_LOG(ERROR, TAG, "LE client is not started");
1151 return CA_STATUS_FAILED;
1156 OIC_LOG(ERROR, TAG, "g_jvm is null");
1157 return CA_STATUS_FAILED;
1160 if (g_isStartedScan)
1162 OIC_LOG(INFO, TAG, "scanning is already started");
1163 return CA_STATUS_OK;
1166 bool isAttached = false;
1168 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1171 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1173 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1176 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1177 return CA_STATUS_FAILED;
1182 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1184 CAResult_t ret = CA_STATUS_OK;
1185 // scan gatt server with UUID
1186 if (g_leScanCallback && g_uuidList)
1189 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1191 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1193 if (CA_STATUS_OK != ret)
1195 if (CA_ADAPTER_NOT_ENABLED == ret)
1197 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1201 OIC_LOG(ERROR, TAG, "start scan has failed");
1208 (*g_jvm)->DetachCurrentThread(g_jvm);
1214 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1216 VERIFY_NON_NULL(callback, TAG, "callback is null");
1217 VERIFY_NON_NULL(env, TAG, "env is null");
1219 if (!CALEIsEnableBTAdapter(env))
1221 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1222 return CA_ADAPTER_NOT_ENABLED;
1225 // get default bt adapter class
1226 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1227 if (!jni_cid_BTAdapter)
1229 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1230 return CA_STATUS_FAILED;
1233 // get remote bt adapter method
1234 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1235 "getDefaultAdapter",
1236 METHODID_OBJECTNONPARAM);
1237 if (!jni_mid_getDefaultAdapter)
1239 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1240 return CA_STATUS_FAILED;
1243 // get start le scan method
1244 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1245 "(Landroid/bluetooth/BluetoothAdapter$"
1246 "LeScanCallback;)Z");
1247 if (!jni_mid_startLeScan)
1249 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1250 return CA_STATUS_FAILED;
1253 // gat bt adapter object
1254 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1255 jni_mid_getDefaultAdapter);
1256 if (!jni_obj_BTAdapter)
1258 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1259 return CA_STATUS_FAILED;
1262 // call start le scan method
1263 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1264 jni_mid_startLeScan, callback);
1265 if (!jni_obj_startLeScan)
1267 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1268 return CA_STATUS_FAILED;
1272 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1273 CALEClientSetScanFlag(true);
1276 return CA_STATUS_OK;
1279 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1281 VERIFY_NON_NULL(callback, TAG, "callback is null");
1282 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1283 VERIFY_NON_NULL(env, TAG, "env is null");
1285 if (!CALEIsEnableBTAdapter(env))
1287 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1288 return CA_ADAPTER_NOT_ENABLED;
1291 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1292 if (!jni_cid_BTAdapter)
1294 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1295 return CA_STATUS_FAILED;
1298 // get remote bt adapter method
1299 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1300 "getDefaultAdapter",
1301 METHODID_OBJECTNONPARAM);
1302 if (!jni_mid_getDefaultAdapter)
1304 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1305 return CA_STATUS_FAILED;
1308 // get start le scan method
1309 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1310 "([Ljava/util/UUID;Landroid/bluetooth/"
1311 "BluetoothAdapter$LeScanCallback;)Z");
1312 if (!jni_mid_startLeScan)
1314 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1315 return CA_STATUS_FAILED;
1318 // get bt adapter object
1319 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1320 jni_mid_getDefaultAdapter);
1321 if (!jni_obj_BTAdapter)
1323 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1324 return CA_STATUS_FAILED;
1327 // call start le scan method
1328 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1329 jni_mid_startLeScan, uuids, callback);
1330 if (!jni_obj_startLeScan)
1332 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1333 return CA_STATUS_FAILED;
1337 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1338 CALEClientSetScanFlag(true);
1341 return CA_STATUS_OK;
1344 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1346 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1347 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1350 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1353 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1357 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1358 "(Ljava/lang/String;)"
1359 "Ljava/util/UUID;");
1360 if (!jni_mid_fromString)
1362 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1366 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1367 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1371 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1375 return jni_obj_uuid;
1378 CAResult_t CALEClientStopScan()
1382 OIC_LOG(ERROR, TAG, "g_jvm is null");
1383 return CA_STATUS_FAILED;
1386 if (!g_isStartedScan)
1388 OIC_LOG(INFO, TAG, "scanning is already stopped");
1389 return CA_STATUS_OK;
1392 bool isAttached = false;
1394 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1397 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1398 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1401 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1402 return CA_STATUS_FAILED;
1407 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1408 if (CA_STATUS_OK != ret)
1410 if (CA_ADAPTER_NOT_ENABLED == ret)
1412 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1416 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1421 CALEClientSetScanFlag(false);
1426 (*g_jvm)->DetachCurrentThread(g_jvm);
1432 void CALEClientSetScanFlag(bool flag)
1434 ca_mutex_lock(g_scanMutex);
1435 g_isStartedScan = flag;
1436 ca_mutex_unlock(g_scanMutex);
1439 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1441 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1442 VERIFY_NON_NULL(callback, TAG, "callback is null");
1443 VERIFY_NON_NULL(env, TAG, "env is null");
1445 if (!CALEIsEnableBTAdapter(env))
1447 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1448 return CA_ADAPTER_NOT_ENABLED;
1451 // get default bt adapter class
1452 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1453 if (!jni_cid_BTAdapter)
1455 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1456 return CA_STATUS_FAILED;
1459 // get remote bt adapter method
1460 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1461 "getDefaultAdapter",
1462 METHODID_OBJECTNONPARAM);
1463 if (!jni_mid_getDefaultAdapter)
1465 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1466 return CA_STATUS_FAILED;
1469 // get start le scan method
1470 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1471 "(Landroid/bluetooth/"
1472 "BluetoothAdapter$LeScanCallback;)V");
1473 if (!jni_mid_stopLeScan)
1475 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1476 return CA_STATUS_FAILED;
1479 // gat bt adapter object
1480 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1481 jni_mid_getDefaultAdapter);
1482 if (!jni_obj_BTAdapter)
1484 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1485 return CA_STATUS_FAILED;
1488 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1489 // call start le scan method
1490 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1491 if ((*env)->ExceptionCheck(env))
1493 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1494 (*env)->ExceptionDescribe(env);
1495 (*env)->ExceptionClear(env);
1496 return CA_STATUS_FAILED;
1499 return CA_STATUS_OK;
1502 void CALEClientSetAutoConnectFlag(jboolean flag)
1504 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1505 g_autoConnectFlag = flag;
1508 jboolean CALEClientGetAutoConnectFlag()
1510 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", g_autoConnectFlag);
1511 return g_autoConnectFlag;
1514 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1516 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1517 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1518 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1520 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1521 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1524 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1527 OIC_LOG(ERROR, TAG, "address is not available");
1531 // close the gatt service
1532 jobject gatt = CALEClientGetGattObjInList(env, address);
1535 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1536 if (CA_STATUS_OK != res)
1538 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1539 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1543 // clean previous gatt object after close profile service
1544 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1545 if (CA_STATUS_OK != res)
1547 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1548 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1552 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1555 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1558 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1562 // add new gatt object into g_gattObjectList
1563 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1564 if (CA_STATUS_OK != res)
1566 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1573 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1575 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1576 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1577 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1579 if (!CALEIsEnableBTAdapter(env))
1581 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1585 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1588 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1592 // get BluetoothDevice class
1593 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1594 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1595 if (!jni_cid_BluetoothDevice)
1597 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1601 // get connectGatt method
1602 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1603 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1604 "(Landroid/content/Context;ZLandroid/"
1605 "bluetooth/BluetoothGattCallback;)"
1606 "Landroid/bluetooth/BluetoothGatt;");
1607 if (!jni_mid_connectGatt)
1609 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1613 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1614 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1615 jni_mid_connectGatt,
1617 autoconnect, g_leGattCallback);
1618 if (!jni_obj_connectGatt)
1620 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1621 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1622 CALEClientUpdateSendCnt(env);
1627 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1629 return jni_obj_connectGatt;
1632 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1634 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1636 VERIFY_NON_NULL(env, TAG, "env is null");
1637 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1639 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1640 if (!jni_cid_BTAdapter)
1642 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1643 return CA_STATUS_FAILED;
1646 // get remote bt adapter method
1647 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1648 "getDefaultAdapter",
1649 METHODID_OBJECTNONPARAM);
1650 if (!jni_mid_getDefaultAdapter)
1652 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1653 return CA_STATUS_FAILED;
1656 // gat bt adapter object
1657 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1658 jni_mid_getDefaultAdapter);
1659 if (!jni_obj_BTAdapter)
1661 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1662 return CA_STATUS_FAILED;
1665 // get closeProfileProxy method
1666 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1667 "closeProfileProxy",
1668 "(ILandroid/bluetooth/"
1669 "BluetoothProfile;)V");
1670 if (!jni_mid_closeProfileProxy)
1672 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1673 return CA_STATUS_FAILED;
1676 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1677 if (!jni_cid_BTProfile)
1679 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1680 return CA_STATUS_FAILED;
1683 // GATT - Constant value : 7 (0x00000007)
1684 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1688 OIC_LOG(ERROR, TAG, "id_gatt is null");
1689 return CA_STATUS_FAILED;
1692 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1694 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1695 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1696 if ((*env)->ExceptionCheck(env))
1698 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1699 (*env)->ExceptionDescribe(env);
1700 (*env)->ExceptionClear(env);
1701 return CA_STATUS_FAILED;
1704 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1705 return CA_STATUS_OK;
1709 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1711 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1712 VERIFY_NON_NULL(env, TAG, "env is null");
1713 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1715 // get BluetoothGatt class
1716 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1717 if (!jni_cid_BluetoothGatt)
1719 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1720 return CA_STATUS_FAILED;
1723 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1724 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1725 "disconnect", "()V");
1726 if (!jni_mid_disconnectGatt)
1728 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1729 return CA_STATUS_FAILED;
1732 // call disconnect gatt method
1733 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1734 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1735 if ((*env)->ExceptionCheck(env))
1737 OIC_LOG(ERROR, TAG, "disconnect has failed");
1738 (*env)->ExceptionDescribe(env);
1739 (*env)->ExceptionClear(env);
1740 return CA_STATUS_FAILED;
1743 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1745 return CA_STATUS_OK;
1748 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1750 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1751 VERIFY_NON_NULL(env, TAG, "env is null");
1753 if (!g_gattObjectList)
1755 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1756 return CA_STATUS_OK;
1759 uint32_t length = u_arraylist_length(g_gattObjectList);
1760 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1761 for (uint32_t index = 0; index < length; index++)
1763 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1764 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1767 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1770 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1771 if (CA_STATUS_OK != res)
1773 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1778 return CA_STATUS_OK;
1781 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1783 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1784 VERIFY_NON_NULL(env, TAG, "env is null");
1786 if (!g_gattObjectList)
1788 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1789 return CA_STATUS_OK;
1792 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1795 OIC_LOG(ERROR, TAG, "address is null");
1796 return CA_STATUS_FAILED;
1799 uint32_t length = u_arraylist_length(g_gattObjectList);
1800 for (uint32_t index = 0; index < length; index++)
1802 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1805 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1809 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1810 if (!jni_setAddress)
1812 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1813 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1814 return CA_STATUS_FAILED;
1817 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1820 OIC_LOG(ERROR, TAG, "setAddress is null");
1821 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1822 return CA_STATUS_FAILED;
1825 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1826 if (!strcmp(address, setAddress))
1828 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1829 if (CA_STATUS_OK != res)
1831 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1832 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1833 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1834 return CA_STATUS_FAILED;
1836 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1837 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1838 return CA_STATUS_OK;
1840 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1842 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1844 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1845 return CA_STATUS_OK;
1848 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1850 VERIFY_NON_NULL(env, TAG, "env is null");
1851 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1853 if (!CALEIsEnableBTAdapter(env))
1855 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1856 return CA_ADAPTER_NOT_ENABLED;
1859 // get BluetoothGatt class
1860 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1861 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1862 if (!jni_cid_BluetoothGatt)
1864 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1865 return CA_STATUS_FAILED;
1868 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1869 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1870 "discoverServices", "()Z");
1871 if (!jni_mid_discoverServices)
1873 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1874 return CA_STATUS_FAILED;
1876 // call disconnect gatt method
1877 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1878 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1881 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1882 return CA_STATUS_FAILED;
1885 return CA_STATUS_OK;
1888 static void CALEWriteCharacteristicThread(void* object)
1890 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1892 bool isAttached = false;
1894 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1897 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1898 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1902 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1908 jobject gatt = (jobject)object;
1909 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1910 if (CA_STATUS_OK != ret)
1912 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1917 (*g_jvm)->DetachCurrentThread(g_jvm);
1921 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1923 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1924 VERIFY_NON_NULL(env, TAG, "env is null");
1927 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1928 if (!jni_obj_character)
1930 CALEClientSendFinish(env, gatt);
1931 return CA_STATUS_FAILED;
1934 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1935 if (CA_STATUS_OK != ret)
1937 CALEClientSendFinish(env, gatt);
1938 return CA_STATUS_FAILED;
1941 // wait for callback for write Characteristic with success to sent data
1942 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1943 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1944 if (!g_isSignalSetFlag)
1946 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1947 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
1948 g_threadWriteCharacteristicMutex,
1949 WAIT_TIME_WRITE_CHARACTERISTIC))
1951 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1952 g_isSignalSetFlag = false;
1953 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1954 return CA_STATUS_FAILED;
1957 // reset flag set by writeCharacteristic Callback
1958 g_isSignalSetFlag = false;
1959 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1961 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
1962 return CA_STATUS_OK;
1965 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1967 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
1968 VERIFY_NON_NULL(env, TAG, "env is null");
1969 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1971 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
1972 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
1973 CALEWriteCharacteristicThread, (void*)gattParam))
1975 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
1976 return CA_STATUS_FAILED;
1979 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
1980 return CA_STATUS_OK;
1983 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1984 jobject gattCharacteristic)
1986 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1987 VERIFY_NON_NULL(env, TAG, "env is null");
1988 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1989 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1991 if (!CALEIsEnableBTAdapter(env))
1993 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1994 return CA_STATUS_FAILED;
1997 // get BluetoothGatt class
1998 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1999 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2000 if (!jni_cid_BluetoothGatt)
2002 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2003 return CA_STATUS_FAILED;
2006 OIC_LOG(DEBUG, TAG, "write characteristic method");
2007 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2008 "writeCharacteristic",
2009 "(Landroid/bluetooth/"
2010 "BluetoothGattCharacteristic;)Z");
2011 if (!jni_mid_writeCharacteristic)
2013 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2014 return CA_STATUS_FAILED;
2017 // call disconnect gatt method
2018 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2019 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2020 jni_mid_writeCharacteristic,
2021 gattCharacteristic);
2024 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2028 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2029 return CA_STATUS_FAILED;
2032 return CA_STATUS_OK;
2035 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2037 VERIFY_NON_NULL(env, TAG, "env is null");
2038 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2040 if (!CALEIsEnableBTAdapter(env))
2042 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2043 return CA_STATUS_FAILED;
2046 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2047 if (!jni_cid_BluetoothGatt)
2049 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2050 return CA_STATUS_FAILED;
2053 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2056 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2057 return CA_STATUS_FAILED;
2060 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2061 if (!jni_obj_GattCharacteristic)
2063 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2064 return CA_STATUS_FAILED;
2067 OIC_LOG(DEBUG, TAG, "read characteristic method");
2068 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2069 "readCharacteristic",
2070 "(Landroid/bluetooth/"
2071 "BluetoothGattCharacteristic;)Z");
2072 if (!jni_mid_readCharacteristic)
2074 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2075 return CA_STATUS_FAILED;
2078 // call disconnect gatt method
2079 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2080 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2081 jni_obj_GattCharacteristic);
2084 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2088 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2089 return CA_STATUS_FAILED;
2092 return CA_STATUS_OK;
2095 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2096 jobject characteristic)
2098 VERIFY_NON_NULL(env, TAG, "env is null");
2099 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2100 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2102 if (!CALEIsEnableBTAdapter(env))
2104 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2105 return CA_ADAPTER_NOT_ENABLED;
2108 // get BluetoothGatt class
2109 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2110 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2111 if (!jni_cid_BluetoothGatt)
2113 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2114 return CA_STATUS_FAILED;
2117 // set Characteristic Notification
2118 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2119 "setCharacteristicNotification",
2120 "(Landroid/bluetooth/"
2121 "BluetoothGattCharacteristic;Z)Z");
2122 if (!jni_mid_setNotification)
2124 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2125 return CA_STATUS_FAILED;
2128 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2129 characteristic, JNI_TRUE);
2130 if (JNI_TRUE == ret)
2132 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2136 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2137 return CA_STATUS_FAILED;
2140 return CA_STATUS_OK;
2143 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2145 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2146 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2147 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2149 if (!CALEIsEnableBTAdapter(env))
2151 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2155 // get BluetoothGatt class
2156 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2157 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2158 if (!jni_cid_BluetoothGatt)
2160 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2164 jmethodID jni_mid_getService = (*env)->GetMethodID(
2165 env, jni_cid_BluetoothGatt, "getService",
2166 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2167 if (!jni_mid_getService)
2169 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2173 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2174 if (!jni_obj_service_uuid)
2176 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2180 // get bluetooth gatt service
2181 OIC_LOG(DEBUG, TAG, "request to get service");
2182 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2183 jni_obj_service_uuid);
2184 if (!jni_obj_gattService)
2186 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2190 // get bluetooth gatt service class
2191 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2192 env, "android/bluetooth/BluetoothGattService");
2193 if (!jni_cid_BluetoothGattService)
2195 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2199 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2200 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2201 "getCharacteristic",
2202 "(Ljava/util/UUID;)"
2203 "Landroid/bluetooth/"
2204 "BluetoothGattCharacteristic;");
2205 if (!jni_mid_getCharacteristic)
2207 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2211 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2214 OIC_LOG(ERROR, TAG, "uuid is null");
2218 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2219 if (!jni_obj_tx_uuid)
2221 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2222 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2226 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2227 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2228 jni_mid_getCharacteristic,
2231 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2232 return jni_obj_GattCharacteristic;
2235 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2237 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2238 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2239 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2240 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2242 if (!CALEIsEnableBTAdapter(env))
2244 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2248 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2251 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2255 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2256 if (!jni_obj_GattCharacteristic)
2258 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2262 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2263 "/BluetoothGattCharacteristic");
2264 if (!jni_cid_BTGattCharacteristic)
2266 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2270 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2271 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2273 if (!jni_mid_setValue)
2275 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2279 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2281 if (JNI_TRUE == ret)
2283 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2287 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2292 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2293 "setWriteType", "(I)V");
2294 if (!jni_mid_setWriteType)
2296 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2300 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2301 "WRITE_TYPE_NO_RESPONSE", "I");
2302 if (!jni_fid_no_response)
2304 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2308 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2309 jni_fid_no_response);
2311 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2313 return jni_obj_GattCharacteristic;
2316 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2318 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2319 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2321 if (!CALEIsEnableBTAdapter(env))
2323 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2327 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2328 "BluetoothGattCharacteristic");
2329 if (!jni_cid_BTGattCharacteristic)
2331 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2335 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2336 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2338 if (!jni_mid_getValue)
2340 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2344 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2346 return jni_obj_data_array;
2349 CAResult_t CALEClientCreateUUIDList()
2353 OIC_LOG(ERROR, TAG, "g_jvm is null");
2354 return CA_STATUS_FAILED;
2357 bool isAttached = false;
2359 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2362 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2363 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2367 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2368 return CA_STATUS_FAILED;
2373 // create new object array
2374 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2375 if (!jni_cid_uuid_list)
2377 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2381 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2382 jni_cid_uuid_list, NULL);
2383 if (!jni_obj_uuid_list)
2385 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2390 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2393 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2396 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2398 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2402 (*g_jvm)->DetachCurrentThread(g_jvm);
2405 return CA_STATUS_OK;
2412 (*g_jvm)->DetachCurrentThread(g_jvm);
2414 return CA_STATUS_FAILED;
2417 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2418 jobject characteristic)
2420 VERIFY_NON_NULL(env, TAG, "env is null");
2421 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2422 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2424 if (!CALEIsEnableBTAdapter(env))
2426 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2427 return CA_ADAPTER_NOT_ENABLED;
2430 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2431 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2432 "BluetoothGattCharacteristic");
2433 if (!jni_cid_BTGattCharacteristic)
2435 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2436 return CA_STATUS_FAILED;
2439 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2440 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2442 "(Ljava/util/UUID;)Landroid/bluetooth/"
2443 "BluetoothGattDescriptor;");
2444 if (!jni_mid_getDescriptor)
2446 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2447 return CA_STATUS_FAILED;
2450 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2451 if (!jni_obj_cc_uuid)
2453 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2454 return CA_STATUS_FAILED;
2457 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2458 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2459 jni_mid_getDescriptor, jni_obj_cc_uuid);
2460 if (!jni_obj_descriptor)
2462 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2463 return CA_NOT_SUPPORTED;
2466 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2467 jclass jni_cid_descriptor = (*env)->FindClass(env,
2468 "android/bluetooth/BluetoothGattDescriptor");
2469 if (!jni_cid_descriptor)
2471 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2472 return CA_STATUS_FAILED;
2475 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2476 if (!jni_mid_setValue)
2478 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2479 return CA_STATUS_FAILED;
2482 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2483 "ENABLE_NOTIFICATION_VALUE", "[B");
2484 if (!jni_fid_NotiValue)
2486 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2487 return CA_STATUS_FAILED;
2490 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2492 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2493 env, jni_obj_descriptor, jni_mid_setValue,
2494 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2497 OIC_LOG(DEBUG, TAG, "setValue success");
2501 OIC_LOG(ERROR, TAG, "setValue has failed");
2502 return CA_STATUS_FAILED;
2505 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2508 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2509 return CA_STATUS_FAILED;
2512 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2513 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2514 "(Landroid/bluetooth/"
2515 "BluetoothGattDescriptor;)Z");
2516 if (!jni_mid_writeDescriptor)
2518 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2519 return CA_STATUS_FAILED;
2522 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2523 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2524 jni_obj_descriptor);
2527 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2531 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2532 return CA_STATUS_FAILED;
2535 return CA_STATUS_OK;
2538 void CALEClientCreateScanDeviceList(JNIEnv *env)
2540 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2541 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2543 ca_mutex_lock(g_deviceListMutex);
2544 // create new object array
2545 if (g_deviceList == NULL)
2547 OIC_LOG(DEBUG, TAG, "Create device list");
2549 g_deviceList = u_arraylist_create();
2551 ca_mutex_unlock(g_deviceListMutex);
2554 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2556 VERIFY_NON_NULL(device, TAG, "device is null");
2557 VERIFY_NON_NULL(env, TAG, "env is null");
2559 ca_mutex_lock(g_deviceListMutex);
2563 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2564 ca_mutex_unlock(g_deviceListMutex);
2565 return CA_STATUS_FAILED;
2568 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2569 if (!jni_remoteAddress)
2571 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2572 ca_mutex_unlock(g_deviceListMutex);
2573 return CA_STATUS_FAILED;
2576 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2579 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2580 ca_mutex_unlock(g_deviceListMutex);
2581 return CA_STATUS_FAILED;
2584 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2586 jobject gdevice = (*env)->NewGlobalRef(env, device);
2587 u_arraylist_add(g_deviceList, gdevice);
2588 ca_cond_signal(g_deviceDescCond);
2589 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2591 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2593 ca_mutex_unlock(g_deviceListMutex);
2595 return CA_STATUS_OK;
2598 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2600 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2601 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2605 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2609 uint32_t length = u_arraylist_length(g_deviceList);
2610 for (uint32_t index = 0; index < length; index++)
2612 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2615 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2619 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2620 if (!jni_setAddress)
2622 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2626 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2629 OIC_LOG(ERROR, TAG, "setAddress is null");
2633 if (!strcmp(remoteAddress, setAddress))
2635 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2639 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2642 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2647 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2649 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2650 VERIFY_NON_NULL(env, TAG, "env is null");
2652 ca_mutex_lock(g_deviceListMutex);
2656 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2657 ca_mutex_unlock(g_deviceListMutex);
2658 return CA_STATUS_FAILED;
2661 uint32_t length = u_arraylist_length(g_deviceList);
2662 for (uint32_t index = 0; index < length; index++)
2664 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2667 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2670 (*env)->DeleteGlobalRef(env, jarrayObj);
2673 OICFree(g_deviceList);
2674 g_deviceList = NULL;
2676 ca_mutex_unlock(g_deviceListMutex);
2677 return CA_STATUS_OK;
2680 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2682 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2683 VERIFY_NON_NULL(address, TAG, "address is null");
2684 VERIFY_NON_NULL(env, TAG, "env is null");
2686 ca_mutex_lock(g_deviceListMutex);
2690 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2691 ca_mutex_unlock(g_deviceListMutex);
2692 return CA_STATUS_FAILED;
2695 uint32_t length = u_arraylist_length(g_deviceList);
2696 for (uint32_t index = 0; index < length; index++)
2698 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2701 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2702 ca_mutex_unlock(g_deviceListMutex);
2703 return CA_STATUS_FAILED;
2706 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2707 if (!jni_setAddress)
2709 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2710 ca_mutex_unlock(g_deviceListMutex);
2711 return CA_STATUS_FAILED;
2714 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2717 OIC_LOG(ERROR, TAG, "setAddress is null");
2718 ca_mutex_unlock(g_deviceListMutex);
2719 return CA_STATUS_FAILED;
2722 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2725 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2726 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2727 ca_mutex_unlock(g_deviceListMutex);
2728 return CA_STATUS_FAILED;
2731 if (!strcmp(setAddress, remoteAddress))
2733 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2734 (*env)->DeleteGlobalRef(env, jarrayObj);
2735 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2736 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2738 if (NULL == u_arraylist_remove(g_deviceList, index))
2740 OIC_LOG(ERROR, TAG, "List removal failed.");
2741 ca_mutex_unlock(g_deviceListMutex);
2742 return CA_STATUS_FAILED;
2744 ca_mutex_unlock(g_deviceListMutex);
2745 return CA_STATUS_OK;
2747 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2748 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2751 ca_mutex_unlock(g_deviceListMutex);
2752 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2754 return CA_STATUS_OK;
2761 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2763 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2764 VERIFY_NON_NULL(env, TAG, "env is null");
2765 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2767 ca_mutex_lock(g_gattObjectMutex);
2769 if (!g_gattObjectList)
2771 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2772 ca_mutex_unlock(g_gattObjectMutex);
2773 return CA_STATUS_FAILED;
2776 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2777 if (!jni_remoteAddress)
2779 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2780 ca_mutex_unlock(g_gattObjectMutex);
2781 return CA_STATUS_FAILED;
2784 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2787 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2788 ca_mutex_unlock(g_gattObjectMutex);
2789 return CA_STATUS_FAILED;
2792 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2793 if (!CALEClientIsGattObjInList(env, remoteAddress))
2795 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2796 u_arraylist_add(g_gattObjectList, newGatt);
2797 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2800 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2801 ca_mutex_unlock(g_gattObjectMutex);
2802 return CA_STATUS_OK;
2805 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2807 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2808 VERIFY_NON_NULL(env, TAG, "env is null");
2809 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2811 uint32_t length = u_arraylist_length(g_gattObjectList);
2812 for (uint32_t index = 0; index < length; index++)
2815 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2818 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2822 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2823 if (!jni_setAddress)
2825 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2829 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2832 OIC_LOG(ERROR, TAG, "setAddress is null");
2836 if (!strcmp(remoteAddress, setAddress))
2838 OIC_LOG(DEBUG, TAG, "the device is already set");
2839 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2844 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2849 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2853 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2855 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2856 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2857 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2859 ca_mutex_lock(g_gattObjectMutex);
2860 uint32_t length = u_arraylist_length(g_gattObjectList);
2861 for (uint32_t index = 0; index < length; index++)
2863 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2866 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2867 ca_mutex_unlock(g_gattObjectMutex);
2871 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2872 if (!jni_setAddress)
2874 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2875 ca_mutex_unlock(g_gattObjectMutex);
2879 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2882 OIC_LOG(ERROR, TAG, "setAddress is null");
2883 ca_mutex_unlock(g_gattObjectMutex);
2887 if (!strcmp(remoteAddress, setAddress))
2889 OIC_LOG(DEBUG, TAG, "the device is already set");
2890 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2891 ca_mutex_unlock(g_gattObjectMutex);
2894 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2897 ca_mutex_unlock(g_gattObjectMutex);
2898 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2902 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2904 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2905 VERIFY_NON_NULL(env, TAG, "env is null");
2907 ca_mutex_lock(g_gattObjectMutex);
2908 if (!g_gattObjectList)
2910 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2911 ca_mutex_unlock(g_gattObjectMutex);
2912 return CA_STATUS_OK;
2915 uint32_t length = u_arraylist_length(g_gattObjectList);
2916 for (uint32_t index = 0; index < length; index++)
2918 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2921 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2924 (*env)->DeleteGlobalRef(env, jarrayObj);
2927 OICFree(g_gattObjectList);
2928 g_gattObjectList = NULL;
2929 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2930 ca_mutex_unlock(g_gattObjectMutex);
2931 return CA_STATUS_OK;
2934 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2936 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2937 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2938 VERIFY_NON_NULL(env, TAG, "env is null");
2940 ca_mutex_lock(g_gattObjectMutex);
2941 if (!g_gattObjectList)
2943 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2944 ca_mutex_unlock(g_gattObjectMutex);
2945 return CA_STATUS_OK;
2948 uint32_t length = u_arraylist_length(g_gattObjectList);
2949 for (uint32_t index = 0; index < length; index++)
2951 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2954 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2955 ca_mutex_unlock(g_gattObjectMutex);
2956 return CA_STATUS_FAILED;
2959 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2960 if (!jni_setAddress)
2962 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2963 ca_mutex_unlock(g_gattObjectMutex);
2964 return CA_STATUS_FAILED;
2967 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2970 OIC_LOG(ERROR, TAG, "setAddress is null");
2971 ca_mutex_unlock(g_gattObjectMutex);
2972 return CA_STATUS_FAILED;
2975 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2976 if (!jni_remoteAddress)
2978 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2979 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2980 ca_mutex_unlock(g_gattObjectMutex);
2981 return CA_STATUS_FAILED;
2984 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2987 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2988 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2989 ca_mutex_unlock(g_gattObjectMutex);
2990 return CA_STATUS_FAILED;
2993 if (!strcmp(setAddress, remoteAddress))
2995 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2996 (*env)->DeleteGlobalRef(env, jarrayObj);
2997 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2998 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3000 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3002 OIC_LOG(ERROR, TAG, "List removal failed.");
3003 ca_mutex_unlock(g_gattObjectMutex);
3004 return CA_STATUS_FAILED;
3006 ca_mutex_unlock(g_gattObjectMutex);
3007 return CA_STATUS_OK;
3009 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3010 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3013 ca_mutex_unlock(g_gattObjectMutex);
3014 OIC_LOG(DEBUG, TAG, "there are no target object");
3015 return CA_STATUS_OK;
3018 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3020 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3021 VERIFY_NON_NULL(addr, TAG, "addr is null");
3022 VERIFY_NON_NULL(env, TAG, "env is null");
3024 ca_mutex_lock(g_gattObjectMutex);
3025 if (!g_gattObjectList)
3027 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3028 ca_mutex_unlock(g_gattObjectMutex);
3029 return CA_STATUS_OK;
3032 uint32_t length = u_arraylist_length(g_gattObjectList);
3033 for (uint32_t index = 0; index < length; index++)
3035 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3038 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3039 ca_mutex_unlock(g_gattObjectMutex);
3040 return CA_STATUS_FAILED;
3043 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3044 if (!jni_setAddress)
3046 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3047 ca_mutex_unlock(g_gattObjectMutex);
3048 return CA_STATUS_FAILED;
3051 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3054 OIC_LOG(ERROR, TAG, "setAddress is null");
3055 ca_mutex_unlock(g_gattObjectMutex);
3056 return CA_STATUS_FAILED;
3059 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3062 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3063 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3064 ca_mutex_unlock(g_gattObjectMutex);
3065 return CA_STATUS_FAILED;
3068 if (!strcmp(setAddress, remoteAddress))
3070 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3071 (*env)->DeleteGlobalRef(env, jarrayObj);
3073 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3074 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3075 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3077 OIC_LOG(ERROR, TAG, "List removal failed.");
3078 ca_mutex_unlock(g_gattObjectMutex);
3079 return CA_STATUS_FAILED;
3081 ca_mutex_unlock(g_gattObjectMutex);
3082 return CA_STATUS_OK;
3084 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3085 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3088 ca_mutex_unlock(g_gattObjectMutex);
3089 OIC_LOG(DEBUG, TAG, "there are no target object");
3090 return CA_STATUS_FAILED;
3093 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3095 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3097 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3098 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3100 // get Bluetooth Address
3101 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3102 if (!jni_btTargetAddress)
3104 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3108 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3111 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3115 // get method ID of getDevice()
3116 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3117 if (!jni_cid_gattdevice_list)
3119 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3120 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3124 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3125 METHODID_BT_DEVICE);
3126 if (!jni_mid_getDevice)
3128 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3129 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3133 size_t length = u_arraylist_length(g_gattObjectList);
3134 for (size_t index = 0; index < length; index++)
3136 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3139 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3140 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3144 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3145 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3146 if (!jni_obj_device)
3148 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3149 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3153 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3156 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3157 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3161 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3164 OIC_LOG(ERROR, TAG, "btAddress is not available");
3165 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3169 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3170 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3171 if (!strcmp(targetAddress, btAddress))
3173 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3176 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3179 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3181 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3182 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3183 (*env)->DeleteLocalRef(env, jni_btAddress);
3184 (*env)->DeleteLocalRef(env, jni_obj_device);
3185 return jni_LEAddress;
3187 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3188 (*env)->DeleteLocalRef(env, jni_btAddress);
3189 (*env)->DeleteLocalRef(env, jni_obj_device);
3192 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3200 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3201 uint16_t notificationState, uint16_t sendState)
3203 VERIFY_NON_NULL(address, TAG, "address is null");
3205 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3208 OIC_LOG(ERROR, TAG, "out of memory");
3209 return CA_MEMORY_ALLOC_FAILED;
3212 if (strlen(address) > CA_MACADDR_SIZE)
3214 OIC_LOG(ERROR, TAG, "address is not proper");
3216 return CA_STATUS_FAILED;
3219 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3220 newstate->connectedState = connectedState;
3221 newstate->notificationState = notificationState;
3222 newstate->sendState = sendState;
3223 return CALEClientAddDeviceStateToList(newstate);
3226 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3228 VERIFY_NON_NULL(state, TAG, "state is null");
3230 ca_mutex_lock(g_deviceStateListMutex);
3232 if (!g_deviceStateList)
3234 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3235 ca_mutex_unlock(g_deviceStateListMutex);
3236 return CA_STATUS_FAILED;
3239 if (CALEClientIsDeviceInList(state->address))
3241 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3244 OIC_LOG(ERROR, TAG, "curState is null");
3245 ca_mutex_unlock(g_deviceStateListMutex);
3246 return CA_STATUS_FAILED;
3249 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3251 state->notificationState = curState->notificationState;
3254 // delete previous state for update new state
3255 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3256 if (CA_STATUS_OK != res)
3258 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3259 ca_mutex_unlock(g_deviceStateListMutex);
3263 u_arraylist_add(g_deviceStateList, state); // update new state
3264 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3265 state->connectedState, state->notificationState, state->address);
3267 ca_mutex_unlock(g_deviceStateListMutex);
3268 return CA_STATUS_OK;
3271 bool CALEClientIsDeviceInList(const char* remoteAddress)
3273 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3275 if (!g_deviceStateList)
3277 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3281 uint32_t length = u_arraylist_length(g_deviceStateList);
3282 for (uint32_t index = 0; index < length; index++)
3284 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3287 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3291 if (!strcmp(remoteAddress, state->address))
3293 OIC_LOG(DEBUG, TAG, "the device is already set");
3302 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3306 CAResult_t CALEClientRemoveAllDeviceState()
3308 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3310 ca_mutex_lock(g_deviceStateListMutex);
3311 if (!g_deviceStateList)
3313 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3314 ca_mutex_unlock(g_deviceStateListMutex);
3315 return CA_STATUS_FAILED;
3318 uint32_t length = u_arraylist_length(g_deviceStateList);
3319 for (uint32_t index = 0; index < length; index++)
3321 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3324 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3330 OICFree(g_deviceStateList);
3331 g_deviceStateList = NULL;
3332 ca_mutex_unlock(g_deviceStateListMutex);
3334 return CA_STATUS_OK;
3337 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3339 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3340 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3342 if (!g_deviceStateList)
3344 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3345 return CA_STATUS_FAILED;
3348 uint32_t length = u_arraylist_length(g_deviceStateList);
3349 for (uint32_t index = 0; index < length; index++)
3351 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3354 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3358 if (!strcmp(state->address, remoteAddress))
3360 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3362 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3364 if (NULL == targetState)
3366 OIC_LOG(ERROR, TAG, "List removal failed.");
3367 return CA_STATUS_FAILED;
3370 OICFree(targetState);
3371 return CA_STATUS_OK;
3375 return CA_STATUS_OK;
3378 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3380 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3381 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3383 if (!g_deviceStateList)
3385 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3389 uint32_t length = u_arraylist_length(g_deviceStateList);
3390 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3392 for (uint32_t index = 0; index < length; index++)
3394 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3397 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3401 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3402 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3404 if (!strcmp(state->address, remoteAddress))
3406 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3413 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3415 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3416 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3418 ca_mutex_lock(g_deviceStateListMutex);
3419 if (!g_deviceStateList)
3421 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3422 ca_mutex_unlock(g_deviceStateListMutex);
3426 uint32_t length = u_arraylist_length(g_deviceStateList);
3427 for (uint32_t index = 0; index < length; index++)
3429 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3432 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3436 if (!strcmp(state->address, remoteAddress))
3438 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3440 if (STATE_CONNECTED == state->connectedState)
3442 ca_mutex_unlock(g_deviceStateListMutex);
3447 ca_mutex_unlock(g_deviceStateListMutex);
3452 ca_mutex_unlock(g_deviceStateListMutex);
3456 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3458 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3459 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3461 ca_mutex_lock(g_deviceStateListMutex);
3462 if (!g_deviceStateList)
3464 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3465 ca_mutex_unlock(g_deviceStateListMutex);
3469 uint32_t length = u_arraylist_length(g_deviceStateList);
3470 for (uint32_t index = 0; index < length; index++)
3472 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3475 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3479 if (!strcmp(state->address, remoteAddress))
3481 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3483 if (STATE_CHARACTER_SET == state->notificationState)
3485 ca_mutex_unlock(g_deviceStateListMutex);
3490 ca_mutex_unlock(g_deviceStateListMutex);
3496 ca_mutex_unlock(g_deviceStateListMutex);
3500 void CALEClientCreateDeviceList()
3502 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3504 // create new object array
3505 if (!g_gattObjectList)
3507 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3509 g_gattObjectList = u_arraylist_create();
3512 if (!g_deviceStateList)
3514 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3516 g_deviceStateList = u_arraylist_create();
3521 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3523 g_deviceList = u_arraylist_create();
3528 * Check Sent Count for remove g_sendBuffer
3530 void CALEClientUpdateSendCnt(JNIEnv *env)
3532 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3534 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3536 ca_mutex_lock(g_threadMutex);
3540 if (g_targetCnt <= g_currentSentCnt)
3543 g_currentSentCnt = 0;
3547 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3548 g_sendBuffer = NULL;
3550 // notity the thread
3551 ca_cond_signal(g_threadCond);
3553 CALEClientSetSendFinishFlag(true);
3554 OIC_LOG(DEBUG, TAG, "set signal for send data");
3557 ca_mutex_unlock(g_threadMutex);
3560 CAResult_t CALEClientInitGattMutexVaraibles()
3562 if (NULL == g_bleReqRespClientCbMutex)
3564 g_bleReqRespClientCbMutex = ca_mutex_new();
3565 if (NULL == g_bleReqRespClientCbMutex)
3567 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3568 return CA_STATUS_FAILED;
3572 if (NULL == g_bleServerBDAddressMutex)
3574 g_bleServerBDAddressMutex = ca_mutex_new();
3575 if (NULL == g_bleServerBDAddressMutex)
3577 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3578 return CA_STATUS_FAILED;
3582 if (NULL == g_threadMutex)
3584 g_threadMutex = ca_mutex_new();
3585 if (NULL == g_threadMutex)
3587 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3588 return CA_STATUS_FAILED;
3592 if (NULL == g_threadSendMutex)
3594 g_threadSendMutex = ca_mutex_new();
3595 if (NULL == g_threadSendMutex)
3597 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3598 return CA_STATUS_FAILED;
3602 if (NULL == g_deviceListMutex)
3604 g_deviceListMutex = ca_mutex_new();
3605 if (NULL == g_deviceListMutex)
3607 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3608 return CA_STATUS_FAILED;
3612 if (NULL == g_gattObjectMutex)
3614 g_gattObjectMutex = ca_mutex_new();
3615 if (NULL == g_gattObjectMutex)
3617 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3618 return CA_STATUS_FAILED;
3622 if (NULL == g_deviceStateListMutex)
3624 g_deviceStateListMutex = ca_mutex_new();
3625 if (NULL == g_deviceStateListMutex)
3627 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3628 return CA_STATUS_FAILED;
3632 if (NULL == g_SendFinishMutex)
3634 g_SendFinishMutex = ca_mutex_new();
3635 if (NULL == g_SendFinishMutex)
3637 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3638 return CA_STATUS_FAILED;
3642 if (NULL == g_scanMutex)
3644 g_scanMutex = ca_mutex_new();
3645 if (NULL == g_scanMutex)
3647 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3648 return CA_STATUS_FAILED;
3652 if (NULL == g_threadWriteCharacteristicMutex)
3654 g_threadWriteCharacteristicMutex = ca_mutex_new();
3655 if (NULL == g_threadWriteCharacteristicMutex)
3657 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3658 return CA_STATUS_FAILED;
3662 return CA_STATUS_OK;
3665 void CALEClientTerminateGattMutexVariables()
3667 ca_mutex_free(g_bleReqRespClientCbMutex);
3668 g_bleReqRespClientCbMutex = NULL;
3670 ca_mutex_free(g_bleServerBDAddressMutex);
3671 g_bleServerBDAddressMutex = NULL;
3673 ca_mutex_free(g_threadMutex);
3674 g_threadMutex = NULL;
3676 ca_mutex_free(g_threadSendMutex);
3677 g_threadSendMutex = NULL;
3679 ca_mutex_free(g_deviceListMutex);
3680 g_deviceListMutex = NULL;
3682 ca_mutex_free(g_SendFinishMutex);
3683 g_SendFinishMutex = NULL;
3685 ca_mutex_free(g_scanMutex);
3688 ca_mutex_free(g_threadWriteCharacteristicMutex);
3689 g_threadWriteCharacteristicMutex = NULL;
3692 void CALEClientSetSendFinishFlag(bool flag)
3694 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3696 ca_mutex_lock(g_SendFinishMutex);
3697 g_isFinishedSendData = flag;
3698 ca_mutex_unlock(g_SendFinishMutex);
3705 CAResult_t CAStartLEGattClient()
3707 CAResult_t res = CALEClientStartMulticastServer();
3708 if (CA_STATUS_OK != res)
3710 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3714 g_isStartedLEClient = true;
3720 void CAStopLEGattClient()
3722 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3726 OIC_LOG(ERROR, TAG, "g_jvm is null");
3730 bool isAttached = false;
3732 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3735 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3736 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3740 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3746 CAResult_t ret = CALEClientDisconnectAll(env);
3747 if (CA_STATUS_OK != ret)
3749 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3752 ret = CALEClientStopScan();
3753 if(CA_STATUS_OK != ret)
3755 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3758 ca_mutex_lock(g_threadMutex);
3759 ca_cond_signal(g_threadCond);
3760 ca_mutex_unlock(g_threadMutex);
3762 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3763 ca_cond_signal(g_threadWriteCharacteristicCond);
3764 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3768 (*g_jvm)->DetachCurrentThread(g_jvm);
3773 CAResult_t CAInitializeLEGattClient()
3775 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3776 CALEClientInitialize();
3777 return CA_STATUS_OK;
3780 void CATerminateLEGattClient()
3782 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3783 CAStopLEGattClient();
3784 CALEClientTerminate();
3787 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3788 uint32_t dataLen, CALETransferType_t type,
3791 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3792 VERIFY_NON_NULL(data, TAG, "data is null");
3793 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3795 if (LE_UNICAST != type || position < 0)
3797 OIC_LOG(ERROR, TAG, "this request is not unicast");
3798 return CA_STATUS_INVALID_PARAM;
3801 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3804 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3806 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3807 VERIFY_NON_NULL(data, TAG, "data is null");
3809 return CALEClientSendMulticastMessage(data, dataLen);
3812 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3814 ca_mutex_lock(g_bleReqRespClientCbMutex);
3815 g_CABLEClientDataReceivedCallback = callback;
3816 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3819 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3821 g_threadPoolHandle = handle;
3824 CAResult_t CAGetLEAddress(char **local_address)
3826 VERIFY_NON_NULL(local_address, TAG, "local_address");
3827 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3828 return CA_NOT_SUPPORTED;
3831 JNIEXPORT void JNICALL
3832 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3835 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3836 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3837 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3838 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3840 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3843 JNIEXPORT void JNICALL
3844 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3847 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3848 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3849 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3850 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3852 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3855 JNIEXPORT void JNICALL
3856 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3859 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3860 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3861 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3863 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3864 if (CA_STATUS_OK != res)
3866 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3871 * Class: org_iotivity_ca_jar_caleinterface
3872 * Method: CALeGattConnectionStateChangeCallback
3873 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3875 JNIEXPORT void JNICALL
3876 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3882 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3884 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3885 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3886 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3888 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
3889 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
3890 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
3892 if (gatt_success == status && state_connected == newstate) // le connected
3894 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3900 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3903 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3904 STATE_CHARACTER_NO_CHANGE,
3906 if (CA_STATUS_OK != res)
3908 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3909 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3912 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
3914 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3917 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3918 if (CA_STATUS_OK != res)
3920 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3924 res = CALEClientDiscoverServices(env, gatt);
3925 if (CA_STATUS_OK != res)
3927 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3931 else if (GATT_ERROR == status && state_disconnected == newstate)
3933 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
3935 else // le disconnected
3937 CAResult_t res = CALEClientStartScan();
3938 if (CA_STATUS_OK != res)
3940 if (CA_ADAPTER_NOT_ENABLED == res)
3942 // scan will be started with start server when adapter is enabled
3943 OIC_LOG(INFO, TAG, "Adapter was disabled");
3947 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3952 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3955 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3959 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3962 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3963 STATE_CHARACTER_UNSET,
3965 if (CA_STATUS_OK != res)
3967 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3968 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3971 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
3973 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3976 res = CALEClientGattClose(env, gatt);
3977 if (CA_STATUS_OK != res)
3979 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3984 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3985 g_sendBuffer = NULL;
3993 CALEClientSendFinish(env, gatt);
3998 * Class: org_iotivity_ca_jar_caleinterface
3999 * Method: CALeGattServicesDiscoveredCallback
4000 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4002 JNIEXPORT void JNICALL
4003 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4008 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4009 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4010 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4011 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4013 if (0 != status) // discovery error
4015 CALEClientSendFinish(env, gatt);
4019 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4022 CALEClientSendFinish(env, gatt);
4026 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4029 CALEClientSendFinish(env, gatt);
4033 if (!CALEClientIsSetCharacteristic(address))
4035 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4038 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4042 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4043 if (!jni_obj_GattCharacteristic)
4045 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4049 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4050 jni_obj_GattCharacteristic);
4051 if (CA_STATUS_OK != res)
4053 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4057 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4058 if (CA_STATUS_OK != res)
4060 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4063 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4064 if (CA_STATUS_OK != res)
4066 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4072 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4074 if (CA_STATUS_OK != res)
4076 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4082 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4083 if (CA_STATUS_OK != res)
4085 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4089 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4090 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4095 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4096 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4097 CALEClientSendFinish(env, gatt);
4102 * Class: org_iotivity_ca_jar_caleinterface
4103 * Method: CALeGattCharacteristicWritjclasseCallback
4104 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4106 JNIEXPORT void JNICALL
4107 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4108 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4111 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4112 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4113 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4114 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4117 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
4119 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
4121 // send success & signal
4122 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4128 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4134 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4135 if (gatt_success != status) // error case
4137 OIC_LOG(ERROR, TAG, "send failure");
4140 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4141 if (CA_STATUS_OK != res)
4143 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4144 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4145 g_isSignalSetFlag = true;
4146 ca_cond_signal(g_threadWriteCharacteristicCond);
4147 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4149 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4150 STATE_CHARACTER_SET,
4152 if (CA_STATUS_OK != res)
4154 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4157 if (g_clientErrorCallback)
4159 jint length = (*env)->GetArrayLength(env, data);
4160 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4163 CALEClientSendFinish(env, gatt);
4169 OIC_LOG(DEBUG, TAG, "send success");
4170 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4171 STATE_SEND_SUCCESS);
4172 if (CA_STATUS_OK != res)
4174 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4177 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4178 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4179 g_isSignalSetFlag = true;
4180 ca_cond_signal(g_threadWriteCharacteristicCond);
4181 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4183 CALEClientUpdateSendCnt(env);
4186 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4192 CALEClientSendFinish(env, gatt);
4197 * Class: org_iotivity_ca_jar_caleinterface
4198 * Method: CALeGattCharacteristicChangedCallback
4199 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4201 JNIEXPORT void JNICALL
4202 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4203 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4205 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4206 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4207 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4208 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4209 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4211 // get Byte Array and convert to uint8_t*
4212 jint length = (*env)->GetArrayLength(env, data);
4215 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4217 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4218 jni_byte_responseData);
4220 uint8_t* receivedData = OICMalloc(length);
4223 OIC_LOG(ERROR, TAG, "receivedData is null");
4227 memcpy(receivedData, jni_byte_responseData, length);
4228 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4230 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4233 OIC_LOG(ERROR, TAG, "jni_address is null");
4234 OICFree(receivedData);
4238 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4241 OIC_LOG(ERROR, TAG, "address is null");
4242 OICFree(receivedData);
4246 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4247 receivedData, length);
4249 ca_mutex_lock(g_bleServerBDAddressMutex);
4250 uint32_t sentLength = 0;
4251 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4253 ca_mutex_unlock(g_bleServerBDAddressMutex);
4255 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4259 * Class: org_iotivity_ca_jar_caleinterface
4260 * Method: CALeGattDescriptorWriteCallback
4261 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4263 JNIEXPORT void JNICALL
4264 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4268 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4269 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4270 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4271 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4273 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4274 if (gatt_success != status) // error
4281 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4282 if (CA_STATUS_OK != res)
4284 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4293 CALEClientSendFinish(env, gatt);