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 success");
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;
921 ca_mutex_unlock(g_deviceStateListMutex);
925 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
927 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
928 VERIFY_NON_NULL(device, TAG, "device is null");
929 VERIFY_NON_NULL(env, TAG, "env is null");
931 // get BLE address from bluetooth device object.
932 char* address = NULL;
933 CALEState_t* state = NULL;
934 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
937 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
938 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
941 OIC_LOG(ERROR, TAG, "address is not available");
942 return CA_STATUS_FAILED;
944 ca_mutex_lock(g_deviceStateListMutex);
945 state = CALEClientGetStateInfo(address);
946 ca_mutex_unlock(g_deviceStateListMutex);
947 (*env)->ReleaseStringUTFChars(env, jni_address, address);
952 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
954 // cancel previous connection request before connection
955 // if there is gatt object in g_gattObjectList.
958 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
961 OIC_LOG(ERROR, TAG, "address is not available");
962 return CA_STATUS_FAILED;
965 jobject gatt = CALEClientGetGattObjInList(env, address);
968 CAResult_t res = CALEClientDisconnect(env, gatt);
969 if (CA_STATUS_OK != res)
971 OIC_LOG(INFO, TAG, "there is no gatt object");
974 (*env)->ReleaseStringUTFChars(env, jni_address, address);
977 // connection request
978 jobject newGatt = CALEClientConnect(env, device, CALEClientGetAutoConnectFlag());
981 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
982 return CA_STATUS_FAILED;
987 if (STATE_CONNECTED == state->connectedState)
989 OIC_LOG(INFO, TAG, "GATT has already connected");
992 OIC_LOG(ERROR, TAG, "jni_address is not available");
993 return CA_STATUS_FAILED;
996 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
999 OIC_LOG(ERROR, TAG, "address is not available");
1000 return CA_STATUS_FAILED;
1003 jobject gatt = CALEClientGetGattObjInList(env, address);
1006 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1007 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1008 return CA_STATUS_FAILED;
1011 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1012 if (CA_STATUS_OK != ret)
1014 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1015 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1018 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1022 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1024 // cancel previous connection request before connection
1025 // if there is gatt object in g_gattObjectList.
1028 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
1031 OIC_LOG(ERROR, TAG, "address is not available");
1032 return CA_STATUS_FAILED;
1035 jobject gatt = CALEClientGetGattObjInList(env, address);
1038 CAResult_t res = CALEClientDisconnect(env, gatt);
1039 if (CA_STATUS_OK != res)
1041 OIC_LOG(INFO, TAG, "there is no gatt object");
1044 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1047 OIC_LOG(DEBUG, TAG, "start to connect LE");
1048 jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
1051 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1052 return CA_STATUS_FAILED;
1057 return CA_STATUS_OK;
1060 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1062 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1063 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1065 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1066 if (!jni_cid_gattdevice_list)
1068 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1072 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1073 "()Landroid/bluetooth/BluetoothDevice;");
1074 if (!jni_mid_getDevice)
1076 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1080 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1081 if (!jni_obj_device)
1083 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1087 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1090 OIC_LOG(ERROR, TAG, "jni_address is null");
1100 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1103 OIC_LOG(DEBUG, TAG, "Gatt Close");
1104 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1105 VERIFY_NON_NULL(env, TAG, "env is null");
1107 // get BluetoothGatt class
1108 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1109 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1110 if (!jni_cid_BluetoothGatt)
1112 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1113 return CA_STATUS_FAILED;
1116 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1117 if (!jni_mid_closeGatt)
1119 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1120 return CA_STATUS_OK;
1123 // call disconnect gatt method
1124 OIC_LOG(DEBUG, TAG, "request to close GATT");
1125 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1127 if ((*env)->ExceptionCheck(env))
1129 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1130 (*env)->ExceptionDescribe(env);
1131 (*env)->ExceptionClear(env);
1132 return CA_STATUS_FAILED;
1135 return CA_STATUS_OK;
1138 CAResult_t CALEClientStartScan()
1140 if (!g_isStartedMulticastServer)
1142 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1143 return CA_STATUS_FAILED;
1146 if (!g_isStartedLEClient)
1148 OIC_LOG(ERROR, TAG, "LE client is not started");
1149 return CA_STATUS_FAILED;
1154 OIC_LOG(ERROR, TAG, "g_jvm is null");
1155 return CA_STATUS_FAILED;
1158 if (g_isStartedScan)
1160 OIC_LOG(INFO, TAG, "scanning is already started");
1161 return CA_STATUS_OK;
1164 bool isAttached = false;
1166 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1169 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1171 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1174 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1175 return CA_STATUS_FAILED;
1180 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1182 CAResult_t ret = CA_STATUS_OK;
1183 // scan gatt server with UUID
1184 if (g_leScanCallback && g_uuidList)
1187 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1189 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1191 if (CA_STATUS_OK != ret)
1193 if (CA_ADAPTER_NOT_ENABLED == ret)
1195 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1199 OIC_LOG(ERROR, TAG, "start scan has failed");
1206 (*g_jvm)->DetachCurrentThread(g_jvm);
1212 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1214 VERIFY_NON_NULL(callback, TAG, "callback is null");
1215 VERIFY_NON_NULL(env, TAG, "env is null");
1217 if (!CALEIsEnableBTAdapter(env))
1219 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1220 return CA_ADAPTER_NOT_ENABLED;
1223 // get default bt adapter class
1224 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1225 if (!jni_cid_BTAdapter)
1227 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1228 return CA_STATUS_FAILED;
1231 // get remote bt adapter method
1232 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1233 "getDefaultAdapter",
1234 METHODID_OBJECTNONPARAM);
1235 if (!jni_mid_getDefaultAdapter)
1237 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1238 return CA_STATUS_FAILED;
1241 // get start le scan method
1242 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1243 "(Landroid/bluetooth/BluetoothAdapter$"
1244 "LeScanCallback;)Z");
1245 if (!jni_mid_startLeScan)
1247 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1248 return CA_STATUS_FAILED;
1251 // gat bt adapter object
1252 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1253 jni_mid_getDefaultAdapter);
1254 if (!jni_obj_BTAdapter)
1256 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1257 return CA_STATUS_FAILED;
1260 // call start le scan method
1261 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1262 jni_mid_startLeScan, callback);
1263 if (!jni_obj_startLeScan)
1265 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1266 return CA_STATUS_FAILED;
1270 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1271 CALEClientSetScanFlag(true);
1274 return CA_STATUS_OK;
1277 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1279 VERIFY_NON_NULL(callback, TAG, "callback is null");
1280 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1281 VERIFY_NON_NULL(env, TAG, "env is null");
1283 if (!CALEIsEnableBTAdapter(env))
1285 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1286 return CA_ADAPTER_NOT_ENABLED;
1289 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1290 if (!jni_cid_BTAdapter)
1292 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1293 return CA_STATUS_FAILED;
1296 // get remote bt adapter method
1297 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1298 "getDefaultAdapter",
1299 METHODID_OBJECTNONPARAM);
1300 if (!jni_mid_getDefaultAdapter)
1302 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1303 return CA_STATUS_FAILED;
1306 // get start le scan method
1307 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1308 "([Ljava/util/UUID;Landroid/bluetooth/"
1309 "BluetoothAdapter$LeScanCallback;)Z");
1310 if (!jni_mid_startLeScan)
1312 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1313 return CA_STATUS_FAILED;
1316 // get bt adapter object
1317 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1318 jni_mid_getDefaultAdapter);
1319 if (!jni_obj_BTAdapter)
1321 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1322 return CA_STATUS_FAILED;
1325 // call start le scan method
1326 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1327 jni_mid_startLeScan, uuids, callback);
1328 if (!jni_obj_startLeScan)
1330 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1331 return CA_STATUS_FAILED;
1335 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1336 CALEClientSetScanFlag(true);
1339 return CA_STATUS_OK;
1342 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1344 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1345 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1348 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1351 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1355 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1356 "(Ljava/lang/String;)"
1357 "Ljava/util/UUID;");
1358 if (!jni_mid_fromString)
1360 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1364 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1365 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1369 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1373 return jni_obj_uuid;
1376 CAResult_t CALEClientStopScan()
1380 OIC_LOG(ERROR, TAG, "g_jvm is null");
1381 return CA_STATUS_FAILED;
1384 if (!g_isStartedScan)
1386 OIC_LOG(INFO, TAG, "scanning is already stopped");
1387 return CA_STATUS_OK;
1390 bool isAttached = false;
1392 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1395 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1396 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1399 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1400 return CA_STATUS_FAILED;
1405 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1406 if (CA_STATUS_OK != ret)
1408 if (CA_ADAPTER_NOT_ENABLED == ret)
1410 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1414 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1419 CALEClientSetScanFlag(false);
1424 (*g_jvm)->DetachCurrentThread(g_jvm);
1430 void CALEClientSetScanFlag(bool flag)
1432 ca_mutex_lock(g_scanMutex);
1433 g_isStartedScan = flag;
1434 ca_mutex_unlock(g_scanMutex);
1437 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1439 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1440 VERIFY_NON_NULL(callback, TAG, "callback is null");
1441 VERIFY_NON_NULL(env, TAG, "env is null");
1443 if (!CALEIsEnableBTAdapter(env))
1445 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1446 return CA_ADAPTER_NOT_ENABLED;
1449 // get default bt adapter class
1450 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1451 if (!jni_cid_BTAdapter)
1453 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1454 return CA_STATUS_FAILED;
1457 // get remote bt adapter method
1458 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1459 "getDefaultAdapter",
1460 METHODID_OBJECTNONPARAM);
1461 if (!jni_mid_getDefaultAdapter)
1463 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1464 return CA_STATUS_FAILED;
1467 // get start le scan method
1468 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1469 "(Landroid/bluetooth/"
1470 "BluetoothAdapter$LeScanCallback;)V");
1471 if (!jni_mid_stopLeScan)
1473 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1474 return CA_STATUS_FAILED;
1477 // gat bt adapter object
1478 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1479 jni_mid_getDefaultAdapter);
1480 if (!jni_obj_BTAdapter)
1482 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1483 return CA_STATUS_FAILED;
1486 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1487 // call start le scan method
1488 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1489 if ((*env)->ExceptionCheck(env))
1491 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1492 (*env)->ExceptionDescribe(env);
1493 (*env)->ExceptionClear(env);
1494 return CA_STATUS_FAILED;
1497 return CA_STATUS_OK;
1500 void CALEClientSetAutoConnectFlag(jboolean flag)
1502 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1503 g_autoConnectFlag = flag;
1506 jboolean CALEClientGetAutoConnectFlag()
1508 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", g_autoConnectFlag);
1509 return g_autoConnectFlag;
1512 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1514 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1515 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1516 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1518 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1519 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1522 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1525 OIC_LOG(ERROR, TAG, "address is not available");
1529 // close the gatt service
1530 jobject gatt = CALEClientGetGattObjInList(env, address);
1533 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1534 if (CA_STATUS_OK != res)
1536 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1537 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1541 // clean previous gatt object after close profile service
1542 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1543 if (CA_STATUS_OK != res)
1545 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1546 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1550 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1553 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1556 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1560 // add new gatt object into g_gattObjectList
1561 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1562 if (CA_STATUS_OK != res)
1564 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1571 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1573 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1574 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1575 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1577 if (!CALEIsEnableBTAdapter(env))
1579 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1583 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1586 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1590 // get BluetoothDevice class
1591 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1592 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1593 if (!jni_cid_BluetoothDevice)
1595 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1599 // get connectGatt method
1600 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1601 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1602 "(Landroid/content/Context;ZLandroid/"
1603 "bluetooth/BluetoothGattCallback;)"
1604 "Landroid/bluetooth/BluetoothGatt;");
1605 if (!jni_mid_connectGatt)
1607 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1611 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1612 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1613 jni_mid_connectGatt,
1615 autoconnect, g_leGattCallback);
1616 if (!jni_obj_connectGatt)
1618 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1619 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1620 CALEClientUpdateSendCnt(env);
1625 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1627 return jni_obj_connectGatt;
1630 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1632 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1634 VERIFY_NON_NULL(env, TAG, "env is null");
1635 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1637 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1638 if (!jni_cid_BTAdapter)
1640 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1641 return CA_STATUS_FAILED;
1644 // get remote bt adapter method
1645 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1646 "getDefaultAdapter",
1647 METHODID_OBJECTNONPARAM);
1648 if (!jni_mid_getDefaultAdapter)
1650 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1651 return CA_STATUS_FAILED;
1654 // gat bt adapter object
1655 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1656 jni_mid_getDefaultAdapter);
1657 if (!jni_obj_BTAdapter)
1659 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1660 return CA_STATUS_FAILED;
1663 // get closeProfileProxy method
1664 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1665 "closeProfileProxy",
1666 "(ILandroid/bluetooth/"
1667 "BluetoothProfile;)V");
1668 if (!jni_mid_closeProfileProxy)
1670 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1671 return CA_STATUS_FAILED;
1674 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1675 if (!jni_cid_BTProfile)
1677 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1678 return CA_STATUS_FAILED;
1681 // GATT - Constant value : 7 (0x00000007)
1682 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1686 OIC_LOG(ERROR, TAG, "id_gatt is null");
1687 return CA_STATUS_FAILED;
1690 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1692 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1693 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1694 if ((*env)->ExceptionCheck(env))
1696 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1697 (*env)->ExceptionDescribe(env);
1698 (*env)->ExceptionClear(env);
1699 return CA_STATUS_FAILED;
1702 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1703 return CA_STATUS_OK;
1707 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1709 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1710 VERIFY_NON_NULL(env, TAG, "env is null");
1711 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1713 // get BluetoothGatt class
1714 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1715 if (!jni_cid_BluetoothGatt)
1717 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1718 return CA_STATUS_FAILED;
1721 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1722 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1723 "disconnect", "()V");
1724 if (!jni_mid_disconnectGatt)
1726 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1727 return CA_STATUS_FAILED;
1730 // call disconnect gatt method
1731 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1732 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1733 if ((*env)->ExceptionCheck(env))
1735 OIC_LOG(ERROR, TAG, "disconnect has failed");
1736 (*env)->ExceptionDescribe(env);
1737 (*env)->ExceptionClear(env);
1738 return CA_STATUS_FAILED;
1741 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1743 return CA_STATUS_OK;
1746 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1748 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1749 VERIFY_NON_NULL(env, TAG, "env is null");
1751 if (!g_gattObjectList)
1753 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1754 return CA_STATUS_OK;
1757 uint32_t length = u_arraylist_length(g_gattObjectList);
1758 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1759 for (uint32_t index = 0; index < length; index++)
1761 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1762 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1765 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1768 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1769 if (CA_STATUS_OK != res)
1771 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1776 return CA_STATUS_OK;
1779 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1781 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1782 VERIFY_NON_NULL(env, TAG, "env is null");
1784 if (!g_gattObjectList)
1786 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1787 return CA_STATUS_OK;
1790 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1793 OIC_LOG(ERROR, TAG, "address is null");
1794 return CA_STATUS_FAILED;
1797 uint32_t length = u_arraylist_length(g_gattObjectList);
1798 for (uint32_t index = 0; index < length; index++)
1800 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1803 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1807 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1808 if (!jni_setAddress)
1810 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1811 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1812 return CA_STATUS_FAILED;
1815 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1818 OIC_LOG(ERROR, TAG, "setAddress is null");
1819 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1820 return CA_STATUS_FAILED;
1823 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1824 if (!strcmp(address, setAddress))
1826 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1827 if (CA_STATUS_OK != res)
1829 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1830 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1831 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1832 return CA_STATUS_FAILED;
1834 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1835 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1836 return CA_STATUS_OK;
1838 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1840 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1842 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1843 return CA_STATUS_OK;
1846 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1848 VERIFY_NON_NULL(env, TAG, "env is null");
1849 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1851 if (!CALEIsEnableBTAdapter(env))
1853 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1854 return CA_ADAPTER_NOT_ENABLED;
1857 // get BluetoothGatt class
1858 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1859 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1860 if (!jni_cid_BluetoothGatt)
1862 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1863 return CA_STATUS_FAILED;
1866 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1867 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1868 "discoverServices", "()Z");
1869 if (!jni_mid_discoverServices)
1871 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1872 return CA_STATUS_FAILED;
1874 // call disconnect gatt method
1875 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1876 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1879 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1880 return CA_STATUS_FAILED;
1883 return CA_STATUS_OK;
1886 static void CALEWriteCharacteristicThread(void* object)
1888 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1890 bool isAttached = false;
1892 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1895 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1896 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1900 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1906 jobject gatt = (jobject)object;
1907 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1908 if (CA_STATUS_OK != ret)
1910 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1915 (*g_jvm)->DetachCurrentThread(g_jvm);
1919 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1921 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1922 VERIFY_NON_NULL(env, TAG, "env is null");
1925 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1926 if (!jni_obj_character)
1928 CALEClientSendFinish(env, gatt);
1929 return CA_STATUS_FAILED;
1932 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1933 if (CA_STATUS_OK != ret)
1935 CALEClientSendFinish(env, gatt);
1936 return CA_STATUS_FAILED;
1939 // wait for callback for write Characteristic with success to sent data
1940 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1941 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1942 if (!g_isSignalSetFlag)
1944 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1945 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
1946 g_threadWriteCharacteristicMutex,
1947 WAIT_TIME_WRITE_CHARACTERISTIC))
1949 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1950 g_isSignalSetFlag = false;
1951 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1952 return CA_STATUS_FAILED;
1955 // reset flag set by writeCharacteristic Callback
1956 g_isSignalSetFlag = false;
1957 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1959 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
1960 return CA_STATUS_OK;
1963 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1965 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
1966 VERIFY_NON_NULL(env, TAG, "env is null");
1967 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1969 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
1970 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
1971 CALEWriteCharacteristicThread, (void*)gattParam))
1973 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
1974 return CA_STATUS_FAILED;
1977 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
1978 return CA_STATUS_OK;
1981 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1982 jobject gattCharacteristic)
1984 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1985 VERIFY_NON_NULL(env, TAG, "env is null");
1986 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1987 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1989 if (!CALEIsEnableBTAdapter(env))
1991 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1992 return CA_STATUS_FAILED;
1995 // get BluetoothGatt class
1996 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1997 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1998 if (!jni_cid_BluetoothGatt)
2000 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2001 return CA_STATUS_FAILED;
2004 OIC_LOG(DEBUG, TAG, "write characteristic method");
2005 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2006 "writeCharacteristic",
2007 "(Landroid/bluetooth/"
2008 "BluetoothGattCharacteristic;)Z");
2009 if (!jni_mid_writeCharacteristic)
2011 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
2012 return CA_STATUS_FAILED;
2015 // call disconnect gatt method
2016 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
2017 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
2018 jni_mid_writeCharacteristic,
2019 gattCharacteristic);
2022 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
2026 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
2027 return CA_STATUS_FAILED;
2030 return CA_STATUS_OK;
2033 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
2035 VERIFY_NON_NULL(env, TAG, "env is null");
2036 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2038 if (!CALEIsEnableBTAdapter(env))
2040 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2041 return CA_STATUS_FAILED;
2044 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2045 if (!jni_cid_BluetoothGatt)
2047 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2048 return CA_STATUS_FAILED;
2051 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2054 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2055 return CA_STATUS_FAILED;
2058 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2059 if (!jni_obj_GattCharacteristic)
2061 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2062 return CA_STATUS_FAILED;
2065 OIC_LOG(DEBUG, TAG, "read characteristic method");
2066 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2067 "readCharacteristic",
2068 "(Landroid/bluetooth/"
2069 "BluetoothGattCharacteristic;)Z");
2070 if (!jni_mid_readCharacteristic)
2072 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2073 return CA_STATUS_FAILED;
2076 // call disconnect gatt method
2077 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2078 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2079 jni_obj_GattCharacteristic);
2082 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2086 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2087 return CA_STATUS_FAILED;
2090 return CA_STATUS_OK;
2093 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2094 jobject characteristic)
2096 VERIFY_NON_NULL(env, TAG, "env is null");
2097 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2098 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2100 if (!CALEIsEnableBTAdapter(env))
2102 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2103 return CA_ADAPTER_NOT_ENABLED;
2106 // get BluetoothGatt class
2107 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2108 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2109 if (!jni_cid_BluetoothGatt)
2111 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2112 return CA_STATUS_FAILED;
2115 // set Characteristic Notification
2116 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2117 "setCharacteristicNotification",
2118 "(Landroid/bluetooth/"
2119 "BluetoothGattCharacteristic;Z)Z");
2120 if (!jni_mid_setNotification)
2122 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2123 return CA_STATUS_FAILED;
2126 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2127 characteristic, JNI_TRUE);
2128 if (JNI_TRUE == ret)
2130 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2134 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2135 return CA_STATUS_FAILED;
2138 return CA_STATUS_OK;
2141 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2143 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2144 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2145 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2147 if (!CALEIsEnableBTAdapter(env))
2149 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2153 // get BluetoothGatt class
2154 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2155 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2156 if (!jni_cid_BluetoothGatt)
2158 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2162 jmethodID jni_mid_getService = (*env)->GetMethodID(
2163 env, jni_cid_BluetoothGatt, "getService",
2164 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2165 if (!jni_mid_getService)
2167 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2171 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2172 if (!jni_obj_service_uuid)
2174 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2178 // get bluetooth gatt service
2179 OIC_LOG(DEBUG, TAG, "request to get service");
2180 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2181 jni_obj_service_uuid);
2182 if (!jni_obj_gattService)
2184 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2188 // get bluetooth gatt service class
2189 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2190 env, "android/bluetooth/BluetoothGattService");
2191 if (!jni_cid_BluetoothGattService)
2193 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2197 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2198 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2199 "getCharacteristic",
2200 "(Ljava/util/UUID;)"
2201 "Landroid/bluetooth/"
2202 "BluetoothGattCharacteristic;");
2203 if (!jni_mid_getCharacteristic)
2205 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2209 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2212 OIC_LOG(ERROR, TAG, "uuid is null");
2216 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2217 if (!jni_obj_tx_uuid)
2219 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2220 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2224 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2225 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2226 jni_mid_getCharacteristic,
2229 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2230 return jni_obj_GattCharacteristic;
2233 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2235 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2236 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2237 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2238 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2240 if (!CALEIsEnableBTAdapter(env))
2242 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2246 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2249 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2253 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2254 if (!jni_obj_GattCharacteristic)
2256 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2260 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2261 "/BluetoothGattCharacteristic");
2262 if (!jni_cid_BTGattCharacteristic)
2264 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2268 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2269 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2271 if (!jni_mid_setValue)
2273 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2277 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2279 if (JNI_TRUE == ret)
2281 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2285 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2290 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2291 "setWriteType", "(I)V");
2292 if (!jni_mid_setWriteType)
2294 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2298 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2299 "WRITE_TYPE_NO_RESPONSE", "I");
2300 if (!jni_fid_no_response)
2302 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2306 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2307 jni_fid_no_response);
2309 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2311 return jni_obj_GattCharacteristic;
2314 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2316 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2317 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2319 if (!CALEIsEnableBTAdapter(env))
2321 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2325 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2326 "BluetoothGattCharacteristic");
2327 if (!jni_cid_BTGattCharacteristic)
2329 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2333 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2334 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2336 if (!jni_mid_getValue)
2338 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2342 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2344 return jni_obj_data_array;
2347 CAResult_t CALEClientCreateUUIDList()
2351 OIC_LOG(ERROR, TAG, "g_jvm is null");
2352 return CA_STATUS_FAILED;
2355 bool isAttached = false;
2357 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2360 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2361 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2365 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2366 return CA_STATUS_FAILED;
2371 // create new object array
2372 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2373 if (!jni_cid_uuid_list)
2375 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2379 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2380 jni_cid_uuid_list, NULL);
2381 if (!jni_obj_uuid_list)
2383 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2388 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2391 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2394 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2396 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2400 (*g_jvm)->DetachCurrentThread(g_jvm);
2403 return CA_STATUS_OK;
2410 (*g_jvm)->DetachCurrentThread(g_jvm);
2412 return CA_STATUS_FAILED;
2415 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2416 jobject characteristic)
2418 VERIFY_NON_NULL(env, TAG, "env is null");
2419 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2420 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2422 if (!CALEIsEnableBTAdapter(env))
2424 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2425 return CA_ADAPTER_NOT_ENABLED;
2428 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2429 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2430 "BluetoothGattCharacteristic");
2431 if (!jni_cid_BTGattCharacteristic)
2433 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2434 return CA_STATUS_FAILED;
2437 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2438 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2440 "(Ljava/util/UUID;)Landroid/bluetooth/"
2441 "BluetoothGattDescriptor;");
2442 if (!jni_mid_getDescriptor)
2444 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2445 return CA_STATUS_FAILED;
2448 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2449 if (!jni_obj_cc_uuid)
2451 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2452 return CA_STATUS_FAILED;
2455 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2456 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2457 jni_mid_getDescriptor, jni_obj_cc_uuid);
2458 if (!jni_obj_descriptor)
2460 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2461 return CA_NOT_SUPPORTED;
2464 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2465 jclass jni_cid_descriptor = (*env)->FindClass(env,
2466 "android/bluetooth/BluetoothGattDescriptor");
2467 if (!jni_cid_descriptor)
2469 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2470 return CA_STATUS_FAILED;
2473 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2474 if (!jni_mid_setValue)
2476 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2477 return CA_STATUS_FAILED;
2480 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2481 "ENABLE_NOTIFICATION_VALUE", "[B");
2482 if (!jni_fid_NotiValue)
2484 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2485 return CA_STATUS_FAILED;
2488 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2490 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2491 env, jni_obj_descriptor, jni_mid_setValue,
2492 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2495 OIC_LOG(DEBUG, TAG, "setValue success");
2499 OIC_LOG(ERROR, TAG, "setValue has failed");
2500 return CA_STATUS_FAILED;
2503 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2506 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2507 return CA_STATUS_FAILED;
2510 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2511 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2512 "(Landroid/bluetooth/"
2513 "BluetoothGattDescriptor;)Z");
2514 if (!jni_mid_writeDescriptor)
2516 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2517 return CA_STATUS_FAILED;
2520 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2521 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2522 jni_obj_descriptor);
2525 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2529 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2530 return CA_STATUS_FAILED;
2533 return CA_STATUS_OK;
2536 void CALEClientCreateScanDeviceList(JNIEnv *env)
2538 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2539 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2541 ca_mutex_lock(g_deviceListMutex);
2542 // create new object array
2543 if (g_deviceList == NULL)
2545 OIC_LOG(DEBUG, TAG, "Create device list");
2547 g_deviceList = u_arraylist_create();
2549 ca_mutex_unlock(g_deviceListMutex);
2552 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2554 VERIFY_NON_NULL(device, TAG, "device is null");
2555 VERIFY_NON_NULL(env, TAG, "env is null");
2557 ca_mutex_lock(g_deviceListMutex);
2561 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2562 ca_mutex_unlock(g_deviceListMutex);
2563 return CA_STATUS_FAILED;
2566 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2567 if (!jni_remoteAddress)
2569 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2570 ca_mutex_unlock(g_deviceListMutex);
2571 return CA_STATUS_FAILED;
2574 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2577 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2578 ca_mutex_unlock(g_deviceListMutex);
2579 return CA_STATUS_FAILED;
2582 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2584 jobject gdevice = (*env)->NewGlobalRef(env, device);
2585 u_arraylist_add(g_deviceList, gdevice);
2586 ca_cond_signal(g_deviceDescCond);
2587 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2589 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2591 ca_mutex_unlock(g_deviceListMutex);
2593 return CA_STATUS_OK;
2596 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2598 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2599 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2603 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2607 uint32_t length = u_arraylist_length(g_deviceList);
2608 for (uint32_t index = 0; index < length; index++)
2610 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2613 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2617 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2618 if (!jni_setAddress)
2620 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2624 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2627 OIC_LOG(ERROR, TAG, "setAddress is null");
2631 if (!strcmp(remoteAddress, setAddress))
2633 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2637 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2640 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2645 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2647 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2648 VERIFY_NON_NULL(env, TAG, "env is null");
2650 ca_mutex_lock(g_deviceListMutex);
2654 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2655 ca_mutex_unlock(g_deviceListMutex);
2656 return CA_STATUS_FAILED;
2659 uint32_t length = u_arraylist_length(g_deviceList);
2660 for (uint32_t index = 0; index < length; index++)
2662 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2665 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2668 (*env)->DeleteGlobalRef(env, jarrayObj);
2671 OICFree(g_deviceList);
2672 g_deviceList = NULL;
2674 ca_mutex_unlock(g_deviceListMutex);
2675 return CA_STATUS_OK;
2678 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2680 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2681 VERIFY_NON_NULL(address, TAG, "address is null");
2682 VERIFY_NON_NULL(env, TAG, "env is null");
2684 ca_mutex_lock(g_deviceListMutex);
2688 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2689 ca_mutex_unlock(g_deviceListMutex);
2690 return CA_STATUS_FAILED;
2693 uint32_t length = u_arraylist_length(g_deviceList);
2694 for (uint32_t index = 0; index < length; index++)
2696 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2699 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2700 ca_mutex_unlock(g_deviceListMutex);
2701 return CA_STATUS_FAILED;
2704 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2705 if (!jni_setAddress)
2707 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2708 ca_mutex_unlock(g_deviceListMutex);
2709 return CA_STATUS_FAILED;
2712 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2715 OIC_LOG(ERROR, TAG, "setAddress is null");
2716 ca_mutex_unlock(g_deviceListMutex);
2717 return CA_STATUS_FAILED;
2720 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2723 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2724 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2725 ca_mutex_unlock(g_deviceListMutex);
2726 return CA_STATUS_FAILED;
2729 if (!strcmp(setAddress, remoteAddress))
2731 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2732 (*env)->DeleteGlobalRef(env, jarrayObj);
2733 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2734 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2736 if (NULL == u_arraylist_remove(g_deviceList, index))
2738 OIC_LOG(ERROR, TAG, "List removal failed.");
2739 ca_mutex_unlock(g_deviceListMutex);
2740 return CA_STATUS_FAILED;
2742 ca_mutex_unlock(g_deviceListMutex);
2743 return CA_STATUS_OK;
2745 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2746 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2749 ca_mutex_unlock(g_deviceListMutex);
2750 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2752 return CA_STATUS_OK;
2759 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2761 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2762 VERIFY_NON_NULL(env, TAG, "env is null");
2763 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2765 ca_mutex_lock(g_gattObjectMutex);
2767 if (!g_gattObjectList)
2769 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2770 ca_mutex_unlock(g_gattObjectMutex);
2771 return CA_STATUS_FAILED;
2774 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2775 if (!jni_remoteAddress)
2777 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2778 ca_mutex_unlock(g_gattObjectMutex);
2779 return CA_STATUS_FAILED;
2782 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2785 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2786 ca_mutex_unlock(g_gattObjectMutex);
2787 return CA_STATUS_FAILED;
2790 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2791 if (!CALEClientIsGattObjInList(env, remoteAddress))
2793 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2794 u_arraylist_add(g_gattObjectList, newGatt);
2795 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2798 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2799 ca_mutex_unlock(g_gattObjectMutex);
2800 return CA_STATUS_OK;
2803 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2805 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2806 VERIFY_NON_NULL(env, TAG, "env is null");
2807 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2809 uint32_t length = u_arraylist_length(g_gattObjectList);
2810 for (uint32_t index = 0; index < length; index++)
2813 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2816 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2820 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2821 if (!jni_setAddress)
2823 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2827 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2830 OIC_LOG(ERROR, TAG, "setAddress is null");
2834 if (!strcmp(remoteAddress, setAddress))
2836 OIC_LOG(DEBUG, TAG, "the device is already set");
2837 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2842 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2847 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2851 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2853 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2854 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2855 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2857 ca_mutex_lock(g_gattObjectMutex);
2858 uint32_t length = u_arraylist_length(g_gattObjectList);
2859 for (uint32_t index = 0; index < length; index++)
2861 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2864 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2865 ca_mutex_unlock(g_gattObjectMutex);
2869 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2870 if (!jni_setAddress)
2872 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2873 ca_mutex_unlock(g_gattObjectMutex);
2877 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2880 OIC_LOG(ERROR, TAG, "setAddress is null");
2881 ca_mutex_unlock(g_gattObjectMutex);
2885 if (!strcmp(remoteAddress, setAddress))
2887 OIC_LOG(DEBUG, TAG, "the device is already set");
2888 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2889 ca_mutex_unlock(g_gattObjectMutex);
2892 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2895 ca_mutex_unlock(g_gattObjectMutex);
2896 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2900 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2902 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2903 VERIFY_NON_NULL(env, TAG, "env is null");
2905 ca_mutex_lock(g_gattObjectMutex);
2906 if (!g_gattObjectList)
2908 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2909 ca_mutex_unlock(g_gattObjectMutex);
2910 return CA_STATUS_OK;
2913 uint32_t length = u_arraylist_length(g_gattObjectList);
2914 for (uint32_t index = 0; index < length; index++)
2916 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2919 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2922 (*env)->DeleteGlobalRef(env, jarrayObj);
2925 OICFree(g_gattObjectList);
2926 g_gattObjectList = NULL;
2927 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2928 ca_mutex_unlock(g_gattObjectMutex);
2929 return CA_STATUS_OK;
2932 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2934 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2935 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2936 VERIFY_NON_NULL(env, TAG, "env is null");
2938 ca_mutex_lock(g_gattObjectMutex);
2939 if (!g_gattObjectList)
2941 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2942 ca_mutex_unlock(g_gattObjectMutex);
2943 return CA_STATUS_OK;
2946 uint32_t length = u_arraylist_length(g_gattObjectList);
2947 for (uint32_t index = 0; index < length; index++)
2949 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2952 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2953 ca_mutex_unlock(g_gattObjectMutex);
2954 return CA_STATUS_FAILED;
2957 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2958 if (!jni_setAddress)
2960 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2961 ca_mutex_unlock(g_gattObjectMutex);
2962 return CA_STATUS_FAILED;
2965 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2968 OIC_LOG(ERROR, TAG, "setAddress is null");
2969 ca_mutex_unlock(g_gattObjectMutex);
2970 return CA_STATUS_FAILED;
2973 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2974 if (!jni_remoteAddress)
2976 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2977 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2978 ca_mutex_unlock(g_gattObjectMutex);
2979 return CA_STATUS_FAILED;
2982 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2985 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2986 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2987 ca_mutex_unlock(g_gattObjectMutex);
2988 return CA_STATUS_FAILED;
2991 if (!strcmp(setAddress, remoteAddress))
2993 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2994 (*env)->DeleteGlobalRef(env, jarrayObj);
2995 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2996 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2998 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3000 OIC_LOG(ERROR, TAG, "List removal failed.");
3001 ca_mutex_unlock(g_gattObjectMutex);
3002 return CA_STATUS_FAILED;
3004 ca_mutex_unlock(g_gattObjectMutex);
3005 return CA_STATUS_OK;
3007 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3008 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
3011 ca_mutex_unlock(g_gattObjectMutex);
3012 OIC_LOG(DEBUG, TAG, "there are no target object");
3013 return CA_STATUS_OK;
3016 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
3018 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
3019 VERIFY_NON_NULL(addr, TAG, "addr is null");
3020 VERIFY_NON_NULL(env, TAG, "env is null");
3022 ca_mutex_lock(g_gattObjectMutex);
3023 if (!g_gattObjectList)
3025 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
3026 ca_mutex_unlock(g_gattObjectMutex);
3027 return CA_STATUS_OK;
3030 uint32_t length = u_arraylist_length(g_gattObjectList);
3031 for (uint32_t index = 0; index < length; index++)
3033 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3036 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3037 ca_mutex_unlock(g_gattObjectMutex);
3038 return CA_STATUS_FAILED;
3041 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3042 if (!jni_setAddress)
3044 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3045 ca_mutex_unlock(g_gattObjectMutex);
3046 return CA_STATUS_FAILED;
3049 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3052 OIC_LOG(ERROR, TAG, "setAddress is null");
3053 ca_mutex_unlock(g_gattObjectMutex);
3054 return CA_STATUS_FAILED;
3057 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3060 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3061 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3062 ca_mutex_unlock(g_gattObjectMutex);
3063 return CA_STATUS_FAILED;
3066 if (!strcmp(setAddress, remoteAddress))
3068 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3069 (*env)->DeleteGlobalRef(env, jarrayObj);
3071 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3072 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3073 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3075 OIC_LOG(ERROR, TAG, "List removal failed.");
3076 ca_mutex_unlock(g_gattObjectMutex);
3077 return CA_STATUS_FAILED;
3079 ca_mutex_unlock(g_gattObjectMutex);
3080 return CA_STATUS_OK;
3082 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3083 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3086 ca_mutex_unlock(g_gattObjectMutex);
3087 OIC_LOG(DEBUG, TAG, "there are no target object");
3088 return CA_STATUS_FAILED;
3091 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3093 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3095 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3096 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3098 // get Bluetooth Address
3099 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3100 if (!jni_btTargetAddress)
3102 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3106 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3109 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3113 // get method ID of getDevice()
3114 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3115 if (!jni_cid_gattdevice_list)
3117 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3118 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3122 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3123 METHODID_BT_DEVICE);
3124 if (!jni_mid_getDevice)
3126 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3127 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3131 size_t length = u_arraylist_length(g_gattObjectList);
3132 for (size_t index = 0; index < length; index++)
3134 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3137 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3138 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3142 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3143 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3144 if (!jni_obj_device)
3146 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3147 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3151 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3154 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3155 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3159 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3162 OIC_LOG(ERROR, TAG, "btAddress is not available");
3163 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3167 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3168 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3169 if (!strcmp(targetAddress, btAddress))
3171 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3174 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3177 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3179 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3180 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3181 (*env)->DeleteLocalRef(env, jni_btAddress);
3182 (*env)->DeleteLocalRef(env, jni_obj_device);
3183 return jni_LEAddress;
3185 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3186 (*env)->DeleteLocalRef(env, jni_btAddress);
3187 (*env)->DeleteLocalRef(env, jni_obj_device);
3190 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3198 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3199 uint16_t notificationState, uint16_t sendState)
3201 VERIFY_NON_NULL(address, TAG, "address is null");
3203 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3206 OIC_LOG(ERROR, TAG, "out of memory");
3207 return CA_MEMORY_ALLOC_FAILED;
3210 if (strlen(address) > CA_MACADDR_SIZE)
3212 OIC_LOG(ERROR, TAG, "address is not proper");
3214 return CA_STATUS_FAILED;
3217 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3218 newstate->connectedState = connectedState;
3219 newstate->notificationState = notificationState;
3220 newstate->sendState = sendState;
3221 return CALEClientAddDeviceStateToList(newstate);
3224 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3226 VERIFY_NON_NULL(state, TAG, "state is null");
3228 ca_mutex_lock(g_deviceStateListMutex);
3230 if (!g_deviceStateList)
3232 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3233 ca_mutex_unlock(g_deviceStateListMutex);
3234 return CA_STATUS_FAILED;
3237 if (CALEClientIsDeviceInList(state->address))
3239 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3242 OIC_LOG(ERROR, TAG, "curState is null");
3243 ca_mutex_unlock(g_deviceStateListMutex);
3244 return CA_STATUS_FAILED;
3247 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3249 state->notificationState = curState->notificationState;
3252 // delete previous state for update new state
3253 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3254 if (CA_STATUS_OK != res)
3256 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3257 ca_mutex_unlock(g_deviceStateListMutex);
3261 u_arraylist_add(g_deviceStateList, state); // update new state
3262 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3263 state->connectedState, state->notificationState, state->address);
3265 ca_mutex_unlock(g_deviceStateListMutex);
3266 return CA_STATUS_OK;
3269 bool CALEClientIsDeviceInList(const char* remoteAddress)
3271 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3273 if (!g_deviceStateList)
3275 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3279 uint32_t length = u_arraylist_length(g_deviceStateList);
3280 for (uint32_t index = 0; index < length; index++)
3282 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3285 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3289 if (!strcmp(remoteAddress, state->address))
3291 OIC_LOG(DEBUG, TAG, "the device is already set");
3300 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3304 CAResult_t CALEClientRemoveAllDeviceState()
3306 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3308 ca_mutex_lock(g_deviceStateListMutex);
3309 if (!g_deviceStateList)
3311 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3312 ca_mutex_unlock(g_deviceStateListMutex);
3313 return CA_STATUS_FAILED;
3316 uint32_t length = u_arraylist_length(g_deviceStateList);
3317 for (uint32_t index = 0; index < length; index++)
3319 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3322 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3328 OICFree(g_deviceStateList);
3329 g_deviceStateList = NULL;
3330 ca_mutex_unlock(g_deviceStateListMutex);
3332 return CA_STATUS_OK;
3335 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3337 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3338 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3340 if (!g_deviceStateList)
3342 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3343 return CA_STATUS_FAILED;
3346 uint32_t length = u_arraylist_length(g_deviceStateList);
3347 for (uint32_t index = 0; index < length; index++)
3349 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3352 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3356 if (!strcmp(state->address, remoteAddress))
3358 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3360 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3362 if (NULL == targetState)
3364 OIC_LOG(ERROR, TAG, "List removal failed.");
3365 return CA_STATUS_FAILED;
3368 OICFree(targetState);
3369 return CA_STATUS_OK;
3373 return CA_STATUS_OK;
3376 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3378 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3379 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3381 if (!g_deviceStateList)
3383 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3387 uint32_t length = u_arraylist_length(g_deviceStateList);
3388 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3390 for (uint32_t index = 0; index < length; index++)
3392 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3395 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3399 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3400 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3402 if (!strcmp(state->address, remoteAddress))
3404 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3411 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3413 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3414 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3416 ca_mutex_lock(g_deviceStateListMutex);
3417 if (!g_deviceStateList)
3419 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3420 ca_mutex_unlock(g_deviceStateListMutex);
3424 uint32_t length = u_arraylist_length(g_deviceStateList);
3425 for (uint32_t index = 0; index < length; index++)
3427 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3430 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3434 if (!strcmp(state->address, remoteAddress))
3436 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3438 if (STATE_CONNECTED == state->connectedState)
3440 ca_mutex_unlock(g_deviceStateListMutex);
3445 ca_mutex_unlock(g_deviceStateListMutex);
3450 ca_mutex_unlock(g_deviceStateListMutex);
3454 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3456 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3457 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3459 ca_mutex_lock(g_deviceStateListMutex);
3460 if (!g_deviceStateList)
3462 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3463 ca_mutex_unlock(g_deviceStateListMutex);
3467 uint32_t length = u_arraylist_length(g_deviceStateList);
3468 for (uint32_t index = 0; index < length; index++)
3470 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3473 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3477 if (!strcmp(state->address, remoteAddress))
3479 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3481 if (STATE_CHARACTER_SET == state->notificationState)
3483 ca_mutex_unlock(g_deviceStateListMutex);
3488 ca_mutex_unlock(g_deviceStateListMutex);
3494 ca_mutex_unlock(g_deviceStateListMutex);
3498 void CALEClientCreateDeviceList()
3500 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3502 // create new object array
3503 if (!g_gattObjectList)
3505 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3507 g_gattObjectList = u_arraylist_create();
3510 if (!g_deviceStateList)
3512 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3514 g_deviceStateList = u_arraylist_create();
3519 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3521 g_deviceList = u_arraylist_create();
3526 * Check Sent Count for remove g_sendBuffer
3528 void CALEClientUpdateSendCnt(JNIEnv *env)
3530 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3532 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3534 ca_mutex_lock(g_threadMutex);
3538 if (g_targetCnt <= g_currentSentCnt)
3541 g_currentSentCnt = 0;
3545 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3546 g_sendBuffer = NULL;
3548 // notity the thread
3549 ca_cond_signal(g_threadCond);
3551 CALEClientSetSendFinishFlag(true);
3552 OIC_LOG(DEBUG, TAG, "set signal for send data");
3555 ca_mutex_unlock(g_threadMutex);
3558 CAResult_t CALEClientInitGattMutexVaraibles()
3560 if (NULL == g_bleReqRespClientCbMutex)
3562 g_bleReqRespClientCbMutex = ca_mutex_new();
3563 if (NULL == g_bleReqRespClientCbMutex)
3565 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3566 return CA_STATUS_FAILED;
3570 if (NULL == g_bleServerBDAddressMutex)
3572 g_bleServerBDAddressMutex = ca_mutex_new();
3573 if (NULL == g_bleServerBDAddressMutex)
3575 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3576 return CA_STATUS_FAILED;
3580 if (NULL == g_threadMutex)
3582 g_threadMutex = ca_mutex_new();
3583 if (NULL == g_threadMutex)
3585 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3586 return CA_STATUS_FAILED;
3590 if (NULL == g_threadSendMutex)
3592 g_threadSendMutex = ca_mutex_new();
3593 if (NULL == g_threadSendMutex)
3595 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3596 return CA_STATUS_FAILED;
3600 if (NULL == g_deviceListMutex)
3602 g_deviceListMutex = ca_mutex_new();
3603 if (NULL == g_deviceListMutex)
3605 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3606 return CA_STATUS_FAILED;
3610 if (NULL == g_gattObjectMutex)
3612 g_gattObjectMutex = ca_mutex_new();
3613 if (NULL == g_gattObjectMutex)
3615 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3616 return CA_STATUS_FAILED;
3620 if (NULL == g_deviceStateListMutex)
3622 g_deviceStateListMutex = ca_mutex_new();
3623 if (NULL == g_deviceStateListMutex)
3625 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3626 return CA_STATUS_FAILED;
3630 if (NULL == g_SendFinishMutex)
3632 g_SendFinishMutex = ca_mutex_new();
3633 if (NULL == g_SendFinishMutex)
3635 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3636 return CA_STATUS_FAILED;
3640 if (NULL == g_scanMutex)
3642 g_scanMutex = ca_mutex_new();
3643 if (NULL == g_scanMutex)
3645 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3646 return CA_STATUS_FAILED;
3650 if (NULL == g_threadWriteCharacteristicMutex)
3652 g_threadWriteCharacteristicMutex = ca_mutex_new();
3653 if (NULL == g_threadWriteCharacteristicMutex)
3655 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3656 return CA_STATUS_FAILED;
3660 return CA_STATUS_OK;
3663 void CALEClientTerminateGattMutexVariables()
3665 ca_mutex_free(g_bleReqRespClientCbMutex);
3666 g_bleReqRespClientCbMutex = NULL;
3668 ca_mutex_free(g_bleServerBDAddressMutex);
3669 g_bleServerBDAddressMutex = NULL;
3671 ca_mutex_free(g_threadMutex);
3672 g_threadMutex = NULL;
3674 ca_mutex_free(g_threadSendMutex);
3675 g_threadSendMutex = NULL;
3677 ca_mutex_free(g_deviceListMutex);
3678 g_deviceListMutex = NULL;
3680 ca_mutex_free(g_SendFinishMutex);
3681 g_SendFinishMutex = NULL;
3683 ca_mutex_free(g_scanMutex);
3686 ca_mutex_free(g_threadWriteCharacteristicMutex);
3687 g_threadWriteCharacteristicMutex = NULL;
3690 void CALEClientSetSendFinishFlag(bool flag)
3692 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3694 ca_mutex_lock(g_SendFinishMutex);
3695 g_isFinishedSendData = flag;
3696 ca_mutex_unlock(g_SendFinishMutex);
3703 CAResult_t CAStartLEGattClient()
3705 CAResult_t res = CALEClientStartMulticastServer();
3706 if (CA_STATUS_OK != res)
3708 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3712 g_isStartedLEClient = true;
3718 void CAStopLEGattClient()
3720 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3724 OIC_LOG(ERROR, TAG, "g_jvm is null");
3728 bool isAttached = false;
3730 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3733 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3734 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3738 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3744 CAResult_t ret = CALEClientDisconnectAll(env);
3745 if (CA_STATUS_OK != ret)
3747 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3750 ret = CALEClientStopScan();
3751 if(CA_STATUS_OK != ret)
3753 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3756 ca_mutex_lock(g_threadMutex);
3757 ca_cond_signal(g_threadCond);
3758 ca_mutex_unlock(g_threadMutex);
3760 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3761 ca_cond_signal(g_threadWriteCharacteristicCond);
3762 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3766 (*g_jvm)->DetachCurrentThread(g_jvm);
3771 CAResult_t CAInitializeLEGattClient()
3773 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3774 CALEClientInitialize();
3775 return CA_STATUS_OK;
3778 void CATerminateLEGattClient()
3780 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3781 CAStopLEGattClient();
3782 CALEClientTerminate();
3785 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3786 uint32_t dataLen, CALETransferType_t type,
3789 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3790 VERIFY_NON_NULL(data, TAG, "data is null");
3791 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3793 if (LE_UNICAST != type || position < 0)
3795 OIC_LOG(ERROR, TAG, "this request is not unicast");
3796 return CA_STATUS_INVALID_PARAM;
3799 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3802 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3804 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3805 VERIFY_NON_NULL(data, TAG, "data is null");
3807 return CALEClientSendMulticastMessage(data, dataLen);
3810 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3812 ca_mutex_lock(g_bleReqRespClientCbMutex);
3813 g_CABLEClientDataReceivedCallback = callback;
3814 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3817 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3819 g_threadPoolHandle = handle;
3822 CAResult_t CAGetLEAddress(char **local_address)
3824 VERIFY_NON_NULL(local_address, TAG, "local_address");
3825 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3826 return CA_NOT_SUPPORTED;
3829 JNIEXPORT void JNICALL
3830 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3833 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3834 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3835 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3836 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3838 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3841 JNIEXPORT void JNICALL
3842 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3845 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3846 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3847 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3848 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3850 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3853 JNIEXPORT void JNICALL
3854 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3857 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3858 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3859 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3861 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3862 if (CA_STATUS_OK != res)
3864 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3869 * Class: org_iotivity_ca_jar_caleinterface
3870 * Method: CALeGattConnectionStateChangeCallback
3871 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3873 JNIEXPORT void JNICALL
3874 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3880 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3882 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3883 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3884 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3886 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
3887 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
3888 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
3890 if (gatt_success == status && state_connected == newstate) // le connected
3892 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3898 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3901 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3902 STATE_CHARACTER_NO_CHANGE,
3904 if (CA_STATUS_OK != res)
3906 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3907 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3910 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
3912 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3915 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3916 if (CA_STATUS_OK != res)
3918 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3922 res = CALEClientDiscoverServices(env, gatt);
3923 if (CA_STATUS_OK != res)
3925 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3929 else if (GATT_ERROR == status && state_disconnected == newstate)
3931 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
3933 else // le disconnected
3935 CAResult_t res = CALEClientStartScan();
3936 if (CA_STATUS_OK != res)
3938 if (CA_ADAPTER_NOT_ENABLED == res)
3940 // scan will be started with start server when adapter is enabled
3941 OIC_LOG(INFO, TAG, "Adapter was disabled");
3945 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3950 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3953 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3957 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3960 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3961 STATE_CHARACTER_UNSET,
3963 if (CA_STATUS_OK != res)
3965 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3966 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3969 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
3971 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3974 res = CALEClientGattClose(env, gatt);
3975 if (CA_STATUS_OK != res)
3977 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3982 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3983 g_sendBuffer = NULL;
3991 CALEClientSendFinish(env, gatt);
3996 * Class: org_iotivity_ca_jar_caleinterface
3997 * Method: CALeGattServicesDiscoveredCallback
3998 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
4000 JNIEXPORT void JNICALL
4001 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
4006 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
4007 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4008 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4009 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4011 if (0 != status) // discovery error
4013 CALEClientSendFinish(env, gatt);
4017 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4020 CALEClientSendFinish(env, gatt);
4024 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4027 CALEClientSendFinish(env, gatt);
4031 if (!CALEClientIsSetCharacteristic(address))
4033 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
4036 OIC_LOG(ERROR, TAG, "jni_uuid is null");
4040 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
4041 if (!jni_obj_GattCharacteristic)
4043 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4047 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4048 jni_obj_GattCharacteristic);
4049 if (CA_STATUS_OK != res)
4051 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4055 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4056 if (CA_STATUS_OK != res)
4058 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4061 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4062 if (CA_STATUS_OK != res)
4064 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4070 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4072 if (CA_STATUS_OK != res)
4074 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4080 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4081 if (CA_STATUS_OK != res)
4083 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4087 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4088 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4093 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4094 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4095 CALEClientSendFinish(env, gatt);
4100 * Class: org_iotivity_ca_jar_caleinterface
4101 * Method: CALeGattCharacteristicWritjclasseCallback
4102 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4104 JNIEXPORT void JNICALL
4105 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4106 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4109 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4110 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4111 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4112 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4115 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
4117 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
4119 // send success & signal
4120 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4126 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4132 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4133 if (gatt_success != status) // error case
4135 OIC_LOG(ERROR, TAG, "send failure");
4138 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4139 if (CA_STATUS_OK != res)
4141 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4142 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4143 g_isSignalSetFlag = true;
4144 ca_cond_signal(g_threadWriteCharacteristicCond);
4145 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4147 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4148 STATE_CHARACTER_SET,
4150 if (CA_STATUS_OK != res)
4152 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4155 if (g_clientErrorCallback)
4157 jint length = (*env)->GetArrayLength(env, data);
4158 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4161 CALEClientSendFinish(env, gatt);
4167 OIC_LOG(DEBUG, TAG, "send success");
4168 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4169 STATE_SEND_SUCCESS);
4170 if (CA_STATUS_OK != res)
4172 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4175 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4176 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4177 g_isSignalSetFlag = true;
4178 ca_cond_signal(g_threadWriteCharacteristicCond);
4179 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4181 CALEClientUpdateSendCnt(env);
4184 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4190 CALEClientSendFinish(env, gatt);
4195 * Class: org_iotivity_ca_jar_caleinterface
4196 * Method: CALeGattCharacteristicChangedCallback
4197 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4199 JNIEXPORT void JNICALL
4200 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4201 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4203 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4204 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4205 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4206 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4207 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4209 // get Byte Array and convert to uint8_t*
4210 jint length = (*env)->GetArrayLength(env, data);
4213 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4215 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4216 jni_byte_responseData);
4218 uint8_t* receivedData = OICMalloc(length);
4221 OIC_LOG(ERROR, TAG, "receivedData is null");
4225 memcpy(receivedData, jni_byte_responseData, length);
4226 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4228 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4231 OIC_LOG(ERROR, TAG, "jni_address is null");
4232 OICFree(receivedData);
4236 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4239 OIC_LOG(ERROR, TAG, "address is null");
4240 OICFree(receivedData);
4244 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4245 receivedData, length);
4247 ca_mutex_lock(g_bleServerBDAddressMutex);
4248 uint32_t sentLength = 0;
4249 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4251 ca_mutex_unlock(g_bleServerBDAddressMutex);
4253 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4257 * Class: org_iotivity_ca_jar_caleinterface
4258 * Method: CALeGattDescriptorWriteCallback
4259 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4261 JNIEXPORT void JNICALL
4262 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4266 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4267 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4268 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4269 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4271 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4272 if (gatt_success != status) // error
4279 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4280 if (CA_STATUS_OK != res)
4282 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4291 CALEClientSendFinish(env, gatt);