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;
90 void CALEClientJniInit()
92 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
93 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
96 void CALEClientJNISetContext()
98 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
99 g_context = (jobject) CANativeJNIGetContext();
102 CAResult_t CALECreateJniInterfaceObject()
104 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
108 OIC_LOG(ERROR, TAG, "g_context is null");
109 return CA_STATUS_FAILED;
114 OIC_LOG(ERROR, TAG, "g_jvm is null");
115 return CA_STATUS_FAILED;
118 bool isAttached = false;
120 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
123 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
124 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
128 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
129 return CA_STATUS_FAILED;
134 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
135 if (!jni_LEInterface)
137 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
141 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
142 "(Landroid/content/Context;)V");
143 if (!LeInterfaceConstructorMethod)
145 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
149 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
150 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
154 (*g_jvm)->DetachCurrentThread(g_jvm);
163 (*g_jvm)->DetachCurrentThread(g_jvm);
166 return CA_STATUS_FAILED;
169 CAResult_t CALEClientInitialize()
171 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
177 OIC_LOG(ERROR, TAG, "g_jvm is null");
178 return CA_STATUS_FAILED;
181 bool isAttached = false;
183 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
186 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
187 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
191 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
192 return CA_STATUS_FAILED;
197 CAResult_t ret = CALECheckPlatformVersion(env, 18);
198 if (CA_STATUS_OK != ret)
200 OIC_LOG(ERROR, TAG, "it is not supported");
204 (*g_jvm)->DetachCurrentThread(g_jvm);
210 ret = CALEClientInitGattMutexVaraibles();
211 if (CA_STATUS_OK != ret)
213 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
214 CALEClientTerminateGattMutexVariables();
218 (*g_jvm)->DetachCurrentThread(g_jvm);
224 g_deviceDescCond = ca_cond_new();
226 // init mutex for send logic
227 g_threadCond = ca_cond_new();
228 g_threadWriteCharacteristicCond = ca_cond_new();
230 CALEClientCreateDeviceList();
231 CALEClientJNISetContext();
233 ret = CALEClientCreateUUIDList();
234 if (CA_STATUS_OK != ret)
236 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
240 (*g_jvm)->DetachCurrentThread(g_jvm);
246 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
247 if (CA_STATUS_OK != ret)
249 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
253 (*g_jvm)->DetachCurrentThread(g_jvm);
258 g_isStartedLEClient = true;
262 (*g_jvm)->DetachCurrentThread(g_jvm);
268 void CALEClientTerminate()
270 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
274 OIC_LOG(ERROR, TAG, "g_jvm is null");
278 bool isAttached = false;
280 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
283 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
284 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
288 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
294 if (g_leScanCallback)
296 (*env)->DeleteGlobalRef(env, g_leScanCallback);
299 if (g_leGattCallback)
301 (*env)->DeleteGlobalRef(env, g_leGattCallback);
306 (*env)->DeleteGlobalRef(env, g_sendBuffer);
311 (*env)->DeleteGlobalRef(env, g_uuidList);
314 CAResult_t ret = CALEClientRemoveAllDeviceState();
315 if (CA_STATUS_OK != ret)
317 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
320 ret = CALEClientRemoveAllScanDevices(env);
321 if (CA_STATUS_OK != ret)
323 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
326 ret = CALEClientRemoveAllGattObjs(env);
327 if (CA_STATUS_OK != ret)
329 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
332 g_isStartedMulticastServer = false;
333 CALEClientSetScanFlag(false);
334 CALEClientSetSendFinishFlag(false);
336 CALEClientTerminateGattMutexVariables();
337 CALEClientDestroyJniInterface();
339 ca_cond_free(g_deviceDescCond);
340 ca_cond_free(g_threadCond);
341 ca_cond_free(g_threadWriteCharacteristicCond);
343 g_deviceDescCond = NULL;
345 g_threadWriteCharacteristicCond = NULL;
346 g_isSignalSetFlag = false;
350 (*g_jvm)->DetachCurrentThread(g_jvm);
354 CAResult_t CALEClientDestroyJniInterface()
356 OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
360 OIC_LOG(ERROR, TAG, "g_jvm is null");
361 return CA_STATUS_FAILED;
364 bool isAttached = false;
366 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
369 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
370 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
374 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
375 return CA_STATUS_FAILED;
380 jclass jni_LeInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
381 if (!jni_LeInterface)
383 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
387 jmethodID jni_InterfaceDestroyMethod = (*env)->GetStaticMethodID(env, jni_LeInterface,
388 "destroyLeInterface",
390 if (!jni_InterfaceDestroyMethod)
392 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface destroy method");
396 (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
398 if ((*env)->ExceptionCheck(env))
400 OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
401 (*env)->ExceptionDescribe(env);
402 (*env)->ExceptionClear(env);
406 OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
410 (*g_jvm)->DetachCurrentThread(g_jvm);
419 (*g_jvm)->DetachCurrentThread(g_jvm);
422 return CA_STATUS_FAILED;
425 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
427 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
428 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
432 CAResult_t res = CALEClientDisconnect(env, gatt);
433 if (CA_STATUS_OK != res)
435 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
438 CALEClientUpdateSendCnt(env);
441 CAResult_t CALEClientSendUnicastMessage(const char* address,
443 const uint32_t dataLen)
445 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
446 VERIFY_NON_NULL(address, TAG, "address is null");
447 VERIFY_NON_NULL(data, TAG, "data is null");
449 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
452 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
453 const uint32_t dataLen)
455 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
456 VERIFY_NON_NULL(data, TAG, "data is null");
460 OIC_LOG(ERROR, TAG, "g_jvm is null");
461 return CA_STATUS_FAILED;
464 bool isAttached = false;
466 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
469 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
470 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
474 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
475 return CA_STATUS_FAILED;
480 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
481 if (CA_STATUS_OK != ret)
483 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
488 (*g_jvm)->DetachCurrentThread(g_jvm);
494 CAResult_t CALEClientStartUnicastServer(const char* address)
496 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
498 return CA_NOT_SUPPORTED;
501 CAResult_t CALEClientStartMulticastServer()
503 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
505 if (g_isStartedMulticastServer)
507 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
508 return CA_STATUS_FAILED;
513 OIC_LOG(ERROR, TAG, "g_jvm is null");
514 return CA_STATUS_FAILED;
517 bool isAttached = false;
519 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
522 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
523 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
527 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
528 return CA_STATUS_FAILED;
533 g_isStartedMulticastServer = true;
534 CAResult_t ret = CALEClientStartScan();
535 if (CA_STATUS_OK != ret)
537 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
542 (*g_jvm)->DetachCurrentThread(g_jvm);
548 void CALEClientStopUnicastServer()
550 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
553 void CALEClientStopMulticastServer()
555 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
556 g_isStartedMulticastServer = false;
557 CAResult_t res = CALEClientStopScan();
558 if (CA_STATUS_OK != res)
560 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
565 void CALEClientSetCallback(CAPacketReceiveCallback callback)
567 g_packetReceiveCallback = callback;
570 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
572 g_clientErrorCallback = callback;
575 CAResult_t CALEClientIsThereScannedDevices()
579 return CA_STATUS_FAILED;
582 if (0 == u_arraylist_length(g_deviceList))
584 // Wait for LE peripherals to be discovered.
586 // Number of times to wait for discovery to complete.
587 static size_t const RETRIES = 5;
589 static uint64_t const TIMEOUT =
590 2 * MICROSECS_PER_SEC; // Microseconds
592 bool devicesDiscovered = false;
594 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
597 if (ca_cond_wait_for(g_deviceDescCond,
599 TIMEOUT) == CA_WAIT_SUCCESS)
601 devicesDiscovered = true;
606 // time out for scanning devices
607 if (!devicesDiscovered)
609 return CA_STATUS_FAILED;
616 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
617 const uint32_t dataLen)
619 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
621 VERIFY_NON_NULL(address, TAG, "address is null");
622 VERIFY_NON_NULL(data, TAG, "data is null");
626 OIC_LOG(ERROR, TAG, "g_jvm is null");
627 return CA_STATUS_FAILED;
630 bool isAttached = false;
632 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
635 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
636 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
639 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
640 return CA_STATUS_FAILED;
645 ca_mutex_lock(g_threadSendMutex);
647 CALEClientSetSendFinishFlag(false);
649 CAResult_t ret = CALEClientIsThereScannedDevices();
650 if (CA_STATUS_OK != ret)
652 OIC_LOG(INFO, TAG, "there is no scanned device");
656 if (g_context && g_deviceList)
658 uint32_t length = u_arraylist_length(g_deviceList);
659 for (uint32_t index = 0; index < length; index++)
661 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
664 OIC_LOG(ERROR, TAG, "jarrayObj is null");
668 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
671 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
675 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
678 OIC_LOG(ERROR, TAG, "setAddress is null");
682 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
684 if (!strcmp(setAddress, address))
686 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
688 // connect to gatt server
689 ret = CALEClientStopScan();
690 if (CA_STATUS_OK != ret)
692 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
698 (*env)->DeleteGlobalRef(env, g_sendBuffer);
701 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
702 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
703 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
705 // Target device to send message is just one.
708 ret = CALEClientSendData(env, jarrayObj);
709 if (CA_STATUS_OK != ret)
711 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
715 OIC_LOG(INFO, TAG, "wake up");
718 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
722 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
724 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
725 // if there is no connection state.
726 ca_mutex_lock(g_threadMutex);
727 if (!g_isFinishedSendData)
729 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
730 ca_cond_wait(g_threadCond, g_threadMutex);
731 OIC_LOG(DEBUG, TAG, "the data was sent");
733 ca_mutex_unlock(g_threadMutex);
737 (*g_jvm)->DetachCurrentThread(g_jvm);
740 // start LE Scan again
741 ret = CALEClientStartScan();
742 if (CA_STATUS_OK != ret)
744 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
745 ca_mutex_unlock(g_threadSendMutex);
749 ca_mutex_unlock(g_threadSendMutex);
750 OIC_LOG(INFO, TAG, "unicast - send success");
756 // start LE Scan again
757 ret = CALEClientStartScan();
758 if (CA_STATUS_OK != ret)
760 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
761 ca_mutex_unlock(g_threadSendMutex);
764 (*g_jvm)->DetachCurrentThread(g_jvm);
771 (*g_jvm)->DetachCurrentThread(g_jvm);
774 if (g_clientErrorCallback)
776 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
778 ca_mutex_unlock(g_threadSendMutex);
779 return CA_SEND_FAILED;
782 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
783 const uint32_t dataLen)
785 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
786 VERIFY_NON_NULL(data, TAG, "data is null");
787 VERIFY_NON_NULL(env, TAG, "env is null");
791 OIC_LOG(ERROR, TAG, "g_deviceList is null");
792 return CA_STATUS_FAILED;
795 ca_mutex_lock(g_threadSendMutex);
797 CALEClientSetSendFinishFlag(false);
799 OIC_LOG(DEBUG, TAG, "set byteArray for data");
802 (*env)->DeleteGlobalRef(env, g_sendBuffer);
806 CAResult_t res = CALEClientIsThereScannedDevices();
807 if (CA_STATUS_OK != res)
809 OIC_LOG(INFO, TAG, "there is no scanned device");
813 // connect to gatt server
814 res = CALEClientStopScan();
815 if (CA_STATUS_OK != res)
817 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
818 ca_mutex_unlock(g_threadSendMutex);
821 uint32_t length = u_arraylist_length(g_deviceList);
822 g_targetCnt = length;
824 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
825 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
826 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
828 for (uint32_t index = 0; index < length; index++)
830 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
833 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
837 res = CALEClientSendData(env, jarrayObj);
838 if (res != CA_STATUS_OK)
840 OIC_LOG(ERROR, TAG, "BT device - send has failed");
843 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
846 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
850 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
853 OIC_LOG(ERROR, TAG, "address is not available");
857 (*env)->ReleaseStringUTFChars(env, jni_address, address);
860 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
862 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
863 ca_mutex_lock(g_threadMutex);
864 if (!g_isFinishedSendData)
866 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
867 ca_cond_wait(g_threadCond, g_threadMutex);
868 OIC_LOG(DEBUG, TAG, "the data was sent");
870 ca_mutex_unlock(g_threadMutex);
872 // start LE Scan again
873 res = CALEClientStartScan();
874 if (CA_STATUS_OK != res)
876 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
877 ca_mutex_unlock(g_threadSendMutex);
881 ca_mutex_unlock(g_threadSendMutex);
882 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
886 res = CALEClientStartScan();
887 if (CA_STATUS_OK != res)
889 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
890 ca_mutex_unlock(g_threadSendMutex);
894 ca_mutex_unlock(g_threadSendMutex);
895 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
896 return CA_SEND_FAILED;
899 CAResult_t CALECheckSendState(const char* address)
901 VERIFY_NON_NULL(address, TAG, "address is null");
903 ca_mutex_lock(g_deviceStateListMutex);
904 CALEState_t* state = CALEClientGetStateInfo(address);
907 OIC_LOG(ERROR, TAG, "state is null");
908 ca_mutex_unlock(g_deviceStateListMutex);
909 return CA_SEND_FAILED;
912 if (STATE_SEND_SUCCESS != state->sendState)
914 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
915 ca_mutex_unlock(g_deviceStateListMutex);
916 return CA_SEND_FAILED;
918 ca_mutex_unlock(g_deviceStateListMutex);
922 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
924 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
925 VERIFY_NON_NULL(device, TAG, "device is null");
926 VERIFY_NON_NULL(env, TAG, "env is null");
928 // get BLE address from bluetooth device object.
929 char* address = NULL;
930 CALEState_t* state = NULL;
931 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
934 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
935 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
938 OIC_LOG(ERROR, TAG, "address is not available");
939 return CA_STATUS_FAILED;
941 ca_mutex_lock(g_deviceStateListMutex);
942 state = CALEClientGetStateInfo(address);
943 ca_mutex_unlock(g_deviceStateListMutex);
944 (*env)->ReleaseStringUTFChars(env, jni_address, address);
949 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
951 // cancel previous connection request before connection
952 // if there is gatt object in g_gattObjectList.
955 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
958 OIC_LOG(ERROR, TAG, "address is not available");
959 return CA_STATUS_FAILED;
962 jobject gatt = CALEClientGetGattObjInList(env, address);
965 CAResult_t res = CALEClientDisconnect(env, gatt);
966 if (CA_STATUS_OK != res)
968 OIC_LOG(INFO, TAG, "there is no gatt object");
971 (*env)->ReleaseStringUTFChars(env, jni_address, address);
974 // connection request
975 jobject newGatt = CALEClientConnect(env, device, JNI_TRUE);
978 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
979 return CA_STATUS_FAILED;
984 if (STATE_CONNECTED == state->connectedState)
986 OIC_LOG(INFO, TAG, "GATT has already connected");
989 OIC_LOG(ERROR, TAG, "jni_address is not available");
990 return CA_STATUS_FAILED;
993 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
996 OIC_LOG(ERROR, TAG, "address is not available");
997 return CA_STATUS_FAILED;
1000 jobject gatt = CALEClientGetGattObjInList(env, address);
1003 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1004 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1005 return CA_STATUS_FAILED;
1008 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1009 if (CA_STATUS_OK != ret)
1011 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1012 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1015 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1019 OIC_LOG(DEBUG, TAG, "start to connect LE");
1020 jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
1023 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1024 return CA_STATUS_FAILED;
1029 return CA_STATUS_OK;
1032 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1034 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1035 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1037 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1038 if (!jni_cid_gattdevice_list)
1040 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1044 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1045 "()Landroid/bluetooth/BluetoothDevice;");
1046 if (!jni_mid_getDevice)
1048 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1052 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1053 if (!jni_obj_device)
1055 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1059 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1062 OIC_LOG(ERROR, TAG, "jni_address is null");
1072 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1075 OIC_LOG(DEBUG, TAG, "Gatt Close");
1076 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1077 VERIFY_NON_NULL(env, TAG, "env is null");
1079 // get BluetoothGatt class
1080 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1081 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1082 if (!jni_cid_BluetoothGatt)
1084 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1085 return CA_STATUS_FAILED;
1088 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1089 if (!jni_mid_closeGatt)
1091 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1092 return CA_STATUS_OK;
1095 // call disconnect gatt method
1096 OIC_LOG(DEBUG, TAG, "request to close GATT");
1097 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1099 if ((*env)->ExceptionCheck(env))
1101 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1102 (*env)->ExceptionDescribe(env);
1103 (*env)->ExceptionClear(env);
1104 return CA_STATUS_FAILED;
1107 return CA_STATUS_OK;
1110 CAResult_t CALEClientStartScan()
1112 if (!g_isStartedMulticastServer)
1114 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1115 return CA_STATUS_FAILED;
1118 if (!g_isStartedLEClient)
1120 OIC_LOG(ERROR, TAG, "LE client is not started");
1121 return CA_STATUS_FAILED;
1126 OIC_LOG(ERROR, TAG, "g_jvm is null");
1127 return CA_STATUS_FAILED;
1130 if (g_isStartedScan)
1132 OIC_LOG(INFO, TAG, "scanning is already started");
1133 return CA_STATUS_OK;
1136 bool isAttached = false;
1138 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1141 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1143 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1146 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1147 return CA_STATUS_FAILED;
1152 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1154 CAResult_t ret = CA_STATUS_OK;
1155 // scan gatt server with UUID
1156 if (g_leScanCallback && g_uuidList)
1159 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1161 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1163 if (CA_STATUS_OK != ret)
1165 if (CA_ADAPTER_NOT_ENABLED == ret)
1167 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1171 OIC_LOG(ERROR, TAG, "start scan has failed");
1178 (*g_jvm)->DetachCurrentThread(g_jvm);
1184 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1186 VERIFY_NON_NULL(callback, TAG, "callback is null");
1187 VERIFY_NON_NULL(env, TAG, "env is null");
1189 if (!CALEIsEnableBTAdapter(env))
1191 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1192 return CA_ADAPTER_NOT_ENABLED;
1195 // get default bt adapter class
1196 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1197 if (!jni_cid_BTAdapter)
1199 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1200 return CA_STATUS_FAILED;
1203 // get remote bt adapter method
1204 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1205 "getDefaultAdapter",
1206 METHODID_OBJECTNONPARAM);
1207 if (!jni_mid_getDefaultAdapter)
1209 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1210 return CA_STATUS_FAILED;
1213 // get start le scan method
1214 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1215 "(Landroid/bluetooth/BluetoothAdapter$"
1216 "LeScanCallback;)Z");
1217 if (!jni_mid_startLeScan)
1219 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1220 return CA_STATUS_FAILED;
1223 // gat bt adapter object
1224 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1225 jni_mid_getDefaultAdapter);
1226 if (!jni_obj_BTAdapter)
1228 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1229 return CA_STATUS_FAILED;
1232 // call start le scan method
1233 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1234 jni_mid_startLeScan, callback);
1235 if (!jni_obj_startLeScan)
1237 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1238 return CA_STATUS_FAILED;
1242 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1243 CALEClientSetScanFlag(true);
1246 return CA_STATUS_OK;
1249 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1251 VERIFY_NON_NULL(callback, TAG, "callback is null");
1252 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1253 VERIFY_NON_NULL(env, TAG, "env is null");
1255 if (!CALEIsEnableBTAdapter(env))
1257 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1258 return CA_ADAPTER_NOT_ENABLED;
1261 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1262 if (!jni_cid_BTAdapter)
1264 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1265 return CA_STATUS_FAILED;
1268 // get remote bt adapter method
1269 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1270 "getDefaultAdapter",
1271 METHODID_OBJECTNONPARAM);
1272 if (!jni_mid_getDefaultAdapter)
1274 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1275 return CA_STATUS_FAILED;
1278 // get start le scan method
1279 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1280 "([Ljava/util/UUID;Landroid/bluetooth/"
1281 "BluetoothAdapter$LeScanCallback;)Z");
1282 if (!jni_mid_startLeScan)
1284 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1285 return CA_STATUS_FAILED;
1288 // get bt adapter object
1289 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1290 jni_mid_getDefaultAdapter);
1291 if (!jni_obj_BTAdapter)
1293 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1294 return CA_STATUS_FAILED;
1297 // call start le scan method
1298 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1299 jni_mid_startLeScan, uuids, callback);
1300 if (!jni_obj_startLeScan)
1302 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1303 return CA_STATUS_FAILED;
1307 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1308 CALEClientSetScanFlag(true);
1311 return CA_STATUS_OK;
1314 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1316 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1317 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1320 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1323 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1327 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1328 "(Ljava/lang/String;)"
1329 "Ljava/util/UUID;");
1330 if (!jni_mid_fromString)
1332 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1336 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1337 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1341 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1345 return jni_obj_uuid;
1348 CAResult_t CALEClientStopScan()
1352 OIC_LOG(ERROR, TAG, "g_jvm is null");
1353 return CA_STATUS_FAILED;
1356 if (!g_isStartedScan)
1358 OIC_LOG(INFO, TAG, "scanning is already stopped");
1359 return CA_STATUS_OK;
1362 bool isAttached = false;
1364 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1367 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1368 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1371 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1372 return CA_STATUS_FAILED;
1377 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1378 if (CA_STATUS_OK != ret)
1380 if (CA_ADAPTER_NOT_ENABLED == ret)
1382 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1386 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1391 CALEClientSetScanFlag(false);
1396 (*g_jvm)->DetachCurrentThread(g_jvm);
1402 void CALEClientSetScanFlag(bool flag)
1404 ca_mutex_lock(g_scanMutex);
1405 g_isStartedScan = flag;
1406 ca_mutex_unlock(g_scanMutex);
1409 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1411 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1412 VERIFY_NON_NULL(callback, TAG, "callback is null");
1413 VERIFY_NON_NULL(env, TAG, "env is null");
1415 if (!CALEIsEnableBTAdapter(env))
1417 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1418 return CA_ADAPTER_NOT_ENABLED;
1421 // get default bt adapter class
1422 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1423 if (!jni_cid_BTAdapter)
1425 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1426 return CA_STATUS_FAILED;
1429 // get remote bt adapter method
1430 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1431 "getDefaultAdapter",
1432 METHODID_OBJECTNONPARAM);
1433 if (!jni_mid_getDefaultAdapter)
1435 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1436 return CA_STATUS_FAILED;
1439 // get start le scan method
1440 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1441 "(Landroid/bluetooth/"
1442 "BluetoothAdapter$LeScanCallback;)V");
1443 if (!jni_mid_stopLeScan)
1445 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1446 return CA_STATUS_FAILED;
1449 // gat bt adapter object
1450 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1451 jni_mid_getDefaultAdapter);
1452 if (!jni_obj_BTAdapter)
1454 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1455 return CA_STATUS_FAILED;
1458 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1459 // call start le scan method
1460 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1461 if ((*env)->ExceptionCheck(env))
1463 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1464 (*env)->ExceptionDescribe(env);
1465 (*env)->ExceptionClear(env);
1466 return CA_STATUS_FAILED;
1469 return CA_STATUS_OK;
1472 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1474 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1475 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1476 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1478 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1479 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1482 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1485 OIC_LOG(ERROR, TAG, "address is not available");
1489 // close the gatt service
1490 jobject gatt = CALEClientGetGattObjInList(env, address);
1493 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1494 if (CA_STATUS_OK != res)
1496 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1497 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1501 // clean previous gatt object after close profile service
1502 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1503 if (CA_STATUS_OK != res)
1505 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1506 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1510 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1513 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1516 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1520 // add new gatt object into g_gattObjectList
1521 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1522 if (CA_STATUS_OK != res)
1524 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1531 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1533 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1534 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1535 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1537 if (!CALEIsEnableBTAdapter(env))
1539 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1543 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1546 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1550 // get BluetoothDevice class
1551 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1552 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1553 if (!jni_cid_BluetoothDevice)
1555 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1559 // get connectGatt method
1560 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1561 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1562 "(Landroid/content/Context;ZLandroid/"
1563 "bluetooth/BluetoothGattCallback;)"
1564 "Landroid/bluetooth/BluetoothGatt;");
1565 if (!jni_mid_connectGatt)
1567 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1571 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1572 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1573 jni_mid_connectGatt,
1575 autoconnect, g_leGattCallback);
1576 if (!jni_obj_connectGatt)
1578 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1579 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1580 CALEClientUpdateSendCnt(env);
1585 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1587 return jni_obj_connectGatt;
1590 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1592 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1594 VERIFY_NON_NULL(env, TAG, "env is null");
1595 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1597 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1598 if (!jni_cid_BTAdapter)
1600 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1601 return CA_STATUS_FAILED;
1604 // get remote bt adapter method
1605 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1606 "getDefaultAdapter",
1607 METHODID_OBJECTNONPARAM);
1608 if (!jni_mid_getDefaultAdapter)
1610 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1611 return CA_STATUS_FAILED;
1614 // gat bt adapter object
1615 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1616 jni_mid_getDefaultAdapter);
1617 if (!jni_obj_BTAdapter)
1619 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1620 return CA_STATUS_FAILED;
1623 // get closeProfileProxy method
1624 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1625 "closeProfileProxy",
1626 "(ILandroid/bluetooth/"
1627 "BluetoothProfile;)V");
1628 if (!jni_mid_closeProfileProxy)
1630 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1631 return CA_STATUS_FAILED;
1634 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1635 if (!jni_cid_BTProfile)
1637 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1638 return CA_STATUS_FAILED;
1641 // GATT - Constant value : 7 (0x00000007)
1642 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1646 OIC_LOG(ERROR, TAG, "id_gatt is null");
1647 return CA_STATUS_FAILED;
1650 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1652 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1653 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1654 if ((*env)->ExceptionCheck(env))
1656 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1657 (*env)->ExceptionDescribe(env);
1658 (*env)->ExceptionClear(env);
1659 return CA_STATUS_FAILED;
1662 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1663 return CA_STATUS_OK;
1667 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1669 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1670 VERIFY_NON_NULL(env, TAG, "env is null");
1671 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1673 // get BluetoothGatt class
1674 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1675 if (!jni_cid_BluetoothGatt)
1677 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1678 return CA_STATUS_FAILED;
1681 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1682 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1683 "disconnect", "()V");
1684 if (!jni_mid_disconnectGatt)
1686 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1687 return CA_STATUS_FAILED;
1690 // call disconnect gatt method
1691 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1692 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1693 if ((*env)->ExceptionCheck(env))
1695 OIC_LOG(ERROR, TAG, "disconnect has failed");
1696 (*env)->ExceptionDescribe(env);
1697 (*env)->ExceptionClear(env);
1698 return CA_STATUS_FAILED;
1701 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1703 return CA_STATUS_OK;
1706 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1708 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1709 VERIFY_NON_NULL(env, TAG, "env is null");
1711 if (!g_gattObjectList)
1713 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1714 return CA_STATUS_OK;
1717 uint32_t length = u_arraylist_length(g_gattObjectList);
1718 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1719 for (uint32_t index = 0; index < length; index++)
1721 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1722 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1725 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1728 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1729 if (CA_STATUS_OK != res)
1731 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1736 return CA_STATUS_OK;
1739 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1741 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1742 VERIFY_NON_NULL(env, TAG, "env is null");
1744 if (!g_gattObjectList)
1746 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1747 return CA_STATUS_OK;
1750 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1753 OIC_LOG(ERROR, TAG, "address is null");
1754 return CA_STATUS_FAILED;
1757 uint32_t length = u_arraylist_length(g_gattObjectList);
1758 for (uint32_t index = 0; index < length; index++)
1760 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1763 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1767 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1768 if (!jni_setAddress)
1770 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1771 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1772 return CA_STATUS_FAILED;
1775 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1778 OIC_LOG(ERROR, TAG, "setAddress is null");
1779 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1780 return CA_STATUS_FAILED;
1783 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1784 if (!strcmp(address, setAddress))
1786 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1787 if (CA_STATUS_OK != res)
1789 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1790 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1791 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1792 return CA_STATUS_FAILED;
1794 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1795 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1796 return CA_STATUS_OK;
1798 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1800 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1802 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1803 return CA_STATUS_OK;
1806 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1808 VERIFY_NON_NULL(env, TAG, "env is null");
1809 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1811 if (!CALEIsEnableBTAdapter(env))
1813 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1814 return CA_ADAPTER_NOT_ENABLED;
1817 // get BluetoothGatt class
1818 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1819 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1820 if (!jni_cid_BluetoothGatt)
1822 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1823 return CA_STATUS_FAILED;
1826 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1827 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1828 "discoverServices", "()Z");
1829 if (!jni_mid_discoverServices)
1831 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1832 return CA_STATUS_FAILED;
1834 // call disconnect gatt method
1835 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1836 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1839 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1840 return CA_STATUS_FAILED;
1843 return CA_STATUS_OK;
1846 static void CALEWriteCharacteristicThread(void* object)
1848 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1850 bool isAttached = false;
1852 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1855 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1856 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1860 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1866 jobject gatt = (jobject)object;
1867 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1868 if (CA_STATUS_OK != ret)
1870 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1875 (*g_jvm)->DetachCurrentThread(g_jvm);
1879 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1881 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1882 VERIFY_NON_NULL(env, TAG, "env is null");
1885 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1886 if (!jni_obj_character)
1888 CALEClientSendFinish(env, gatt);
1889 return CA_STATUS_FAILED;
1892 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1893 if (CA_STATUS_OK != ret)
1895 CALEClientSendFinish(env, gatt);
1896 return CA_STATUS_FAILED;
1899 // wait for callback for write Characteristic with success to sent data
1900 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1901 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1902 if (!g_isSignalSetFlag)
1904 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1905 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
1906 g_threadWriteCharacteristicMutex,
1907 WAIT_TIME_WRITE_CHARACTERISTIC))
1909 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1910 g_isSignalSetFlag = false;
1911 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1912 return CA_STATUS_FAILED;
1915 // reset flag set by writeCharacteristic Callback
1916 g_isSignalSetFlag = false;
1917 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1919 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
1920 return CA_STATUS_OK;
1923 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1925 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
1926 VERIFY_NON_NULL(env, TAG, "env is null");
1927 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1929 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
1930 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
1931 CALEWriteCharacteristicThread, (void*)gattParam))
1933 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
1934 return CA_STATUS_FAILED;
1937 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
1938 return CA_STATUS_OK;
1941 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1942 jobject gattCharacteristic)
1944 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1945 VERIFY_NON_NULL(env, TAG, "env is null");
1946 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1947 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1949 if (!CALEIsEnableBTAdapter(env))
1951 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1952 return CA_STATUS_FAILED;
1955 // get BluetoothGatt class
1956 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1957 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1958 if (!jni_cid_BluetoothGatt)
1960 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1961 return CA_STATUS_FAILED;
1964 OIC_LOG(DEBUG, TAG, "write characteristic method");
1965 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1966 "writeCharacteristic",
1967 "(Landroid/bluetooth/"
1968 "BluetoothGattCharacteristic;)Z");
1969 if (!jni_mid_writeCharacteristic)
1971 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1972 return CA_STATUS_FAILED;
1975 // call disconnect gatt method
1976 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1977 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1978 jni_mid_writeCharacteristic,
1979 gattCharacteristic);
1982 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
1986 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1987 return CA_STATUS_FAILED;
1990 return CA_STATUS_OK;
1993 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1995 VERIFY_NON_NULL(env, TAG, "env is null");
1996 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1998 if (!CALEIsEnableBTAdapter(env))
2000 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2001 return CA_STATUS_FAILED;
2004 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2005 if (!jni_cid_BluetoothGatt)
2007 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2008 return CA_STATUS_FAILED;
2011 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2014 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2015 return CA_STATUS_FAILED;
2018 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2019 if (!jni_obj_GattCharacteristic)
2021 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2022 return CA_STATUS_FAILED;
2025 OIC_LOG(DEBUG, TAG, "read characteristic method");
2026 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2027 "readCharacteristic",
2028 "(Landroid/bluetooth/"
2029 "BluetoothGattCharacteristic;)Z");
2030 if (!jni_mid_readCharacteristic)
2032 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2033 return CA_STATUS_FAILED;
2036 // call disconnect gatt method
2037 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2038 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2039 jni_obj_GattCharacteristic);
2042 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2046 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2047 return CA_STATUS_FAILED;
2050 return CA_STATUS_OK;
2053 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2054 jobject characteristic)
2056 VERIFY_NON_NULL(env, TAG, "env is null");
2057 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2058 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2060 if (!CALEIsEnableBTAdapter(env))
2062 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2063 return CA_ADAPTER_NOT_ENABLED;
2066 // get BluetoothGatt class
2067 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2068 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2069 if (!jni_cid_BluetoothGatt)
2071 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2072 return CA_STATUS_FAILED;
2075 // set Characteristic Notification
2076 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2077 "setCharacteristicNotification",
2078 "(Landroid/bluetooth/"
2079 "BluetoothGattCharacteristic;Z)Z");
2080 if (!jni_mid_setNotification)
2082 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2083 return CA_STATUS_FAILED;
2086 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2087 characteristic, JNI_TRUE);
2088 if (JNI_TRUE == ret)
2090 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2094 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2095 return CA_STATUS_FAILED;
2098 return CA_STATUS_OK;
2101 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2103 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2104 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2105 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2107 if (!CALEIsEnableBTAdapter(env))
2109 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2113 // get BluetoothGatt class
2114 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2115 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2116 if (!jni_cid_BluetoothGatt)
2118 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2122 jmethodID jni_mid_getService = (*env)->GetMethodID(
2123 env, jni_cid_BluetoothGatt, "getService",
2124 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2125 if (!jni_mid_getService)
2127 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2131 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2132 if (!jni_obj_service_uuid)
2134 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2138 // get bluetooth gatt service
2139 OIC_LOG(DEBUG, TAG, "request to get service");
2140 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2141 jni_obj_service_uuid);
2142 if (!jni_obj_gattService)
2144 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2148 // get bluetooth gatt service class
2149 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2150 env, "android/bluetooth/BluetoothGattService");
2151 if (!jni_cid_BluetoothGattService)
2153 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2157 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2158 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2159 "getCharacteristic",
2160 "(Ljava/util/UUID;)"
2161 "Landroid/bluetooth/"
2162 "BluetoothGattCharacteristic;");
2163 if (!jni_mid_getCharacteristic)
2165 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2169 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2172 OIC_LOG(ERROR, TAG, "uuid is null");
2176 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2177 if (!jni_obj_tx_uuid)
2179 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2180 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2184 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2185 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2186 jni_mid_getCharacteristic,
2189 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2190 return jni_obj_GattCharacteristic;
2193 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2195 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2196 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2197 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2198 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2200 if (!CALEIsEnableBTAdapter(env))
2202 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2206 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2209 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2213 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2214 if (!jni_obj_GattCharacteristic)
2216 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2220 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2221 "/BluetoothGattCharacteristic");
2222 if (!jni_cid_BTGattCharacteristic)
2224 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2228 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2229 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2231 if (!jni_mid_setValue)
2233 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2237 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2239 if (JNI_TRUE == ret)
2241 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2245 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2250 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2251 "setWriteType", "(I)V");
2252 if (!jni_mid_setWriteType)
2254 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2258 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2259 "WRITE_TYPE_NO_RESPONSE", "I");
2260 if (!jni_fid_no_response)
2262 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2266 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2267 jni_fid_no_response);
2269 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2271 return jni_obj_GattCharacteristic;
2274 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2276 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2277 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2279 if (!CALEIsEnableBTAdapter(env))
2281 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2285 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2286 "BluetoothGattCharacteristic");
2287 if (!jni_cid_BTGattCharacteristic)
2289 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2293 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2294 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2296 if (!jni_mid_getValue)
2298 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2302 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2304 return jni_obj_data_array;
2307 CAResult_t CALEClientCreateUUIDList()
2311 OIC_LOG(ERROR, TAG, "g_jvm is null");
2312 return CA_STATUS_FAILED;
2315 bool isAttached = false;
2317 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2320 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2321 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2325 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2326 return CA_STATUS_FAILED;
2331 // create new object array
2332 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2333 if (!jni_cid_uuid_list)
2335 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2339 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2340 jni_cid_uuid_list, NULL);
2341 if (!jni_obj_uuid_list)
2343 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2348 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2351 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2354 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2356 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2360 (*g_jvm)->DetachCurrentThread(g_jvm);
2363 return CA_STATUS_OK;
2370 (*g_jvm)->DetachCurrentThread(g_jvm);
2372 return CA_STATUS_FAILED;
2375 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2376 jobject characteristic)
2378 VERIFY_NON_NULL(env, TAG, "env is null");
2379 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2380 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2382 if (!CALEIsEnableBTAdapter(env))
2384 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2385 return CA_ADAPTER_NOT_ENABLED;
2388 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2389 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2390 "BluetoothGattCharacteristic");
2391 if (!jni_cid_BTGattCharacteristic)
2393 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2394 return CA_STATUS_FAILED;
2397 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2398 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2400 "(Ljava/util/UUID;)Landroid/bluetooth/"
2401 "BluetoothGattDescriptor;");
2402 if (!jni_mid_getDescriptor)
2404 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2405 return CA_STATUS_FAILED;
2408 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2409 if (!jni_obj_cc_uuid)
2411 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2412 return CA_STATUS_FAILED;
2415 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2416 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2417 jni_mid_getDescriptor, jni_obj_cc_uuid);
2418 if (!jni_obj_descriptor)
2420 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2421 return CA_NOT_SUPPORTED;
2424 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2425 jclass jni_cid_descriptor = (*env)->FindClass(env,
2426 "android/bluetooth/BluetoothGattDescriptor");
2427 if (!jni_cid_descriptor)
2429 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2430 return CA_STATUS_FAILED;
2433 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2434 if (!jni_mid_setValue)
2436 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2437 return CA_STATUS_FAILED;
2440 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2441 "ENABLE_NOTIFICATION_VALUE", "[B");
2442 if (!jni_fid_NotiValue)
2444 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2445 return CA_STATUS_FAILED;
2448 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2450 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2451 env, jni_obj_descriptor, jni_mid_setValue,
2452 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2455 OIC_LOG(DEBUG, TAG, "setValue success");
2459 OIC_LOG(ERROR, TAG, "setValue has failed");
2460 return CA_STATUS_FAILED;
2463 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2466 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2467 return CA_STATUS_FAILED;
2470 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2471 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2472 "(Landroid/bluetooth/"
2473 "BluetoothGattDescriptor;)Z");
2474 if (!jni_mid_writeDescriptor)
2476 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2477 return CA_STATUS_FAILED;
2480 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2481 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2482 jni_obj_descriptor);
2485 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2489 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2490 return CA_STATUS_FAILED;
2493 return CA_STATUS_OK;
2496 void CALEClientCreateScanDeviceList(JNIEnv *env)
2498 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2499 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2501 ca_mutex_lock(g_deviceListMutex);
2502 // create new object array
2503 if (g_deviceList == NULL)
2505 OIC_LOG(DEBUG, TAG, "Create device list");
2507 g_deviceList = u_arraylist_create();
2509 ca_mutex_unlock(g_deviceListMutex);
2512 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2514 VERIFY_NON_NULL(device, TAG, "device is null");
2515 VERIFY_NON_NULL(env, TAG, "env is null");
2517 ca_mutex_lock(g_deviceListMutex);
2521 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2522 ca_mutex_unlock(g_deviceListMutex);
2523 return CA_STATUS_FAILED;
2526 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2527 if (!jni_remoteAddress)
2529 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2530 ca_mutex_unlock(g_deviceListMutex);
2531 return CA_STATUS_FAILED;
2534 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2537 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2538 ca_mutex_unlock(g_deviceListMutex);
2539 return CA_STATUS_FAILED;
2542 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2544 jobject gdevice = (*env)->NewGlobalRef(env, device);
2545 u_arraylist_add(g_deviceList, gdevice);
2546 ca_cond_signal(g_deviceDescCond);
2547 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2549 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2551 ca_mutex_unlock(g_deviceListMutex);
2553 return CA_STATUS_OK;
2556 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2558 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2559 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2563 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2567 uint32_t length = u_arraylist_length(g_deviceList);
2568 for (uint32_t index = 0; index < length; index++)
2570 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2573 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2577 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2578 if (!jni_setAddress)
2580 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2584 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2587 OIC_LOG(ERROR, TAG, "setAddress is null");
2591 if (!strcmp(remoteAddress, setAddress))
2593 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2597 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2600 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2605 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2607 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2608 VERIFY_NON_NULL(env, TAG, "env is null");
2610 ca_mutex_lock(g_deviceListMutex);
2614 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2615 ca_mutex_unlock(g_deviceListMutex);
2616 return CA_STATUS_FAILED;
2619 uint32_t length = u_arraylist_length(g_deviceList);
2620 for (uint32_t index = 0; index < length; index++)
2622 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2625 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2628 (*env)->DeleteGlobalRef(env, jarrayObj);
2631 OICFree(g_deviceList);
2632 g_deviceList = NULL;
2634 ca_mutex_unlock(g_deviceListMutex);
2635 return CA_STATUS_OK;
2638 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2640 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2641 VERIFY_NON_NULL(address, TAG, "address is null");
2642 VERIFY_NON_NULL(env, TAG, "env is null");
2644 ca_mutex_lock(g_deviceListMutex);
2648 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2649 ca_mutex_unlock(g_deviceListMutex);
2650 return CA_STATUS_FAILED;
2653 uint32_t length = u_arraylist_length(g_deviceList);
2654 for (uint32_t index = 0; index < length; index++)
2656 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2659 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2660 ca_mutex_unlock(g_deviceListMutex);
2661 return CA_STATUS_FAILED;
2664 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2665 if (!jni_setAddress)
2667 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2668 ca_mutex_unlock(g_deviceListMutex);
2669 return CA_STATUS_FAILED;
2672 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2675 OIC_LOG(ERROR, TAG, "setAddress is null");
2676 ca_mutex_unlock(g_deviceListMutex);
2677 return CA_STATUS_FAILED;
2680 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2683 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2684 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2685 ca_mutex_unlock(g_deviceListMutex);
2686 return CA_STATUS_FAILED;
2689 if (!strcmp(setAddress, remoteAddress))
2691 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2692 (*env)->DeleteGlobalRef(env, jarrayObj);
2693 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2694 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2696 if (NULL == u_arraylist_remove(g_deviceList, index))
2698 OIC_LOG(ERROR, TAG, "List removal failed.");
2699 ca_mutex_unlock(g_deviceListMutex);
2700 return CA_STATUS_FAILED;
2702 ca_mutex_unlock(g_deviceListMutex);
2703 return CA_STATUS_OK;
2705 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2706 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2709 ca_mutex_unlock(g_deviceListMutex);
2710 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2712 return CA_STATUS_OK;
2719 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2721 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2722 VERIFY_NON_NULL(env, TAG, "env is null");
2723 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2725 ca_mutex_lock(g_gattObjectMutex);
2727 if (!g_gattObjectList)
2729 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2730 ca_mutex_unlock(g_gattObjectMutex);
2731 return CA_STATUS_FAILED;
2734 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2735 if (!jni_remoteAddress)
2737 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2738 ca_mutex_unlock(g_gattObjectMutex);
2739 return CA_STATUS_FAILED;
2742 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2745 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2746 ca_mutex_unlock(g_gattObjectMutex);
2747 return CA_STATUS_FAILED;
2750 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2751 if (!CALEClientIsGattObjInList(env, remoteAddress))
2753 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2754 u_arraylist_add(g_gattObjectList, newGatt);
2755 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2758 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2759 ca_mutex_unlock(g_gattObjectMutex);
2760 return CA_STATUS_OK;
2763 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2765 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2766 VERIFY_NON_NULL(env, TAG, "env is null");
2767 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2769 uint32_t length = u_arraylist_length(g_gattObjectList);
2770 for (uint32_t index = 0; index < length; index++)
2773 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2776 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2780 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2781 if (!jni_setAddress)
2783 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2787 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2790 OIC_LOG(ERROR, TAG, "setAddress is null");
2794 if (!strcmp(remoteAddress, setAddress))
2796 OIC_LOG(DEBUG, TAG, "the device is already set");
2797 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2802 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2807 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2811 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2813 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2814 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2815 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2817 ca_mutex_lock(g_gattObjectMutex);
2818 uint32_t length = u_arraylist_length(g_gattObjectList);
2819 for (uint32_t index = 0; index < length; index++)
2821 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2824 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2825 ca_mutex_unlock(g_gattObjectMutex);
2829 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2830 if (!jni_setAddress)
2832 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2833 ca_mutex_unlock(g_gattObjectMutex);
2837 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2840 OIC_LOG(ERROR, TAG, "setAddress is null");
2841 ca_mutex_unlock(g_gattObjectMutex);
2845 if (!strcmp(remoteAddress, setAddress))
2847 OIC_LOG(DEBUG, TAG, "the device is already set");
2848 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2849 ca_mutex_unlock(g_gattObjectMutex);
2852 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2855 ca_mutex_unlock(g_gattObjectMutex);
2856 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2860 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2862 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2863 VERIFY_NON_NULL(env, TAG, "env is null");
2865 ca_mutex_lock(g_gattObjectMutex);
2866 if (!g_gattObjectList)
2868 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2869 ca_mutex_unlock(g_gattObjectMutex);
2870 return CA_STATUS_OK;
2873 uint32_t length = u_arraylist_length(g_gattObjectList);
2874 for (uint32_t index = 0; index < length; index++)
2876 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2879 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2882 (*env)->DeleteGlobalRef(env, jarrayObj);
2885 OICFree(g_gattObjectList);
2886 g_gattObjectList = NULL;
2887 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2888 ca_mutex_unlock(g_gattObjectMutex);
2889 return CA_STATUS_OK;
2892 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2894 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2895 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2896 VERIFY_NON_NULL(env, TAG, "env is null");
2898 ca_mutex_lock(g_gattObjectMutex);
2899 if (!g_gattObjectList)
2901 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2902 ca_mutex_unlock(g_gattObjectMutex);
2903 return CA_STATUS_OK;
2906 uint32_t length = u_arraylist_length(g_gattObjectList);
2907 for (uint32_t index = 0; index < length; index++)
2909 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2912 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2913 ca_mutex_unlock(g_gattObjectMutex);
2914 return CA_STATUS_FAILED;
2917 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2918 if (!jni_setAddress)
2920 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2921 ca_mutex_unlock(g_gattObjectMutex);
2922 return CA_STATUS_FAILED;
2925 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2928 OIC_LOG(ERROR, TAG, "setAddress is null");
2929 ca_mutex_unlock(g_gattObjectMutex);
2930 return CA_STATUS_FAILED;
2933 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2934 if (!jni_remoteAddress)
2936 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2937 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2938 ca_mutex_unlock(g_gattObjectMutex);
2939 return CA_STATUS_FAILED;
2942 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2945 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2946 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2947 ca_mutex_unlock(g_gattObjectMutex);
2948 return CA_STATUS_FAILED;
2951 if (!strcmp(setAddress, remoteAddress))
2953 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2954 (*env)->DeleteGlobalRef(env, jarrayObj);
2955 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2956 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2958 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2960 OIC_LOG(ERROR, TAG, "List removal failed.");
2961 ca_mutex_unlock(g_gattObjectMutex);
2962 return CA_STATUS_FAILED;
2964 ca_mutex_unlock(g_gattObjectMutex);
2965 return CA_STATUS_OK;
2967 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2968 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2971 ca_mutex_unlock(g_gattObjectMutex);
2972 OIC_LOG(DEBUG, TAG, "there are no target object");
2973 return CA_STATUS_OK;
2976 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2978 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2979 VERIFY_NON_NULL(addr, TAG, "addr is null");
2980 VERIFY_NON_NULL(env, TAG, "env is null");
2982 ca_mutex_lock(g_gattObjectMutex);
2983 if (!g_gattObjectList)
2985 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2986 ca_mutex_unlock(g_gattObjectMutex);
2987 return CA_STATUS_OK;
2990 uint32_t length = u_arraylist_length(g_gattObjectList);
2991 for (uint32_t index = 0; index < length; index++)
2993 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2996 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2997 ca_mutex_unlock(g_gattObjectMutex);
2998 return CA_STATUS_FAILED;
3001 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3002 if (!jni_setAddress)
3004 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3005 ca_mutex_unlock(g_gattObjectMutex);
3006 return CA_STATUS_FAILED;
3009 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3012 OIC_LOG(ERROR, TAG, "setAddress is null");
3013 ca_mutex_unlock(g_gattObjectMutex);
3014 return CA_STATUS_FAILED;
3017 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3020 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3021 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3022 ca_mutex_unlock(g_gattObjectMutex);
3023 return CA_STATUS_FAILED;
3026 if (!strcmp(setAddress, remoteAddress))
3028 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3029 (*env)->DeleteGlobalRef(env, jarrayObj);
3031 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3032 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3033 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3035 OIC_LOG(ERROR, TAG, "List removal failed.");
3036 ca_mutex_unlock(g_gattObjectMutex);
3037 return CA_STATUS_FAILED;
3039 ca_mutex_unlock(g_gattObjectMutex);
3040 return CA_STATUS_OK;
3042 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3043 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3046 ca_mutex_unlock(g_gattObjectMutex);
3047 OIC_LOG(DEBUG, TAG, "there are no target object");
3048 return CA_STATUS_FAILED;
3051 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3053 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3055 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3056 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3058 // get Bluetooth Address
3059 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3060 if (!jni_btTargetAddress)
3062 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3066 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3069 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3073 // get method ID of getDevice()
3074 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3075 if (!jni_cid_gattdevice_list)
3077 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3078 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3082 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3083 METHODID_BT_DEVICE);
3084 if (!jni_mid_getDevice)
3086 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3087 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3091 size_t length = u_arraylist_length(g_gattObjectList);
3092 for (size_t index = 0; index < length; index++)
3094 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3097 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3098 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3102 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3103 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3104 if (!jni_obj_device)
3106 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3107 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3111 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3114 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3115 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3119 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3122 OIC_LOG(ERROR, TAG, "btAddress is not available");
3123 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3127 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3128 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3129 if (!strcmp(targetAddress, btAddress))
3131 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3134 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3137 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3139 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3140 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3141 (*env)->DeleteLocalRef(env, jni_btAddress);
3142 (*env)->DeleteLocalRef(env, jni_obj_device);
3143 return jni_LEAddress;
3145 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3146 (*env)->DeleteLocalRef(env, jni_btAddress);
3147 (*env)->DeleteLocalRef(env, jni_obj_device);
3150 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3158 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3159 uint16_t notificationState, uint16_t sendState)
3161 VERIFY_NON_NULL(address, TAG, "address is null");
3163 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3166 OIC_LOG(ERROR, TAG, "out of memory");
3167 return CA_MEMORY_ALLOC_FAILED;
3170 if (strlen(address) > CA_MACADDR_SIZE)
3172 OIC_LOG(ERROR, TAG, "address is not proper");
3174 return CA_STATUS_FAILED;
3177 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3178 newstate->connectedState = connectedState;
3179 newstate->notificationState = notificationState;
3180 newstate->sendState = sendState;
3181 return CALEClientAddDeviceStateToList(newstate);
3184 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3186 VERIFY_NON_NULL(state, TAG, "state is null");
3188 ca_mutex_lock(g_deviceStateListMutex);
3190 if (!g_deviceStateList)
3192 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3193 ca_mutex_unlock(g_deviceStateListMutex);
3194 return CA_STATUS_FAILED;
3197 if (CALEClientIsDeviceInList(state->address))
3199 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3202 OIC_LOG(ERROR, TAG, "curState is null");
3203 ca_mutex_unlock(g_deviceStateListMutex);
3204 return CA_STATUS_FAILED;
3207 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3209 state->notificationState = curState->notificationState;
3212 // delete previous state for update new state
3213 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3214 if (CA_STATUS_OK != res)
3216 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3217 ca_mutex_unlock(g_deviceStateListMutex);
3221 u_arraylist_add(g_deviceStateList, state); // update new state
3222 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3223 state->connectedState, state->notificationState, state->address);
3225 ca_mutex_unlock(g_deviceStateListMutex);
3226 return CA_STATUS_OK;
3229 bool CALEClientIsDeviceInList(const char* remoteAddress)
3231 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3233 if (!g_deviceStateList)
3235 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3239 uint32_t length = u_arraylist_length(g_deviceStateList);
3240 for (uint32_t index = 0; index < length; index++)
3242 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3245 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3249 if (!strcmp(remoteAddress, state->address))
3251 OIC_LOG(DEBUG, TAG, "the device is already set");
3260 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3264 CAResult_t CALEClientRemoveAllDeviceState()
3266 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3268 ca_mutex_lock(g_deviceStateListMutex);
3269 if (!g_deviceStateList)
3271 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3272 ca_mutex_unlock(g_deviceStateListMutex);
3273 return CA_STATUS_FAILED;
3276 uint32_t length = u_arraylist_length(g_deviceStateList);
3277 for (uint32_t index = 0; index < length; index++)
3279 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3282 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3288 OICFree(g_deviceStateList);
3289 g_deviceStateList = NULL;
3290 ca_mutex_unlock(g_deviceStateListMutex);
3292 return CA_STATUS_OK;
3295 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3297 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3298 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3300 if (!g_deviceStateList)
3302 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3303 return CA_STATUS_FAILED;
3306 uint32_t length = u_arraylist_length(g_deviceStateList);
3307 for (uint32_t index = 0; index < length; index++)
3309 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3312 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3316 if (!strcmp(state->address, remoteAddress))
3318 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3320 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3322 if (NULL == targetState)
3324 OIC_LOG(ERROR, TAG, "List removal failed.");
3325 return CA_STATUS_FAILED;
3328 OICFree(targetState);
3329 return CA_STATUS_OK;
3333 return CA_STATUS_OK;
3336 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3338 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3339 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3341 if (!g_deviceStateList)
3343 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3347 uint32_t length = u_arraylist_length(g_deviceStateList);
3348 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3350 for (uint32_t index = 0; index < length; index++)
3352 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3355 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3359 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3360 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3362 if (!strcmp(state->address, remoteAddress))
3364 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3371 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3373 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3374 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3376 ca_mutex_lock(g_deviceStateListMutex);
3377 if (!g_deviceStateList)
3379 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3380 ca_mutex_unlock(g_deviceStateListMutex);
3384 uint32_t length = u_arraylist_length(g_deviceStateList);
3385 for (uint32_t index = 0; index < length; index++)
3387 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3390 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3394 if (!strcmp(state->address, remoteAddress))
3396 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3398 if (STATE_CONNECTED == state->connectedState)
3400 ca_mutex_unlock(g_deviceStateListMutex);
3405 ca_mutex_unlock(g_deviceStateListMutex);
3410 ca_mutex_unlock(g_deviceStateListMutex);
3414 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3416 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3417 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3419 ca_mutex_lock(g_deviceStateListMutex);
3420 if (!g_deviceStateList)
3422 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3423 ca_mutex_unlock(g_deviceStateListMutex);
3427 uint32_t length = u_arraylist_length(g_deviceStateList);
3428 for (uint32_t index = 0; index < length; index++)
3430 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3433 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3437 if (!strcmp(state->address, remoteAddress))
3439 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3441 if (STATE_CHARACTER_SET == state->notificationState)
3443 ca_mutex_unlock(g_deviceStateListMutex);
3448 ca_mutex_unlock(g_deviceStateListMutex);
3454 ca_mutex_unlock(g_deviceStateListMutex);
3458 void CALEClientCreateDeviceList()
3460 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3462 // create new object array
3463 if (!g_gattObjectList)
3465 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3467 g_gattObjectList = u_arraylist_create();
3470 if (!g_deviceStateList)
3472 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3474 g_deviceStateList = u_arraylist_create();
3479 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3481 g_deviceList = u_arraylist_create();
3486 * Check Sent Count for remove g_sendBuffer
3488 void CALEClientUpdateSendCnt(JNIEnv *env)
3490 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
3492 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3494 ca_mutex_lock(g_threadMutex);
3498 if (g_targetCnt <= g_currentSentCnt)
3501 g_currentSentCnt = 0;
3505 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3506 g_sendBuffer = NULL;
3508 // notity the thread
3509 ca_cond_signal(g_threadCond);
3511 CALEClientSetSendFinishFlag(true);
3512 OIC_LOG(DEBUG, TAG, "set signal for send data");
3515 ca_mutex_unlock(g_threadMutex);
3518 CAResult_t CALEClientInitGattMutexVaraibles()
3520 if (NULL == g_bleReqRespClientCbMutex)
3522 g_bleReqRespClientCbMutex = ca_mutex_new();
3523 if (NULL == g_bleReqRespClientCbMutex)
3525 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3526 return CA_STATUS_FAILED;
3530 if (NULL == g_bleServerBDAddressMutex)
3532 g_bleServerBDAddressMutex = ca_mutex_new();
3533 if (NULL == g_bleServerBDAddressMutex)
3535 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3536 return CA_STATUS_FAILED;
3540 if (NULL == g_threadMutex)
3542 g_threadMutex = ca_mutex_new();
3543 if (NULL == g_threadMutex)
3545 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3546 return CA_STATUS_FAILED;
3550 if (NULL == g_threadSendMutex)
3552 g_threadSendMutex = ca_mutex_new();
3553 if (NULL == g_threadSendMutex)
3555 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3556 return CA_STATUS_FAILED;
3560 if (NULL == g_deviceListMutex)
3562 g_deviceListMutex = ca_mutex_new();
3563 if (NULL == g_deviceListMutex)
3565 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3566 return CA_STATUS_FAILED;
3570 if (NULL == g_gattObjectMutex)
3572 g_gattObjectMutex = ca_mutex_new();
3573 if (NULL == g_gattObjectMutex)
3575 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3576 return CA_STATUS_FAILED;
3580 if (NULL == g_deviceStateListMutex)
3582 g_deviceStateListMutex = ca_mutex_new();
3583 if (NULL == g_deviceStateListMutex)
3585 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3586 return CA_STATUS_FAILED;
3590 if (NULL == g_SendFinishMutex)
3592 g_SendFinishMutex = ca_mutex_new();
3593 if (NULL == g_SendFinishMutex)
3595 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3596 return CA_STATUS_FAILED;
3600 if (NULL == g_scanMutex)
3602 g_scanMutex = ca_mutex_new();
3603 if (NULL == g_scanMutex)
3605 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3606 return CA_STATUS_FAILED;
3610 if (NULL == g_threadWriteCharacteristicMutex)
3612 g_threadWriteCharacteristicMutex = ca_mutex_new();
3613 if (NULL == g_threadWriteCharacteristicMutex)
3615 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3616 return CA_STATUS_FAILED;
3620 return CA_STATUS_OK;
3623 void CALEClientTerminateGattMutexVariables()
3625 ca_mutex_free(g_bleReqRespClientCbMutex);
3626 g_bleReqRespClientCbMutex = NULL;
3628 ca_mutex_free(g_bleServerBDAddressMutex);
3629 g_bleServerBDAddressMutex = NULL;
3631 ca_mutex_free(g_threadMutex);
3632 g_threadMutex = NULL;
3634 ca_mutex_free(g_threadSendMutex);
3635 g_threadSendMutex = NULL;
3637 ca_mutex_free(g_deviceListMutex);
3638 g_deviceListMutex = NULL;
3640 ca_mutex_free(g_SendFinishMutex);
3641 g_SendFinishMutex = NULL;
3643 ca_mutex_free(g_scanMutex);
3646 ca_mutex_free(g_threadWriteCharacteristicMutex);
3647 g_threadWriteCharacteristicMutex = NULL;
3650 void CALEClientSetSendFinishFlag(bool flag)
3652 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3654 ca_mutex_lock(g_SendFinishMutex);
3655 g_isFinishedSendData = flag;
3656 ca_mutex_unlock(g_SendFinishMutex);
3663 CAResult_t CAStartLEGattClient()
3665 CAResult_t res = CALEClientStartMulticastServer();
3666 if (CA_STATUS_OK != res)
3668 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3672 g_isStartedLEClient = true;
3678 void CAStopLEGattClient()
3680 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3684 OIC_LOG(ERROR, TAG, "g_jvm is null");
3688 bool isAttached = false;
3690 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3693 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3694 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3698 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3704 CAResult_t ret = CALEClientDisconnectAll(env);
3705 if (CA_STATUS_OK != ret)
3707 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3710 ret = CALEClientStopScan();
3711 if(CA_STATUS_OK != ret)
3713 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3716 ca_mutex_lock(g_threadMutex);
3717 ca_cond_signal(g_threadCond);
3718 ca_mutex_unlock(g_threadMutex);
3720 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3721 ca_cond_signal(g_threadWriteCharacteristicCond);
3722 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3726 (*g_jvm)->DetachCurrentThread(g_jvm);
3731 CAResult_t CAInitializeLEGattClient()
3733 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3734 CALEClientInitialize();
3735 return CA_STATUS_OK;
3738 void CATerminateLEGattClient()
3740 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3741 CAStopLEGattClient();
3742 CALEClientTerminate();
3745 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3746 uint32_t dataLen, CALETransferType_t type,
3749 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3750 VERIFY_NON_NULL(data, TAG, "data is null");
3751 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3753 if (LE_UNICAST != type || position < 0)
3755 OIC_LOG(ERROR, TAG, "this request is not unicast");
3756 return CA_STATUS_INVALID_PARAM;
3759 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3762 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3764 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3765 VERIFY_NON_NULL(data, TAG, "data is null");
3767 return CALEClientSendMulticastMessage(data, dataLen);
3770 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3772 ca_mutex_lock(g_bleReqRespClientCbMutex);
3773 g_CABLEClientDataReceivedCallback = callback;
3774 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3777 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3779 g_threadPoolHandle = handle;
3782 CAResult_t CAGetLEAddress(char **local_address)
3784 VERIFY_NON_NULL(local_address, TAG, "local_address");
3785 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3786 return CA_NOT_SUPPORTED;
3789 JNIEXPORT void JNICALL
3790 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3793 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3794 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3795 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3796 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3798 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3801 JNIEXPORT void JNICALL
3802 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3805 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3806 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3807 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3808 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3810 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3813 JNIEXPORT void JNICALL
3814 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3817 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3818 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3819 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3821 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3822 if (CA_STATUS_OK != res)
3824 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3829 * Class: org_iotivity_ca_jar_caleinterface
3830 * Method: CALeGattConnectionStateChangeCallback
3831 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3833 JNIEXPORT void JNICALL
3834 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3840 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3842 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3843 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3844 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3846 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
3847 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
3848 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
3850 if (gatt_success == status && state_connected == newstate) // le connected
3852 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3858 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3861 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3862 STATE_CHARACTER_NO_CHANGE,
3864 if (CA_STATUS_OK != res)
3866 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3867 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3870 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
3872 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3875 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3876 if (CA_STATUS_OK != res)
3878 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3882 res = CALEClientDiscoverServices(env, gatt);
3883 if (CA_STATUS_OK != res)
3885 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3889 else if (GATT_ERROR == status && state_disconnected == newstate)
3891 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
3893 else // le disconnected
3895 CAResult_t res = CALEClientStartScan();
3896 if (CA_STATUS_OK != res)
3898 if (CA_ADAPTER_NOT_ENABLED == res)
3900 // scan will be started with start server when adapter is enabled
3901 OIC_LOG(INFO, TAG, "Adapter was disabled");
3905 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3910 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3913 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3917 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3920 res = CALEClientRemoveDeviceState(address);
3921 if (CA_STATUS_OK != res)
3923 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3927 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3930 res = CALEClientGattClose(env, gatt);
3931 if (CA_STATUS_OK != res)
3933 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3938 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3939 g_sendBuffer = NULL;
3947 CALEClientSendFinish(env, gatt);
3952 * Class: org_iotivity_ca_jar_caleinterface
3953 * Method: CALeGattServicesDiscoveredCallback
3954 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3956 JNIEXPORT void JNICALL
3957 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3962 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3963 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3964 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3965 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3967 if (0 != status) // discovery error
3969 CALEClientSendFinish(env, gatt);
3973 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3976 CALEClientSendFinish(env, gatt);
3980 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3983 CALEClientSendFinish(env, gatt);
3987 if (!CALEClientIsSetCharacteristic(address))
3989 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3992 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3996 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3997 if (!jni_obj_GattCharacteristic)
3999 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
4003 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
4004 jni_obj_GattCharacteristic);
4005 if (CA_STATUS_OK != res)
4007 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4011 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4012 if (CA_STATUS_OK != res)
4014 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4017 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4018 if (CA_STATUS_OK != res)
4020 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4026 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4028 if (CA_STATUS_OK != res)
4030 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4036 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4037 if (CA_STATUS_OK != res)
4039 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4043 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4044 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4049 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4050 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4051 CALEClientSendFinish(env, gatt);
4056 * Class: org_iotivity_ca_jar_caleinterface
4057 * Method: CALeGattCharacteristicWritjclasseCallback
4058 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4060 JNIEXPORT void JNICALL
4061 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4062 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4065 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4066 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4067 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4068 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4071 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
4073 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
4075 // send success & signal
4076 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4082 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4088 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4089 if (gatt_success != status) // error case
4091 OIC_LOG(ERROR, TAG, "send failure");
4094 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4095 if (CA_STATUS_OK != res)
4097 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4098 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4099 g_isSignalSetFlag = true;
4100 ca_cond_signal(g_threadWriteCharacteristicCond);
4101 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4103 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4104 STATE_CHARACTER_SET,
4106 if (CA_STATUS_OK != res)
4108 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4111 if (g_clientErrorCallback)
4113 jint length = (*env)->GetArrayLength(env, data);
4114 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4117 CALEClientSendFinish(env, gatt);
4123 OIC_LOG(DEBUG, TAG, "send success");
4124 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4125 STATE_SEND_SUCCESS);
4126 if (CA_STATUS_OK != res)
4128 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4131 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4132 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4133 g_isSignalSetFlag = true;
4134 ca_cond_signal(g_threadWriteCharacteristicCond);
4135 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4137 CALEClientUpdateSendCnt(env);
4140 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4146 CALEClientSendFinish(env, gatt);
4151 * Class: org_iotivity_ca_jar_caleinterface
4152 * Method: CALeGattCharacteristicChangedCallback
4153 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4155 JNIEXPORT void JNICALL
4156 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4157 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4159 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4160 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4161 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4162 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4163 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4165 // get Byte Array and convert to uint8_t*
4166 jint length = (*env)->GetArrayLength(env, data);
4169 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4171 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4172 jni_byte_responseData);
4174 uint8_t* receivedData = OICMalloc(length);
4177 OIC_LOG(ERROR, TAG, "receivedData is null");
4181 memcpy(receivedData, jni_byte_responseData, length);
4182 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4184 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4187 OIC_LOG(ERROR, TAG, "jni_address is null");
4188 OICFree(receivedData);
4192 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4195 OIC_LOG(ERROR, TAG, "address is null");
4196 OICFree(receivedData);
4200 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4201 receivedData, length);
4203 ca_mutex_lock(g_bleServerBDAddressMutex);
4204 uint32_t sentLength = 0;
4205 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4207 ca_mutex_unlock(g_bleServerBDAddressMutex);
4209 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4213 * Class: org_iotivity_ca_jar_caleinterface
4214 * Method: CALeGattDescriptorWriteCallback
4215 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4217 JNIEXPORT void JNICALL
4218 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4222 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4223 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4224 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4225 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4227 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4228 if (gatt_success != status) // error
4235 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4236 if (CA_STATUS_OK != res)
4238 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4247 CALEClientSendFinish(env, gatt);