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,
601 devicesDiscovered = true;
606 if (!devicesDiscovered)
608 return CA_STATUS_FAILED;
615 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
616 const uint32_t dataLen)
618 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
620 VERIFY_NON_NULL(address, TAG, "address is null");
621 VERIFY_NON_NULL(data, TAG, "data is null");
625 OIC_LOG(ERROR, TAG, "g_jvm is null");
626 return CA_STATUS_FAILED;
629 bool isAttached = false;
631 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
634 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
635 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
638 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
639 return CA_STATUS_FAILED;
644 ca_mutex_lock(g_threadSendMutex);
646 CALEClientSetSendFinishFlag(false);
648 CAResult_t ret = CALEClientIsThereScannedDevices();
649 if (CA_STATUS_OK != ret)
651 OIC_LOG(INFO, TAG, "there is no scanned device");
655 if (g_context && g_deviceList)
657 uint32_t length = u_arraylist_length(g_deviceList);
658 for (uint32_t index = 0; index < length; index++)
660 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
663 OIC_LOG(ERROR, TAG, "jarrayObj is null");
667 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
670 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
674 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
677 OIC_LOG(ERROR, TAG, "setAddress is null");
681 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
683 if (!strcmp(setAddress, address))
685 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
687 // connect to gatt server
688 ret = CALEClientStopScan();
689 if (CA_STATUS_OK != ret)
691 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
697 (*env)->DeleteGlobalRef(env, g_sendBuffer);
700 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
701 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
702 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
704 // Target device to send message is just one.
707 ret = CALEClientSendData(env, jarrayObj);
708 if (CA_STATUS_OK != ret)
710 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
714 OIC_LOG(INFO, TAG, "wake up");
717 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
721 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
723 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
724 // if there is no connection state.
725 if (!g_isFinishedSendData)
727 ca_mutex_lock(g_threadMutex);
728 ca_cond_wait(g_threadCond, g_threadMutex);
729 OIC_LOG(DEBUG, TAG, "the data was sent");
730 ca_mutex_unlock(g_threadMutex);
735 (*g_jvm)->DetachCurrentThread(g_jvm);
738 // start LE Scan again
739 ret = CALEClientStartScan();
740 if (CA_STATUS_OK != ret)
742 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
743 ca_mutex_unlock(g_threadSendMutex);
747 ca_mutex_unlock(g_threadSendMutex);
748 OIC_LOG(INFO, TAG, "unicast - send success");
754 // start LE Scan again
755 ret = CALEClientStartScan();
756 if (CA_STATUS_OK != ret)
758 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
759 ca_mutex_unlock(g_threadSendMutex);
762 (*g_jvm)->DetachCurrentThread(g_jvm);
769 (*g_jvm)->DetachCurrentThread(g_jvm);
772 if (g_clientErrorCallback)
774 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
776 ca_mutex_unlock(g_threadSendMutex);
777 return CA_SEND_FAILED;
780 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
781 const uint32_t dataLen)
783 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
784 VERIFY_NON_NULL(data, TAG, "data is null");
785 VERIFY_NON_NULL(env, TAG, "env is null");
789 OIC_LOG(ERROR, TAG, "g_deviceList is null");
790 return CA_STATUS_FAILED;
793 ca_mutex_lock(g_threadSendMutex);
795 CALEClientSetSendFinishFlag(false);
797 OIC_LOG(DEBUG, TAG, "set byteArray for data");
800 (*env)->DeleteGlobalRef(env, g_sendBuffer);
804 CAResult_t res = CALEClientIsThereScannedDevices();
805 if (CA_STATUS_OK != res)
807 OIC_LOG(INFO, TAG, "there is no scanned device");
811 // connect to gatt server
812 res = CALEClientStopScan();
813 if (CA_STATUS_OK != res)
815 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
816 ca_mutex_unlock(g_threadSendMutex);
819 uint32_t length = u_arraylist_length(g_deviceList);
820 g_targetCnt = length;
822 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
823 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
824 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
826 for (uint32_t index = 0; index < length; index++)
828 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
831 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
835 res = CALEClientSendData(env, jarrayObj);
836 if (res != CA_STATUS_OK)
838 OIC_LOG(ERROR, TAG, "BT device - send has failed");
841 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
844 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
848 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
851 OIC_LOG(ERROR, TAG, "address is not available");
855 (*env)->ReleaseStringUTFChars(env, jni_address, address);
858 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
860 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
861 if (!g_isFinishedSendData)
863 ca_mutex_lock(g_threadMutex);
864 ca_cond_wait(g_threadCond, g_threadMutex);
865 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
866 ca_mutex_unlock(g_threadMutex);
869 // start LE Scan again
870 res = CALEClientStartScan();
871 if (CA_STATUS_OK != res)
873 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
874 ca_mutex_unlock(g_threadSendMutex);
878 ca_mutex_unlock(g_threadSendMutex);
879 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
883 res = CALEClientStartScan();
884 if (CA_STATUS_OK != res)
886 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
887 ca_mutex_unlock(g_threadSendMutex);
891 ca_mutex_unlock(g_threadSendMutex);
892 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
893 return CA_SEND_FAILED;
896 CAResult_t CALECheckSendState(const char* address)
898 VERIFY_NON_NULL(address, TAG, "address is null");
900 ca_mutex_lock(g_deviceStateListMutex);
901 CALEState_t* state = CALEClientGetStateInfo(address);
904 OIC_LOG(ERROR, TAG, "state is null");
905 ca_mutex_unlock(g_deviceStateListMutex);
906 return CA_SEND_FAILED;
909 if (STATE_SEND_SUCCESS != state->sendState)
911 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
912 ca_mutex_unlock(g_deviceStateListMutex);
913 return CA_SEND_FAILED;
915 ca_mutex_unlock(g_deviceStateListMutex);
919 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
921 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
922 VERIFY_NON_NULL(device, TAG, "device is null");
923 VERIFY_NON_NULL(env, TAG, "env is null");
925 // get BLE address from bluetooth device object.
926 char* address = NULL;
927 CALEState_t* state = NULL;
928 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, device);
931 OIC_LOG(INFO, TAG, "there is gatt object..it's not first connection");
932 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
935 OIC_LOG(ERROR, TAG, "address is not available");
936 return CA_STATUS_FAILED;
938 ca_mutex_lock(g_deviceStateListMutex);
939 state = CALEClientGetStateInfo(address);
940 ca_mutex_unlock(g_deviceStateListMutex);
941 (*env)->ReleaseStringUTFChars(env, jni_address, address);
946 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
948 // cancel previous connection request before connection
949 // if there is gatt object in g_gattObjectList.
952 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
955 OIC_LOG(ERROR, TAG, "address is not available");
956 return CA_STATUS_FAILED;
959 jobject gatt = CALEClientGetGattObjInList(env, address);
962 CAResult_t res = CALEClientDisconnect(env, gatt);
963 if (CA_STATUS_OK != res)
965 OIC_LOG(INFO, TAG, "there is no gatt object");
968 (*env)->ReleaseStringUTFChars(env, jni_address, address);
971 // connection request
972 jobject newGatt = CALEClientConnect(env, device, JNI_TRUE);
975 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
976 return CA_STATUS_FAILED;
981 if (STATE_CONNECTED == state->connectedState)
983 OIC_LOG(INFO, TAG, "GATT has already connected");
986 OIC_LOG(ERROR, TAG, "jni_address is not available");
987 return CA_STATUS_FAILED;
990 address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
993 OIC_LOG(ERROR, TAG, "address is not available");
994 return CA_STATUS_FAILED;
997 jobject gatt = CALEClientGetGattObjInList(env, address);
1000 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1001 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1002 return CA_STATUS_FAILED;
1005 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1006 if (CA_STATUS_OK != ret)
1008 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1009 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1012 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1016 OIC_LOG(DEBUG, TAG, "start to connect LE");
1017 jobject gatt = CALEClientConnect(env, device, JNI_TRUE);
1020 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
1021 return CA_STATUS_FAILED;
1026 return CA_STATUS_OK;
1029 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
1031 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
1032 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1034 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1035 if (!jni_cid_gattdevice_list)
1037 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
1041 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
1042 "()Landroid/bluetooth/BluetoothDevice;");
1043 if (!jni_mid_getDevice)
1045 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
1049 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
1050 if (!jni_obj_device)
1052 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
1056 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
1059 OIC_LOG(ERROR, TAG, "jni_address is null");
1069 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
1072 OIC_LOG(DEBUG, TAG, "Gatt Close");
1073 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1074 VERIFY_NON_NULL(env, TAG, "env is null");
1076 // get BluetoothGatt class
1077 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1078 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1079 if (!jni_cid_BluetoothGatt)
1081 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1082 return CA_STATUS_FAILED;
1085 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1086 if (!jni_mid_closeGatt)
1088 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1089 return CA_STATUS_OK;
1092 // call disconnect gatt method
1093 OIC_LOG(DEBUG, TAG, "request to close GATT");
1094 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
1096 if ((*env)->ExceptionCheck(env))
1098 OIC_LOG(ERROR, TAG, "closeGATT has failed");
1099 (*env)->ExceptionDescribe(env);
1100 (*env)->ExceptionClear(env);
1101 return CA_STATUS_FAILED;
1104 return CA_STATUS_OK;
1107 CAResult_t CALEClientStartScan()
1109 if (!g_isStartedMulticastServer)
1111 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
1112 return CA_STATUS_FAILED;
1115 if (!g_isStartedLEClient)
1117 OIC_LOG(ERROR, TAG, "LE client is not started");
1118 return CA_STATUS_FAILED;
1123 OIC_LOG(ERROR, TAG, "g_jvm is null");
1124 return CA_STATUS_FAILED;
1127 if (g_isStartedScan)
1129 OIC_LOG(INFO, TAG, "scanning is already started");
1130 return CA_STATUS_OK;
1133 bool isAttached = false;
1135 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1138 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1140 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1143 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1144 return CA_STATUS_FAILED;
1149 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1151 CAResult_t ret = CA_STATUS_OK;
1152 // scan gatt server with UUID
1153 if (g_leScanCallback && g_uuidList)
1156 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1158 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1160 if (CA_STATUS_OK != ret)
1162 if (CA_ADAPTER_NOT_ENABLED == ret)
1164 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1168 OIC_LOG(ERROR, TAG, "start scan has failed");
1175 (*g_jvm)->DetachCurrentThread(g_jvm);
1181 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1183 VERIFY_NON_NULL(callback, TAG, "callback is null");
1184 VERIFY_NON_NULL(env, TAG, "env is null");
1186 if (!CALEIsEnableBTAdapter(env))
1188 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1189 return CA_ADAPTER_NOT_ENABLED;
1192 // get default bt adapter class
1193 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1194 if (!jni_cid_BTAdapter)
1196 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1197 return CA_STATUS_FAILED;
1200 // get remote bt adapter method
1201 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1202 "getDefaultAdapter",
1203 METHODID_OBJECTNONPARAM);
1204 if (!jni_mid_getDefaultAdapter)
1206 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1207 return CA_STATUS_FAILED;
1210 // get start le scan method
1211 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1212 "(Landroid/bluetooth/BluetoothAdapter$"
1213 "LeScanCallback;)Z");
1214 if (!jni_mid_startLeScan)
1216 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1217 return CA_STATUS_FAILED;
1220 // gat bt adapter object
1221 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1222 jni_mid_getDefaultAdapter);
1223 if (!jni_obj_BTAdapter)
1225 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1226 return CA_STATUS_FAILED;
1229 // call start le scan method
1230 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1231 jni_mid_startLeScan, callback);
1232 if (!jni_obj_startLeScan)
1234 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1235 return CA_STATUS_FAILED;
1239 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1240 CALEClientSetScanFlag(true);
1243 return CA_STATUS_OK;
1246 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1248 VERIFY_NON_NULL(callback, TAG, "callback is null");
1249 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1250 VERIFY_NON_NULL(env, TAG, "env is null");
1252 if (!CALEIsEnableBTAdapter(env))
1254 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1255 return CA_ADAPTER_NOT_ENABLED;
1258 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1259 if (!jni_cid_BTAdapter)
1261 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1262 return CA_STATUS_FAILED;
1265 // get remote bt adapter method
1266 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1267 "getDefaultAdapter",
1268 METHODID_OBJECTNONPARAM);
1269 if (!jni_mid_getDefaultAdapter)
1271 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1272 return CA_STATUS_FAILED;
1275 // get start le scan method
1276 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1277 "([Ljava/util/UUID;Landroid/bluetooth/"
1278 "BluetoothAdapter$LeScanCallback;)Z");
1279 if (!jni_mid_startLeScan)
1281 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1282 return CA_STATUS_FAILED;
1285 // get bt adapter object
1286 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1287 jni_mid_getDefaultAdapter);
1288 if (!jni_obj_BTAdapter)
1290 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1291 return CA_STATUS_FAILED;
1294 // call start le scan method
1295 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1296 jni_mid_startLeScan, uuids, callback);
1297 if (!jni_obj_startLeScan)
1299 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1300 return CA_STATUS_FAILED;
1304 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1305 CALEClientSetScanFlag(true);
1308 return CA_STATUS_OK;
1311 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1313 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1314 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1317 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1320 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1324 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1325 "(Ljava/lang/String;)"
1326 "Ljava/util/UUID;");
1327 if (!jni_mid_fromString)
1329 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1333 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1334 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1338 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1342 return jni_obj_uuid;
1345 CAResult_t CALEClientStopScan()
1349 OIC_LOG(ERROR, TAG, "g_jvm is null");
1350 return CA_STATUS_FAILED;
1353 if (!g_isStartedScan)
1355 OIC_LOG(INFO, TAG, "scanning is already stopped");
1356 return CA_STATUS_OK;
1359 bool isAttached = false;
1361 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1364 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1365 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1368 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1369 return CA_STATUS_FAILED;
1374 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1375 if (CA_STATUS_OK != ret)
1377 if (CA_ADAPTER_NOT_ENABLED == ret)
1379 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1383 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1388 CALEClientSetScanFlag(false);
1393 (*g_jvm)->DetachCurrentThread(g_jvm);
1399 void CALEClientSetScanFlag(bool flag)
1401 ca_mutex_lock(g_scanMutex);
1402 g_isStartedScan = flag;
1403 ca_mutex_unlock(g_scanMutex);
1406 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1408 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1409 VERIFY_NON_NULL(callback, TAG, "callback is null");
1410 VERIFY_NON_NULL(env, TAG, "env is null");
1412 if (!CALEIsEnableBTAdapter(env))
1414 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1415 return CA_ADAPTER_NOT_ENABLED;
1418 // get default bt adapter class
1419 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1420 if (!jni_cid_BTAdapter)
1422 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1423 return CA_STATUS_FAILED;
1426 // get remote bt adapter method
1427 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1428 "getDefaultAdapter",
1429 METHODID_OBJECTNONPARAM);
1430 if (!jni_mid_getDefaultAdapter)
1432 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1433 return CA_STATUS_FAILED;
1436 // get start le scan method
1437 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1438 "(Landroid/bluetooth/"
1439 "BluetoothAdapter$LeScanCallback;)V");
1440 if (!jni_mid_stopLeScan)
1442 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1443 return CA_STATUS_FAILED;
1446 // gat bt adapter object
1447 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1448 jni_mid_getDefaultAdapter);
1449 if (!jni_obj_BTAdapter)
1451 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1452 return CA_STATUS_FAILED;
1455 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1456 // call start le scan method
1457 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1458 if ((*env)->ExceptionCheck(env))
1460 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1461 (*env)->ExceptionDescribe(env);
1462 (*env)->ExceptionClear(env);
1463 return CA_STATUS_FAILED;
1466 return CA_STATUS_OK;
1469 jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1471 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1472 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1473 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1475 // get gatt object from Bluetooth Device object for closeProfileProxy(..)
1476 jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
1479 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1482 OIC_LOG(ERROR, TAG, "address is not available");
1486 // close the gatt service
1487 jobject gatt = CALEClientGetGattObjInList(env, address);
1490 CAResult_t res = CALEClientCloseProfileProxy(env, gatt);
1491 if (CA_STATUS_OK != res)
1493 OIC_LOG(ERROR, TAG, "CALEClientCloseProfileProxy has failed");
1494 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1498 // clean previous gatt object after close profile service
1499 res = CALEClientRemoveGattObjForAddr(env, jni_address);
1500 if (CA_STATUS_OK != res)
1502 OIC_LOG(ERROR, TAG, "CALEClientRemoveGattObjForAddr has failed");
1503 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1507 (*env)->ReleaseStringUTFChars(env, jni_address, address);
1510 jobject newGatt = CALEClientGattConnect(env, bluetoothDevice, autoconnect);
1513 OIC_LOG(DEBUG, TAG, "re-connection will be started");
1517 // add new gatt object into g_gattObjectList
1518 CAResult_t res = CALEClientAddGattobjToList(env, newGatt);
1519 if (CA_STATUS_OK != res)
1521 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
1528 jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
1530 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1531 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1532 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice is null", NULL);
1534 if (!CALEIsEnableBTAdapter(env))
1536 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1540 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1543 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1547 // get BluetoothDevice class
1548 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1549 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1550 if (!jni_cid_BluetoothDevice)
1552 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1556 // get connectGatt method
1557 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1558 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1559 "(Landroid/content/Context;ZLandroid/"
1560 "bluetooth/BluetoothGattCallback;)"
1561 "Landroid/bluetooth/BluetoothGatt;");
1562 if (!jni_mid_connectGatt)
1564 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1568 OIC_LOG(INFO, TAG, "CALL API - connectGatt");
1569 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1570 jni_mid_connectGatt,
1572 autoconnect, g_leGattCallback);
1573 if (!jni_obj_connectGatt)
1575 OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
1576 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1577 CALEClientUpdateSendCnt(env);
1582 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1584 return jni_obj_connectGatt;
1587 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
1589 OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
1591 VERIFY_NON_NULL(env, TAG, "env is null");
1592 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1594 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1595 if (!jni_cid_BTAdapter)
1597 OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
1598 return CA_STATUS_FAILED;
1601 // get remote bt adapter method
1602 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1603 "getDefaultAdapter",
1604 METHODID_OBJECTNONPARAM);
1605 if (!jni_mid_getDefaultAdapter)
1607 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1608 return CA_STATUS_FAILED;
1611 // gat bt adapter object
1612 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1613 jni_mid_getDefaultAdapter);
1614 if (!jni_obj_BTAdapter)
1616 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1617 return CA_STATUS_FAILED;
1620 // get closeProfileProxy method
1621 jmethodID jni_mid_closeProfileProxy = (*env)->GetMethodID(env, jni_cid_BTAdapter,
1622 "closeProfileProxy",
1623 "(ILandroid/bluetooth/"
1624 "BluetoothProfile;)V");
1625 if (!jni_mid_closeProfileProxy)
1627 OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
1628 return CA_STATUS_FAILED;
1631 jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
1632 if (!jni_cid_BTProfile)
1634 OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
1635 return CA_STATUS_FAILED;
1638 // GATT - Constant value : 7 (0x00000007)
1639 jfieldID id_gatt = (*env)->GetStaticFieldID(env, jni_cid_BTProfile,
1643 OIC_LOG(ERROR, TAG, "id_gatt is null");
1644 return CA_STATUS_FAILED;
1647 jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
1649 OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
1650 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
1651 if ((*env)->ExceptionCheck(env))
1653 OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
1654 (*env)->ExceptionDescribe(env);
1655 (*env)->ExceptionClear(env);
1656 return CA_STATUS_FAILED;
1659 OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
1660 return CA_STATUS_OK;
1664 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1666 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1667 VERIFY_NON_NULL(env, TAG, "env is null");
1668 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1670 // get BluetoothGatt class
1671 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1672 if (!jni_cid_BluetoothGatt)
1674 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1675 return CA_STATUS_FAILED;
1678 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1679 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1680 "disconnect", "()V");
1681 if (!jni_mid_disconnectGatt)
1683 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1684 return CA_STATUS_FAILED;
1687 // call disconnect gatt method
1688 OIC_LOG(DEBUG, TAG, "CALL API - request disconnect gatt");
1689 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1690 if ((*env)->ExceptionCheck(env))
1692 OIC_LOG(ERROR, TAG, "disconnect has failed");
1693 (*env)->ExceptionDescribe(env);
1694 (*env)->ExceptionClear(env);
1695 return CA_STATUS_FAILED;
1698 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1700 return CA_STATUS_OK;
1703 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1705 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1706 VERIFY_NON_NULL(env, TAG, "env is null");
1708 if (!g_gattObjectList)
1710 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1711 return CA_STATUS_OK;
1714 uint32_t length = u_arraylist_length(g_gattObjectList);
1715 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1716 for (uint32_t index = 0; index < length; index++)
1718 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1719 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1722 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1725 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1726 if (CA_STATUS_OK != res)
1728 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1733 return CA_STATUS_OK;
1736 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
1738 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1739 VERIFY_NON_NULL(env, TAG, "env is null");
1741 if (!g_gattObjectList)
1743 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1744 return CA_STATUS_OK;
1747 char* address = (char*)(*env)->GetStringUTFChars(env, remote_address, NULL);
1750 OIC_LOG(ERROR, TAG, "address is null");
1751 return CA_STATUS_FAILED;
1754 uint32_t length = u_arraylist_length(g_gattObjectList);
1755 for (uint32_t index = 0; index < length; index++)
1757 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1760 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1764 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
1765 if (!jni_setAddress)
1767 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1768 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1769 return CA_STATUS_FAILED;
1772 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1775 OIC_LOG(ERROR, TAG, "setAddress is null");
1776 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1777 return CA_STATUS_FAILED;
1780 OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
1781 if (!strcmp(address, setAddress))
1783 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1784 if (CA_STATUS_OK != res)
1786 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1787 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1788 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1789 return CA_STATUS_FAILED;
1791 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1792 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1793 return CA_STATUS_OK;
1795 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1797 (*env)->ReleaseStringUTFChars(env, remote_address, address);
1799 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1800 return CA_STATUS_OK;
1803 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1805 VERIFY_NON_NULL(env, TAG, "env is null");
1806 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1808 if (!CALEIsEnableBTAdapter(env))
1810 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1811 return CA_ADAPTER_NOT_ENABLED;
1814 // get BluetoothGatt class
1815 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1816 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1817 if (!jni_cid_BluetoothGatt)
1819 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1820 return CA_STATUS_FAILED;
1823 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1824 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1825 "discoverServices", "()Z");
1826 if (!jni_mid_discoverServices)
1828 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1829 return CA_STATUS_FAILED;
1831 // call disconnect gatt method
1832 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1833 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1836 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1837 return CA_STATUS_FAILED;
1840 return CA_STATUS_OK;
1843 static void CALEWriteCharacteristicThread(void* object)
1845 VERIFY_NON_NULL_VOID(object, TAG, "object is null");
1847 bool isAttached = false;
1849 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1852 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1853 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1857 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1863 jobject gatt = (jobject)object;
1864 CAResult_t ret = CALESetValueAndWriteCharacteristic(env, gatt);
1865 if (CA_STATUS_OK != ret)
1867 OIC_LOG(ERROR, TAG, "CALESetValueAndWriteCharacteristic has failed");
1872 (*g_jvm)->DetachCurrentThread(g_jvm);
1876 CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
1878 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1879 VERIFY_NON_NULL(env, TAG, "env is null");
1882 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1883 if (!jni_obj_character)
1885 CALEClientSendFinish(env, gatt);
1886 return CA_STATUS_FAILED;
1889 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1890 if (CA_STATUS_OK != ret)
1892 CALEClientSendFinish(env, gatt);
1893 return CA_STATUS_FAILED;
1896 // wait for callback for write Characteristic with success to sent data
1897 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1898 ca_mutex_lock(g_threadWriteCharacteristicMutex);
1899 if (!g_isSignalSetFlag)
1901 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1902 if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
1903 g_threadWriteCharacteristicMutex,
1904 WAIT_TIME_WRITE_CHARACTERISTIC))
1906 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1907 g_isSignalSetFlag = false;
1908 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1909 return CA_STATUS_FAILED;
1912 // reset flag set by writeCharacteristic Callback
1913 g_isSignalSetFlag = false;
1914 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
1916 OIC_LOG(INFO, TAG, "writeCharacteristic success!!");
1917 return CA_STATUS_OK;
1920 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1922 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
1923 VERIFY_NON_NULL(env, TAG, "env is null");
1924 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1926 jobject gattParam = (*env)->NewGlobalRef(env, gatt);
1927 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
1928 CALEWriteCharacteristicThread, (void*)gattParam))
1930 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
1931 return CA_STATUS_FAILED;
1934 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
1935 return CA_STATUS_OK;
1938 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1939 jobject gattCharacteristic)
1941 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1942 VERIFY_NON_NULL(env, TAG, "env is null");
1943 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1944 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1946 if (!CALEIsEnableBTAdapter(env))
1948 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1949 return CA_STATUS_FAILED;
1952 // get BluetoothGatt class
1953 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1954 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1955 if (!jni_cid_BluetoothGatt)
1957 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1958 return CA_STATUS_FAILED;
1961 OIC_LOG(DEBUG, TAG, "write characteristic method");
1962 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1963 "writeCharacteristic",
1964 "(Landroid/bluetooth/"
1965 "BluetoothGattCharacteristic;)Z");
1966 if (!jni_mid_writeCharacteristic)
1968 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1969 return CA_STATUS_FAILED;
1972 // call disconnect gatt method
1973 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1974 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1975 jni_mid_writeCharacteristic,
1976 gattCharacteristic);
1979 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
1983 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1984 return CA_STATUS_FAILED;
1987 return CA_STATUS_OK;
1990 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1992 VERIFY_NON_NULL(env, TAG, "env is null");
1993 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1995 if (!CALEIsEnableBTAdapter(env))
1997 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1998 return CA_STATUS_FAILED;
2001 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2002 if (!jni_cid_BluetoothGatt)
2004 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2005 return CA_STATUS_FAILED;
2008 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
2011 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2012 return CA_STATUS_FAILED;
2015 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2016 if (!jni_obj_GattCharacteristic)
2018 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2019 return CA_STATUS_FAILED;
2022 OIC_LOG(DEBUG, TAG, "read characteristic method");
2023 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2024 "readCharacteristic",
2025 "(Landroid/bluetooth/"
2026 "BluetoothGattCharacteristic;)Z");
2027 if (!jni_mid_readCharacteristic)
2029 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
2030 return CA_STATUS_FAILED;
2033 // call disconnect gatt method
2034 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
2035 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
2036 jni_obj_GattCharacteristic);
2039 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
2043 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
2044 return CA_STATUS_FAILED;
2047 return CA_STATUS_OK;
2050 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
2051 jobject characteristic)
2053 VERIFY_NON_NULL(env, TAG, "env is null");
2054 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2055 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2057 if (!CALEIsEnableBTAdapter(env))
2059 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2060 return CA_ADAPTER_NOT_ENABLED;
2063 // get BluetoothGatt class
2064 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
2065 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2066 if (!jni_cid_BluetoothGatt)
2068 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2069 return CA_STATUS_FAILED;
2072 // set Characteristic Notification
2073 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
2074 "setCharacteristicNotification",
2075 "(Landroid/bluetooth/"
2076 "BluetoothGattCharacteristic;Z)Z");
2077 if (!jni_mid_setNotification)
2079 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2080 return CA_STATUS_FAILED;
2083 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
2084 characteristic, JNI_TRUE);
2085 if (JNI_TRUE == ret)
2087 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
2091 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
2092 return CA_STATUS_FAILED;
2095 return CA_STATUS_OK;
2098 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
2100 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2101 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2102 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
2104 if (!CALEIsEnableBTAdapter(env))
2106 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2110 // get BluetoothGatt class
2111 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
2112 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
2113 if (!jni_cid_BluetoothGatt)
2115 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
2119 jmethodID jni_mid_getService = (*env)->GetMethodID(
2120 env, jni_cid_BluetoothGatt, "getService",
2121 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
2122 if (!jni_mid_getService)
2124 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
2128 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2129 if (!jni_obj_service_uuid)
2131 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
2135 // get bluetooth gatt service
2136 OIC_LOG(DEBUG, TAG, "request to get service");
2137 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
2138 jni_obj_service_uuid);
2139 if (!jni_obj_gattService)
2141 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
2145 // get bluetooth gatt service class
2146 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
2147 env, "android/bluetooth/BluetoothGattService");
2148 if (!jni_cid_BluetoothGattService)
2150 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
2154 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
2155 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
2156 "getCharacteristic",
2157 "(Ljava/util/UUID;)"
2158 "Landroid/bluetooth/"
2159 "BluetoothGattCharacteristic;");
2160 if (!jni_mid_getCharacteristic)
2162 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
2166 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
2169 OIC_LOG(ERROR, TAG, "uuid is null");
2173 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
2174 if (!jni_obj_tx_uuid)
2176 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
2177 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2181 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
2182 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
2183 jni_mid_getCharacteristic,
2186 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
2187 return jni_obj_GattCharacteristic;
2190 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
2192 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
2193 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2194 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
2195 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
2197 if (!CALEIsEnableBTAdapter(env))
2199 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2203 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
2206 OIC_LOG(ERROR, TAG, "jni_uuid is null");
2210 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
2211 if (!jni_obj_GattCharacteristic)
2213 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
2217 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
2218 "/BluetoothGattCharacteristic");
2219 if (!jni_cid_BTGattCharacteristic)
2221 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2225 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2226 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
2228 if (!jni_mid_setValue)
2230 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2234 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
2236 if (JNI_TRUE == ret)
2238 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
2242 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
2247 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2248 "setWriteType", "(I)V");
2249 if (!jni_mid_setWriteType)
2251 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
2255 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
2256 "WRITE_TYPE_NO_RESPONSE", "I");
2257 if (!jni_fid_no_response)
2259 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
2263 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
2264 jni_fid_no_response);
2266 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
2268 return jni_obj_GattCharacteristic;
2271 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
2273 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
2274 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2276 if (!CALEIsEnableBTAdapter(env))
2278 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2282 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2283 "BluetoothGattCharacteristic");
2284 if (!jni_cid_BTGattCharacteristic)
2286 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2290 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
2291 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
2293 if (!jni_mid_getValue)
2295 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
2299 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
2301 return jni_obj_data_array;
2304 CAResult_t CALEClientCreateUUIDList()
2308 OIC_LOG(ERROR, TAG, "g_jvm is null");
2309 return CA_STATUS_FAILED;
2312 bool isAttached = false;
2314 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
2317 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
2318 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
2322 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
2323 return CA_STATUS_FAILED;
2328 // create new object array
2329 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
2330 if (!jni_cid_uuid_list)
2332 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
2336 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
2337 jni_cid_uuid_list, NULL);
2338 if (!jni_obj_uuid_list)
2340 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
2345 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
2348 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
2351 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
2353 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
2357 (*g_jvm)->DetachCurrentThread(g_jvm);
2360 return CA_STATUS_OK;
2367 (*g_jvm)->DetachCurrentThread(g_jvm);
2369 return CA_STATUS_FAILED;
2372 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
2373 jobject characteristic)
2375 VERIFY_NON_NULL(env, TAG, "env is null");
2376 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
2377 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
2379 if (!CALEIsEnableBTAdapter(env))
2381 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
2382 return CA_ADAPTER_NOT_ENABLED;
2385 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
2386 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
2387 "BluetoothGattCharacteristic");
2388 if (!jni_cid_BTGattCharacteristic)
2390 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
2391 return CA_STATUS_FAILED;
2394 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
2395 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
2397 "(Ljava/util/UUID;)Landroid/bluetooth/"
2398 "BluetoothGattDescriptor;");
2399 if (!jni_mid_getDescriptor)
2401 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
2402 return CA_STATUS_FAILED;
2405 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
2406 if (!jni_obj_cc_uuid)
2408 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
2409 return CA_STATUS_FAILED;
2412 OIC_LOG(DEBUG, TAG, "request to get descriptor");
2413 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
2414 jni_mid_getDescriptor, jni_obj_cc_uuid);
2415 if (!jni_obj_descriptor)
2417 OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
2418 return CA_NOT_SUPPORTED;
2421 OIC_LOG(DEBUG, TAG, "set value in descriptor");
2422 jclass jni_cid_descriptor = (*env)->FindClass(env,
2423 "android/bluetooth/BluetoothGattDescriptor");
2424 if (!jni_cid_descriptor)
2426 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
2427 return CA_STATUS_FAILED;
2430 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2431 if (!jni_mid_setValue)
2433 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2434 return CA_STATUS_FAILED;
2437 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2438 "ENABLE_NOTIFICATION_VALUE", "[B");
2439 if (!jni_fid_NotiValue)
2441 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2442 return CA_STATUS_FAILED;
2445 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2447 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2448 env, jni_obj_descriptor, jni_mid_setValue,
2449 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2452 OIC_LOG(DEBUG, TAG, "setValue success");
2456 OIC_LOG(ERROR, TAG, "setValue has failed");
2457 return CA_STATUS_FAILED;
2460 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2463 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2464 return CA_STATUS_FAILED;
2467 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2468 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2469 "(Landroid/bluetooth/"
2470 "BluetoothGattDescriptor;)Z");
2471 if (!jni_mid_writeDescriptor)
2473 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2474 return CA_STATUS_FAILED;
2477 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2478 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2479 jni_obj_descriptor);
2482 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2486 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2487 return CA_STATUS_FAILED;
2490 return CA_STATUS_OK;
2493 void CALEClientCreateScanDeviceList(JNIEnv *env)
2495 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2496 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2498 ca_mutex_lock(g_deviceListMutex);
2499 // create new object array
2500 if (g_deviceList == NULL)
2502 OIC_LOG(DEBUG, TAG, "Create device list");
2504 g_deviceList = u_arraylist_create();
2506 ca_mutex_unlock(g_deviceListMutex);
2509 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2511 VERIFY_NON_NULL(device, TAG, "device is null");
2512 VERIFY_NON_NULL(env, TAG, "env is null");
2514 ca_mutex_lock(g_deviceListMutex);
2518 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2519 ca_mutex_unlock(g_deviceListMutex);
2520 return CA_STATUS_FAILED;
2523 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2524 if (!jni_remoteAddress)
2526 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2527 ca_mutex_unlock(g_deviceListMutex);
2528 return CA_STATUS_FAILED;
2531 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2534 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2535 ca_mutex_unlock(g_deviceListMutex);
2536 return CA_STATUS_FAILED;
2539 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2541 jobject gdevice = (*env)->NewGlobalRef(env, device);
2542 u_arraylist_add(g_deviceList, gdevice);
2543 ca_cond_signal(g_deviceDescCond);
2544 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
2546 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2548 ca_mutex_unlock(g_deviceListMutex);
2550 return CA_STATUS_OK;
2553 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2555 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2556 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2560 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2564 uint32_t length = u_arraylist_length(g_deviceList);
2565 for (uint32_t index = 0; index < length; index++)
2567 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2570 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2574 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2575 if (!jni_setAddress)
2577 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2581 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2584 OIC_LOG(ERROR, TAG, "setAddress is null");
2588 if (!strcmp(remoteAddress, setAddress))
2590 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2594 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2597 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2602 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2604 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2605 VERIFY_NON_NULL(env, TAG, "env is null");
2607 ca_mutex_lock(g_deviceListMutex);
2611 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2612 ca_mutex_unlock(g_deviceListMutex);
2613 return CA_STATUS_FAILED;
2616 uint32_t length = u_arraylist_length(g_deviceList);
2617 for (uint32_t index = 0; index < length; index++)
2619 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2622 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2625 (*env)->DeleteGlobalRef(env, jarrayObj);
2628 OICFree(g_deviceList);
2629 g_deviceList = NULL;
2631 ca_mutex_unlock(g_deviceListMutex);
2632 return CA_STATUS_OK;
2635 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2637 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2638 VERIFY_NON_NULL(address, TAG, "address is null");
2639 VERIFY_NON_NULL(env, TAG, "env is null");
2641 ca_mutex_lock(g_deviceListMutex);
2645 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2646 ca_mutex_unlock(g_deviceListMutex);
2647 return CA_STATUS_FAILED;
2650 uint32_t length = u_arraylist_length(g_deviceList);
2651 for (uint32_t index = 0; index < length; index++)
2653 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2656 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2657 ca_mutex_unlock(g_deviceListMutex);
2658 return CA_STATUS_FAILED;
2661 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2662 if (!jni_setAddress)
2664 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2665 ca_mutex_unlock(g_deviceListMutex);
2666 return CA_STATUS_FAILED;
2669 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2672 OIC_LOG(ERROR, TAG, "setAddress is null");
2673 ca_mutex_unlock(g_deviceListMutex);
2674 return CA_STATUS_FAILED;
2677 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2680 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2681 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2682 ca_mutex_unlock(g_deviceListMutex);
2683 return CA_STATUS_FAILED;
2686 if (!strcmp(setAddress, remoteAddress))
2688 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2689 (*env)->DeleteGlobalRef(env, jarrayObj);
2690 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2691 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2693 if (NULL == u_arraylist_remove(g_deviceList, index))
2695 OIC_LOG(ERROR, TAG, "List removal failed.");
2696 ca_mutex_unlock(g_deviceListMutex);
2697 return CA_STATUS_FAILED;
2699 ca_mutex_unlock(g_deviceListMutex);
2700 return CA_STATUS_OK;
2702 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2703 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2706 ca_mutex_unlock(g_deviceListMutex);
2707 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2709 return CA_STATUS_OK;
2716 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2718 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
2719 VERIFY_NON_NULL(env, TAG, "env is null");
2720 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2722 ca_mutex_lock(g_gattObjectMutex);
2724 if (!g_gattObjectList)
2726 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
2727 ca_mutex_unlock(g_gattObjectMutex);
2728 return CA_STATUS_FAILED;
2731 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2732 if (!jni_remoteAddress)
2734 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2735 ca_mutex_unlock(g_gattObjectMutex);
2736 return CA_STATUS_FAILED;
2739 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2742 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2743 ca_mutex_unlock(g_gattObjectMutex);
2744 return CA_STATUS_FAILED;
2747 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddress);
2748 if (!CALEClientIsGattObjInList(env, remoteAddress))
2750 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2751 u_arraylist_add(g_gattObjectList, newGatt);
2752 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2755 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2756 ca_mutex_unlock(g_gattObjectMutex);
2757 return CA_STATUS_OK;
2760 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2762 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2763 VERIFY_NON_NULL(env, TAG, "env is null");
2764 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2766 uint32_t length = u_arraylist_length(g_gattObjectList);
2767 for (uint32_t index = 0; index < length; index++)
2770 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2773 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2777 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2778 if (!jni_setAddress)
2780 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2784 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2787 OIC_LOG(ERROR, TAG, "setAddress is null");
2791 if (!strcmp(remoteAddress, setAddress))
2793 OIC_LOG(DEBUG, TAG, "the device is already set");
2794 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2799 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2804 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2808 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2810 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2811 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2812 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2814 ca_mutex_lock(g_gattObjectMutex);
2815 uint32_t length = u_arraylist_length(g_gattObjectList);
2816 for (uint32_t index = 0; index < length; index++)
2818 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2821 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2822 ca_mutex_unlock(g_gattObjectMutex);
2826 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2827 if (!jni_setAddress)
2829 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2830 ca_mutex_unlock(g_gattObjectMutex);
2834 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2837 OIC_LOG(ERROR, TAG, "setAddress is null");
2838 ca_mutex_unlock(g_gattObjectMutex);
2842 if (!strcmp(remoteAddress, setAddress))
2844 OIC_LOG(DEBUG, TAG, "the device is already set");
2845 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2846 ca_mutex_unlock(g_gattObjectMutex);
2849 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2852 ca_mutex_unlock(g_gattObjectMutex);
2853 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2857 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2859 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2860 VERIFY_NON_NULL(env, TAG, "env is null");
2862 ca_mutex_lock(g_gattObjectMutex);
2863 if (!g_gattObjectList)
2865 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2866 ca_mutex_unlock(g_gattObjectMutex);
2867 return CA_STATUS_OK;
2870 uint32_t length = u_arraylist_length(g_gattObjectList);
2871 for (uint32_t index = 0; index < length; index++)
2873 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2876 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2879 (*env)->DeleteGlobalRef(env, jarrayObj);
2882 OICFree(g_gattObjectList);
2883 g_gattObjectList = NULL;
2884 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2885 ca_mutex_unlock(g_gattObjectMutex);
2886 return CA_STATUS_OK;
2889 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2891 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2892 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2893 VERIFY_NON_NULL(env, TAG, "env is null");
2895 ca_mutex_lock(g_gattObjectMutex);
2896 if (!g_gattObjectList)
2898 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2899 ca_mutex_unlock(g_gattObjectMutex);
2900 return CA_STATUS_OK;
2903 uint32_t length = u_arraylist_length(g_gattObjectList);
2904 for (uint32_t index = 0; index < length; index++)
2906 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2909 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2910 ca_mutex_unlock(g_gattObjectMutex);
2911 return CA_STATUS_FAILED;
2914 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2915 if (!jni_setAddress)
2917 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2918 ca_mutex_unlock(g_gattObjectMutex);
2919 return CA_STATUS_FAILED;
2922 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2925 OIC_LOG(ERROR, TAG, "setAddress is null");
2926 ca_mutex_unlock(g_gattObjectMutex);
2927 return CA_STATUS_FAILED;
2930 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2931 if (!jni_remoteAddress)
2933 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2934 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2935 ca_mutex_unlock(g_gattObjectMutex);
2936 return CA_STATUS_FAILED;
2939 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2942 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2943 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2944 ca_mutex_unlock(g_gattObjectMutex);
2945 return CA_STATUS_FAILED;
2948 if (!strcmp(setAddress, remoteAddress))
2950 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2951 (*env)->DeleteGlobalRef(env, jarrayObj);
2952 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2953 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2955 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2957 OIC_LOG(ERROR, TAG, "List removal failed.");
2958 ca_mutex_unlock(g_gattObjectMutex);
2959 return CA_STATUS_FAILED;
2961 ca_mutex_unlock(g_gattObjectMutex);
2962 return CA_STATUS_OK;
2964 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2965 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2968 ca_mutex_unlock(g_gattObjectMutex);
2969 OIC_LOG(DEBUG, TAG, "there are no target object");
2970 return CA_STATUS_OK;
2973 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2975 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2976 VERIFY_NON_NULL(addr, TAG, "addr is null");
2977 VERIFY_NON_NULL(env, TAG, "env is null");
2979 ca_mutex_lock(g_gattObjectMutex);
2980 if (!g_gattObjectList)
2982 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2983 ca_mutex_unlock(g_gattObjectMutex);
2984 return CA_STATUS_OK;
2987 uint32_t length = u_arraylist_length(g_gattObjectList);
2988 for (uint32_t index = 0; index < length; index++)
2990 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2993 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2994 ca_mutex_unlock(g_gattObjectMutex);
2995 return CA_STATUS_FAILED;
2998 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2999 if (!jni_setAddress)
3001 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
3002 ca_mutex_unlock(g_gattObjectMutex);
3003 return CA_STATUS_FAILED;
3006 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
3009 OIC_LOG(ERROR, TAG, "setAddress is null");
3010 ca_mutex_unlock(g_gattObjectMutex);
3011 return CA_STATUS_FAILED;
3014 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
3017 OIC_LOG(ERROR, TAG, "remoteAddress is null");
3018 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3019 ca_mutex_unlock(g_gattObjectMutex);
3020 return CA_STATUS_FAILED;
3023 if (!strcmp(setAddress, remoteAddress))
3025 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
3026 (*env)->DeleteGlobalRef(env, jarrayObj);
3028 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3029 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3030 if (NULL == u_arraylist_remove(g_gattObjectList, index))
3032 OIC_LOG(ERROR, TAG, "List removal failed.");
3033 ca_mutex_unlock(g_gattObjectMutex);
3034 return CA_STATUS_FAILED;
3036 ca_mutex_unlock(g_gattObjectMutex);
3037 return CA_STATUS_OK;
3039 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
3040 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
3043 ca_mutex_unlock(g_gattObjectMutex);
3044 OIC_LOG(DEBUG, TAG, "there are no target object");
3045 return CA_STATUS_FAILED;
3048 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
3050 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetLEAddressFromBTDevice");
3052 VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
3053 VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
3055 // get Bluetooth Address
3056 jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
3057 if (!jni_btTargetAddress)
3059 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3063 const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
3066 OIC_LOG(ERROR, TAG, "targetAddress is not available");
3070 // get method ID of getDevice()
3071 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
3072 if (!jni_cid_gattdevice_list)
3074 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
3075 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3079 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
3080 METHODID_BT_DEVICE);
3081 if (!jni_mid_getDevice)
3083 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
3084 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3088 size_t length = u_arraylist_length(g_gattObjectList);
3089 for (size_t index = 0; index < length; index++)
3091 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
3094 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3095 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3096 return CA_STATUS_FAILED;
3099 OIC_LOG(DEBUG, TAG, "CALL API - bluetoothGatt.getDevice()");
3100 jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
3101 if (!jni_obj_device)
3103 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
3104 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3108 jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
3111 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
3112 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3116 const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
3119 OIC_LOG(ERROR, TAG, "btAddress is not available");
3120 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3124 OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
3125 OIC_LOG_V(DEBUG, TAG, "btAddress : %s", btAddress);
3126 if (!strcmp(targetAddress, btAddress))
3128 OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
3131 jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
3134 OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
3136 (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
3137 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3138 (*env)->DeleteLocalRef(env, jni_btAddress);
3139 (*env)->DeleteLocalRef(env, jni_obj_device);
3140 return jni_LEAddress;
3142 (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
3143 (*env)->DeleteLocalRef(env, jni_btAddress);
3144 (*env)->DeleteLocalRef(env, jni_obj_device);
3147 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetLEAddressFromBTDevice");
3155 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
3156 uint16_t notificationState, uint16_t sendState)
3158 VERIFY_NON_NULL(address, TAG, "address is null");
3160 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
3163 OIC_LOG(ERROR, TAG, "out of memory");
3164 return CA_MEMORY_ALLOC_FAILED;
3167 if (strlen(address) > CA_MACADDR_SIZE)
3169 OIC_LOG(ERROR, TAG, "address is not proper");
3171 return CA_STATUS_FAILED;
3174 OICStrcpy(newstate->address, sizeof(newstate->address), address);
3175 newstate->connectedState = connectedState;
3176 newstate->notificationState = notificationState;
3177 newstate->sendState = sendState;
3178 return CALEClientAddDeviceStateToList(newstate);
3181 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
3183 VERIFY_NON_NULL(state, TAG, "state is null");
3185 ca_mutex_lock(g_deviceStateListMutex);
3187 if (!g_deviceStateList)
3189 OIC_LOG(ERROR, TAG, "gdevice_list is null");
3190 ca_mutex_unlock(g_deviceStateListMutex);
3191 return CA_STATUS_FAILED;
3194 if (CALEClientIsDeviceInList(state->address))
3196 CALEState_t* curState = CALEClientGetStateInfo(state->address);
3199 OIC_LOG(ERROR, TAG, "curState is null");
3200 ca_mutex_unlock(g_deviceStateListMutex);
3201 return CA_STATUS_FAILED;
3204 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
3206 state->notificationState = curState->notificationState;
3209 // delete previous state for update new state
3210 CAResult_t res = CALEClientRemoveDeviceState(state->address);
3211 if (CA_STATUS_OK != res)
3213 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3214 ca_mutex_unlock(g_deviceStateListMutex);
3218 u_arraylist_add(g_deviceStateList, state); // update new state
3219 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s",
3220 state->connectedState, state->notificationState, state->address);
3222 ca_mutex_unlock(g_deviceStateListMutex);
3223 return CA_STATUS_OK;
3226 bool CALEClientIsDeviceInList(const char* remoteAddress)
3228 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3230 if (!g_deviceStateList)
3232 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3236 uint32_t length = u_arraylist_length(g_deviceStateList);
3237 for (uint32_t index = 0; index < length; index++)
3239 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3242 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3246 if (!strcmp(remoteAddress, state->address))
3248 OIC_LOG(DEBUG, TAG, "the device is already set");
3257 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
3261 CAResult_t CALEClientRemoveAllDeviceState()
3263 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
3265 ca_mutex_lock(g_deviceStateListMutex);
3266 if (!g_deviceStateList)
3268 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3269 ca_mutex_unlock(g_deviceStateListMutex);
3270 return CA_STATUS_FAILED;
3273 uint32_t length = u_arraylist_length(g_deviceStateList);
3274 for (uint32_t index = 0; index < length; index++)
3276 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3279 OIC_LOG(ERROR, TAG, "jarrayObj is null");
3285 OICFree(g_deviceStateList);
3286 g_deviceStateList = NULL;
3287 ca_mutex_unlock(g_deviceStateListMutex);
3289 return CA_STATUS_OK;
3292 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
3294 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
3295 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3297 if (!g_deviceStateList)
3299 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3300 return CA_STATUS_FAILED;
3303 uint32_t length = u_arraylist_length(g_deviceStateList);
3304 for (uint32_t index = 0; index < length; index++)
3306 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3309 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3313 if (!strcmp(state->address, remoteAddress))
3315 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
3317 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
3319 if (NULL == targetState)
3321 OIC_LOG(ERROR, TAG, "List removal failed.");
3322 return CA_STATUS_FAILED;
3325 OICFree(targetState);
3326 return CA_STATUS_OK;
3330 return CA_STATUS_OK;
3333 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
3335 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
3336 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
3338 if (!g_deviceStateList)
3340 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3344 uint32_t length = u_arraylist_length(g_deviceStateList);
3345 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
3347 for (uint32_t index = 0; index < length; index++)
3349 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3352 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3356 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
3357 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
3359 if (!strcmp(state->address, remoteAddress))
3361 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
3368 bool CALEClientIsConnectedDevice(const char* remoteAddress)
3370 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
3371 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3373 ca_mutex_lock(g_deviceStateListMutex);
3374 if (!g_deviceStateList)
3376 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3377 ca_mutex_unlock(g_deviceStateListMutex);
3381 uint32_t length = u_arraylist_length(g_deviceStateList);
3382 for (uint32_t index = 0; index < length; index++)
3384 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3387 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3391 if (!strcmp(state->address, remoteAddress))
3393 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
3395 if (STATE_CONNECTED == state->connectedState)
3397 ca_mutex_unlock(g_deviceStateListMutex);
3402 ca_mutex_unlock(g_deviceStateListMutex);
3407 ca_mutex_unlock(g_deviceStateListMutex);
3411 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
3413 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
3414 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
3416 ca_mutex_lock(g_deviceStateListMutex);
3417 if (!g_deviceStateList)
3419 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
3420 ca_mutex_unlock(g_deviceStateListMutex);
3424 uint32_t length = u_arraylist_length(g_deviceStateList);
3425 for (uint32_t index = 0; index < length; index++)
3427 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
3430 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
3434 if (!strcmp(state->address, remoteAddress))
3436 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
3438 if (STATE_CHARACTER_SET == state->notificationState)
3440 ca_mutex_unlock(g_deviceStateListMutex);
3445 ca_mutex_unlock(g_deviceStateListMutex);
3451 ca_mutex_unlock(g_deviceStateListMutex);
3455 void CALEClientCreateDeviceList()
3457 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
3459 // create new object array
3460 if (!g_gattObjectList)
3462 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
3464 g_gattObjectList = u_arraylist_create();
3467 if (!g_deviceStateList)
3469 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
3471 g_deviceStateList = u_arraylist_create();
3476 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
3478 g_deviceList = u_arraylist_create();
3483 * Check Sent Count for remove g_sendBuffer
3485 void CALEClientUpdateSendCnt(JNIEnv *env)
3487 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3489 ca_mutex_lock(g_threadMutex);
3493 if (g_targetCnt <= g_currentSentCnt)
3496 g_currentSentCnt = 0;
3500 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3501 g_sendBuffer = NULL;
3503 // notity the thread
3504 ca_cond_signal(g_threadCond);
3506 CALEClientSetSendFinishFlag(true);
3507 OIC_LOG(DEBUG, TAG, "set signal for send data");
3510 ca_mutex_unlock(g_threadMutex);
3513 CAResult_t CALEClientInitGattMutexVaraibles()
3515 if (NULL == g_bleReqRespClientCbMutex)
3517 g_bleReqRespClientCbMutex = ca_mutex_new();
3518 if (NULL == g_bleReqRespClientCbMutex)
3520 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3521 return CA_STATUS_FAILED;
3525 if (NULL == g_bleServerBDAddressMutex)
3527 g_bleServerBDAddressMutex = ca_mutex_new();
3528 if (NULL == g_bleServerBDAddressMutex)
3530 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3531 return CA_STATUS_FAILED;
3535 if (NULL == g_threadMutex)
3537 g_threadMutex = ca_mutex_new();
3538 if (NULL == g_threadMutex)
3540 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3541 return CA_STATUS_FAILED;
3545 if (NULL == g_threadSendMutex)
3547 g_threadSendMutex = ca_mutex_new();
3548 if (NULL == g_threadSendMutex)
3550 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3551 return CA_STATUS_FAILED;
3555 if (NULL == g_deviceListMutex)
3557 g_deviceListMutex = ca_mutex_new();
3558 if (NULL == g_deviceListMutex)
3560 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3561 return CA_STATUS_FAILED;
3565 if (NULL == g_gattObjectMutex)
3567 g_gattObjectMutex = ca_mutex_new();
3568 if (NULL == g_gattObjectMutex)
3570 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3571 return CA_STATUS_FAILED;
3575 if (NULL == g_deviceStateListMutex)
3577 g_deviceStateListMutex = ca_mutex_new();
3578 if (NULL == g_deviceStateListMutex)
3580 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3581 return CA_STATUS_FAILED;
3585 if (NULL == g_SendFinishMutex)
3587 g_SendFinishMutex = ca_mutex_new();
3588 if (NULL == g_SendFinishMutex)
3590 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3591 return CA_STATUS_FAILED;
3595 if (NULL == g_scanMutex)
3597 g_scanMutex = ca_mutex_new();
3598 if (NULL == g_scanMutex)
3600 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3601 return CA_STATUS_FAILED;
3605 if (NULL == g_threadWriteCharacteristicMutex)
3607 g_threadWriteCharacteristicMutex = ca_mutex_new();
3608 if (NULL == g_threadWriteCharacteristicMutex)
3610 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3611 return CA_STATUS_FAILED;
3615 return CA_STATUS_OK;
3618 void CALEClientTerminateGattMutexVariables()
3620 ca_mutex_free(g_bleReqRespClientCbMutex);
3621 g_bleReqRespClientCbMutex = NULL;
3623 ca_mutex_free(g_bleServerBDAddressMutex);
3624 g_bleServerBDAddressMutex = NULL;
3626 ca_mutex_free(g_threadMutex);
3627 g_threadMutex = NULL;
3629 ca_mutex_free(g_threadSendMutex);
3630 g_threadSendMutex = NULL;
3632 ca_mutex_free(g_deviceListMutex);
3633 g_deviceListMutex = NULL;
3635 ca_mutex_free(g_SendFinishMutex);
3636 g_SendFinishMutex = NULL;
3638 ca_mutex_free(g_scanMutex);
3641 ca_mutex_free(g_threadWriteCharacteristicMutex);
3642 g_threadWriteCharacteristicMutex = NULL;
3645 void CALEClientSetSendFinishFlag(bool flag)
3647 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3649 ca_mutex_lock(g_SendFinishMutex);
3650 g_isFinishedSendData = flag;
3651 ca_mutex_unlock(g_SendFinishMutex);
3658 CAResult_t CAStartLEGattClient()
3660 CAResult_t res = CALEClientStartMulticastServer();
3661 if (CA_STATUS_OK != res)
3663 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3667 g_isStartedLEClient = true;
3673 void CAStopLEGattClient()
3675 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3679 OIC_LOG(ERROR, TAG, "g_jvm is null");
3683 bool isAttached = false;
3685 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3688 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3689 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3693 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3699 CAResult_t ret = CALEClientDisconnectAll(env);
3700 if (CA_STATUS_OK != ret)
3702 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3705 ret = CALEClientStopScan();
3706 if(CA_STATUS_OK != ret)
3708 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3711 ca_mutex_lock(g_threadMutex);
3712 ca_cond_signal(g_threadCond);
3713 ca_mutex_unlock(g_threadMutex);
3715 ca_mutex_lock(g_threadWriteCharacteristicMutex);
3716 ca_cond_signal(g_threadWriteCharacteristicCond);
3717 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
3721 (*g_jvm)->DetachCurrentThread(g_jvm);
3726 CAResult_t CAInitializeLEGattClient()
3728 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
3729 CALEClientInitialize();
3730 return CA_STATUS_OK;
3733 void CATerminateLEGattClient()
3735 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3736 CAStopLEGattClient();
3737 CALEClientTerminate();
3740 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3741 uint32_t dataLen, CALETransferType_t type,
3744 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3745 VERIFY_NON_NULL(data, TAG, "data is null");
3746 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3748 if (LE_UNICAST != type || position < 0)
3750 OIC_LOG(ERROR, TAG, "this request is not unicast");
3751 return CA_STATUS_INVALID_PARAM;
3754 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3757 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3759 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3760 VERIFY_NON_NULL(data, TAG, "data is null");
3762 return CALEClientSendMulticastMessage(data, dataLen);
3765 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3767 ca_mutex_lock(g_bleReqRespClientCbMutex);
3768 g_CABLEClientDataReceivedCallback = callback;
3769 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3772 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3774 g_threadPoolHandle = handle;
3777 CAResult_t CAGetLEAddress(char **local_address)
3779 VERIFY_NON_NULL(local_address, TAG, "local_address");
3780 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3781 return CA_NOT_SUPPORTED;
3784 JNIEXPORT void JNICALL
3785 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3788 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3789 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3790 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3791 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3793 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3796 JNIEXPORT void JNICALL
3797 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3800 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3801 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3802 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3803 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3805 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3808 JNIEXPORT void JNICALL
3809 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3812 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3813 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3814 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3816 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3817 if (CA_STATUS_OK != res)
3819 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3824 * Class: org_iotivity_ca_jar_caleinterface
3825 * Method: CALeGattConnectionStateChangeCallback
3826 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3828 JNIEXPORT void JNICALL
3829 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3835 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3837 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3838 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3839 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3841 jint state_connected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_CONNECTED");
3842 jint state_disconnected = CALEGetConstantsValue(env, CLASSPATH_BT_PROFILE, "STATE_DISCONNECTED");
3843 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
3845 if (gatt_success == status && state_connected == newstate) // le connected
3847 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3853 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3856 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3857 STATE_CHARACTER_NO_CHANGE,
3859 if (CA_STATUS_OK != res)
3861 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3862 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3865 OIC_LOG_V(INFO, TAG, "ConnectionStateCB - remote address : %s", address);
3867 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3870 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3871 if (CA_STATUS_OK != res)
3873 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3877 res = CALEClientDiscoverServices(env, gatt);
3878 if (CA_STATUS_OK != res)
3880 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3884 else if (GATT_ERROR == status && state_disconnected == newstate)
3886 OIC_LOG(INFO, TAG, "Background connection running.. please wait");
3888 else // le disconnected
3890 CAResult_t res = CALEClientStartScan();
3891 if (CA_STATUS_OK != res)
3893 if (CA_ADAPTER_NOT_ENABLED == res)
3895 // scan will be started with start server when adapter is enabled
3896 OIC_LOG(INFO, TAG, "Adapter was disabled");
3900 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3905 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3908 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3912 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3915 res = CALEClientRemoveDeviceState(address);
3916 if (CA_STATUS_OK != res)
3918 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
3922 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3925 res = CALEClientGattClose(env, gatt);
3926 if (CA_STATUS_OK != res)
3928 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3933 (*env)->DeleteGlobalRef(env, g_sendBuffer);
3934 g_sendBuffer = NULL;
3942 CALEClientSendFinish(env, gatt);
3947 * Class: org_iotivity_ca_jar_caleinterface
3948 * Method: CALeGattServicesDiscoveredCallback
3949 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3951 JNIEXPORT void JNICALL
3952 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3957 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3958 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3959 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3960 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3962 if (0 != status) // discovery error
3964 CALEClientSendFinish(env, gatt);
3968 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3971 CALEClientSendFinish(env, gatt);
3975 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3978 CALEClientSendFinish(env, gatt);
3982 if (!CALEClientIsSetCharacteristic(address))
3984 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3987 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3991 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3992 if (!jni_obj_GattCharacteristic)
3994 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3998 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3999 jni_obj_GattCharacteristic);
4000 if (CA_STATUS_OK != res)
4002 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
4006 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
4007 if (CA_STATUS_OK != res)
4009 OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
4012 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4013 if (CA_STATUS_OK != res)
4015 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4021 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4023 if (CA_STATUS_OK != res)
4025 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4031 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4032 if (CA_STATUS_OK != res)
4034 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4038 OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
4039 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4044 OIC_LOG(ERROR, TAG, "ServicesDiscovery has failed");
4045 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4046 CALEClientSendFinish(env, gatt);
4051 * Class: org_iotivity_ca_jar_caleinterface
4052 * Method: CALeGattCharacteristicWritjclasseCallback
4053 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
4055 JNIEXPORT void JNICALL
4056 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
4057 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
4060 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
4061 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4062 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4063 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4066 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
4068 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
4070 // send success & signal
4071 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4077 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4083 jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
4084 if (gatt_success != status) // error case
4086 OIC_LOG(ERROR, TAG, "send failure");
4089 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4090 if (CA_STATUS_OK != res)
4092 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
4093 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4094 g_isSignalSetFlag = true;
4095 ca_cond_signal(g_threadWriteCharacteristicCond);
4096 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4098 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
4099 STATE_CHARACTER_SET,
4101 if (CA_STATUS_OK != res)
4103 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4106 if (g_clientErrorCallback)
4108 jint length = (*env)->GetArrayLength(env, data);
4109 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
4112 CALEClientSendFinish(env, gatt);
4118 OIC_LOG(DEBUG, TAG, "send success");
4119 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
4120 STATE_SEND_SUCCESS);
4121 if (CA_STATUS_OK != res)
4123 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
4126 ca_mutex_lock(g_threadWriteCharacteristicMutex);
4127 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
4128 g_isSignalSetFlag = true;
4129 ca_cond_signal(g_threadWriteCharacteristicCond);
4130 ca_mutex_unlock(g_threadWriteCharacteristicMutex);
4132 CALEClientUpdateSendCnt(env);
4135 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4141 CALEClientSendFinish(env, gatt);
4146 * Class: org_iotivity_ca_jar_caleinterface
4147 * Method: CALeGattCharacteristicChangedCallback
4148 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
4150 JNIEXPORT void JNICALL
4151 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
4152 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
4154 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
4155 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4156 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4157 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4158 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
4160 // get Byte Array and convert to uint8_t*
4161 jint length = (*env)->GetArrayLength(env, data);
4164 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
4166 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
4167 jni_byte_responseData);
4169 uint8_t* receivedData = OICMalloc(length);
4172 OIC_LOG(ERROR, TAG, "receivedData is null");
4176 memcpy(receivedData, jni_byte_responseData, length);
4177 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
4179 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
4182 OIC_LOG(ERROR, TAG, "jni_address is null");
4183 OICFree(receivedData);
4187 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
4190 OIC_LOG(ERROR, TAG, "address is null");
4191 OICFree(receivedData);
4195 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
4196 receivedData, length);
4198 ca_mutex_lock(g_bleServerBDAddressMutex);
4199 uint32_t sentLength = 0;
4200 g_CABLEClientDataReceivedCallback(address, receivedData, length,
4202 ca_mutex_unlock(g_bleServerBDAddressMutex);
4204 (*env)->ReleaseStringUTFChars(env, jni_address, address);
4208 * Class: org_iotivity_ca_jar_caleinterface
4209 * Method: CALeGattDescriptorWriteCallback
4210 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
4212 JNIEXPORT void JNICALL
4213 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
4217 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
4218 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
4219 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
4220 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
4222 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
4223 if (CA_STATUS_OK != res)
4225 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
4233 CALEClientSendFinish(env, gatt);