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("CA_LE_CLIENT")
42 #define MICROSECS_PER_SEC 1000000
44 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
45 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
46 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
47 static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
50 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
51 static u_arraylist_t *g_gattObjectList = NULL;
52 static u_arraylist_t *g_deviceStateList = NULL;
54 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
55 static CABLEErrorHandleCallback g_clientErrorCallback;
56 static ca_thread_pool_t g_threadPoolHandle = NULL;
57 static jobject g_leScanCallback = NULL;
58 static jobject g_leGattCallback = NULL;
59 static jobject g_context = NULL;
60 static jobjectArray g_uuidList = NULL;
62 // it will be prevent to start send logic when adapter has stopped.
63 static bool g_isStartedLEClient = false;
64 static bool g_isStartedMulticastServer = false;
65 static bool g_isStartedScan = false;
67 static jbyteArray g_sendBuffer = NULL;
68 static uint32_t g_targetCnt = 0;
69 static uint32_t g_currentSentCnt = 0;
70 static bool g_isFinishedSendData = false;
71 static ca_mutex g_SendFinishMutex = NULL;
72 static ca_mutex g_threadMutex = NULL;
73 static ca_cond g_threadCond = NULL;
74 static ca_cond g_deviceDescCond = NULL;
76 static ca_mutex g_threadSendMutex = NULL;
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 CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
88 void CALEClientJniInit()
90 OIC_LOG(DEBUG, TAG, "CALEClientJniInit");
91 g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
94 void CALEClientJNISetContext()
96 OIC_LOG(DEBUG, TAG, "CALEClientJNISetContext");
97 g_context = (jobject) CANativeJNIGetContext();
100 CAResult_t CALECreateJniInterfaceObject()
102 OIC_LOG(DEBUG, TAG, "CALECreateJniInterfaceObject");
106 OIC_LOG(ERROR, TAG, "g_context is null");
107 return CA_STATUS_FAILED;
112 OIC_LOG(ERROR, TAG, "g_jvm is null");
113 return CA_STATUS_FAILED;
116 bool isAttached = false;
118 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
121 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
122 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
126 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
127 return CA_STATUS_FAILED;
132 jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
133 if (!jni_LEInterface)
135 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
139 jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
140 "(Landroid/content/Context;)V");
141 if (!LeInterfaceConstructorMethod)
143 OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface constructor method");
147 (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
148 OIC_LOG(DEBUG, TAG, "Create instance for CaLeClientInterface");
152 (*g_jvm)->DetachCurrentThread(g_jvm);
161 (*g_jvm)->DetachCurrentThread(g_jvm);
164 return CA_STATUS_FAILED;
167 CAResult_t CALEClientInitialize(ca_thread_pool_t handle)
169 OIC_LOG(DEBUG, TAG, "CALEClientInitialize");
175 OIC_LOG(ERROR, TAG, "g_jvm is null");
176 return CA_STATUS_FAILED;
179 bool isAttached = false;
181 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
184 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
185 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
189 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
190 return CA_STATUS_FAILED;
195 CAResult_t ret = CALECheckPlatformVersion(env, 18);
196 if (CA_STATUS_OK != ret)
198 OIC_LOG(ERROR, TAG, "it is not supported");
202 (*g_jvm)->DetachCurrentThread(g_jvm);
208 g_threadPoolHandle = handle;
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();
229 CALEClientCreateDeviceList();
230 CALEClientJNISetContext();
232 ret = CALEClientCreateUUIDList();
233 if (CA_STATUS_OK != ret)
235 OIC_LOG(ERROR, TAG, "CALEClientCreateUUIDList has failed");
239 (*g_jvm)->DetachCurrentThread(g_jvm);
245 ret = CALECreateJniInterfaceObject(); /* create java caleinterface instance*/
246 if (CA_STATUS_OK != ret)
248 OIC_LOG(ERROR, TAG, "CALECreateJniInterfaceObject has failed");
252 (*g_jvm)->DetachCurrentThread(g_jvm);
257 g_isStartedLEClient = true;
261 (*g_jvm)->DetachCurrentThread(g_jvm);
267 void CALEClientTerminate()
269 OIC_LOG(DEBUG, TAG, "CALEClientTerminate");
273 OIC_LOG(ERROR, TAG, "g_jvm is null");
277 bool isAttached = false;
279 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
282 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
283 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
287 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
293 if (g_leScanCallback)
295 (*env)->DeleteGlobalRef(env, g_leScanCallback);
298 if (g_leGattCallback)
300 (*env)->DeleteGlobalRef(env, g_leGattCallback);
305 (*env)->DeleteGlobalRef(env, g_sendBuffer);
310 (*env)->DeleteGlobalRef(env, g_uuidList);
313 CAResult_t ret = CALEClientRemoveAllDeviceState();
314 if (CA_STATUS_OK != ret)
316 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
319 ret = CALEClientRemoveAllScanDevices(env);
320 if (CA_STATUS_OK != ret)
322 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
325 ret = CALEClientRemoveAllGattObjs(env);
326 if (CA_STATUS_OK != ret)
328 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
331 g_isStartedMulticastServer = false;
332 g_isStartedScan = false;
333 CALEClientSetSendFinishFlag(false);
335 CALEClientTerminateGattMutexVariables();
337 ca_cond_free(g_deviceDescCond);
338 ca_cond_free(g_threadCond);
340 g_deviceDescCond = NULL;
345 (*g_jvm)->DetachCurrentThread(g_jvm);
349 void CALEClientSendFinish(JNIEnv *env, jobject gatt)
351 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
352 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
356 CAResult_t res = CALEClientDisconnect(env, gatt);
357 if (CA_STATUS_OK != res)
359 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
362 CALEClientUpdateSendCnt(env);
365 CAResult_t CALEClientSendUnicastMessage(const char* address,
367 const uint32_t dataLen)
369 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
370 VERIFY_NON_NULL(address, TAG, "address is null");
371 VERIFY_NON_NULL(data, TAG, "data is null");
373 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
376 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
377 const uint32_t dataLen)
379 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
380 VERIFY_NON_NULL(data, TAG, "data is null");
384 OIC_LOG(ERROR, TAG, "g_jvm is null");
385 return CA_STATUS_FAILED;
388 bool isAttached = false;
390 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
393 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
394 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
398 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
399 return CA_STATUS_FAILED;
404 CAResult_t ret = CALEClientSendMulticastMessageImpl(env, data, dataLen);
405 if (CA_STATUS_OK != ret)
407 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
412 (*g_jvm)->DetachCurrentThread(g_jvm);
418 CAResult_t CALEClientStartUnicastServer(const char* address)
420 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
422 return CA_NOT_SUPPORTED;
425 CAResult_t CALEClientStartMulticastServer()
427 OIC_LOG(DEBUG, TAG, "CALEClientStartMulticastServer");
429 if (g_isStartedMulticastServer)
431 OIC_LOG(ERROR, TAG, "server is already started..it will be skipped");
432 return CA_STATUS_FAILED;
437 OIC_LOG(ERROR, TAG, "g_jvm is null");
438 return CA_STATUS_FAILED;
441 bool isAttached = false;
443 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
446 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
447 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
451 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
452 return CA_STATUS_FAILED;
457 g_isStartedMulticastServer = true;
458 CAResult_t ret = CALEClientStartScan();
459 if (CA_STATUS_OK != ret)
461 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
466 (*g_jvm)->DetachCurrentThread(g_jvm);
472 void CALEClientStopUnicastServer()
474 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
477 void CALEClientStopMulticastServer()
479 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
480 g_isStartedMulticastServer = false;
481 CAResult_t res = CALEClientStopScan();
482 if (CA_STATUS_OK != res)
484 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
489 void CALEClientSetCallback(CAPacketReceiveCallback callback)
491 g_packetReceiveCallback = callback;
494 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
496 g_clientErrorCallback = callback;
499 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
500 const uint32_t dataLen)
502 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
504 VERIFY_NON_NULL(address, TAG, "address is null");
505 VERIFY_NON_NULL(data, TAG, "data is null");
509 OIC_LOG(ERROR, TAG, "g_jvm is null");
510 return CA_STATUS_FAILED;
513 bool isAttached = false;
515 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
518 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
519 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
522 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
523 return CA_STATUS_FAILED;
528 ca_mutex_lock(g_threadSendMutex);
530 CAResult_t ret = CA_STATUS_OK;
531 if (g_context && g_deviceList)
533 uint32_t length = u_arraylist_length(g_deviceList);
534 for (uint32_t index = 0; index < length; index++)
536 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
539 OIC_LOG(ERROR, TAG, "jarrayObj is null");
543 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
546 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
550 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
553 OIC_LOG(ERROR, TAG, "setAddress is null");
557 OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
559 if (!strcmp(setAddress, address))
561 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
563 // connect to gatt server
564 ret = CALEClientStopScan();
565 if (CA_STATUS_OK != ret)
567 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
573 (*env)->DeleteGlobalRef(env, g_sendBuffer);
575 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
576 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
577 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
579 ret = CALEClientSendData(env, jarrayObj);
580 if (CA_STATUS_OK != ret)
582 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
586 OIC_LOG(INFO, TAG, "wake up");
589 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
595 (*g_jvm)->DetachCurrentThread(g_jvm);
598 ret = CALECheckSendState(address);
599 if(CA_STATUS_OK != ret)
601 OIC_LOG(ERROR, TAG, "send has failed");
605 // start LE Scan again
606 ret = CALEClientStartScan();
607 if (CA_STATUS_OK != ret)
609 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
610 ca_mutex_unlock(g_threadSendMutex);
614 ca_mutex_unlock(g_threadSendMutex);
615 OIC_LOG(INFO, TAG, "unicast - send success");
621 // start LE Scan again
622 ret = CALEClientStartScan();
623 if (CA_STATUS_OK != ret)
625 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
626 ca_mutex_unlock(g_threadSendMutex);
629 (*g_jvm)->DetachCurrentThread(g_jvm);
636 (*g_jvm)->DetachCurrentThread(g_jvm);
638 ca_mutex_unlock(g_threadSendMutex);
639 return CA_SEND_FAILED;
642 CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
643 const uint32_t dataLen)
645 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
646 VERIFY_NON_NULL(data, TAG, "data is null");
647 VERIFY_NON_NULL(env, TAG, "env is null");
651 OIC_LOG(ERROR, TAG, "g_deviceList is null");
652 return CA_STATUS_FAILED;
655 ca_mutex_lock(g_threadSendMutex);
657 CALEClientSetSendFinishFlag(false);
659 OIC_LOG(DEBUG, TAG, "set byteArray for data");
662 (*env)->DeleteGlobalRef(env, g_sendBuffer);
665 if (0 == u_arraylist_length(g_deviceList))
667 // Wait for LE peripherals to be discovered.
669 // Number of times to wait for discovery to complete.
670 static int const RETRIES = 5;
672 static uint64_t const TIMEOUT =
673 2 * MICROSECS_PER_SEC; // Microseconds
675 bool devicesDiscovered = false;
677 0 == u_arraylist_length(g_deviceList) && i < RETRIES;
680 if (ca_cond_wait_for(g_deviceDescCond,
684 devicesDiscovered = true;
688 if (!devicesDiscovered)
694 // connect to gatt server
695 CAResult_t res = CALEClientStopScan();
696 if (CA_STATUS_OK != res)
698 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
699 ca_mutex_unlock(g_threadSendMutex);
702 uint32_t length = u_arraylist_length(g_deviceList);
703 g_targetCnt = length;
705 jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
706 (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
707 g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
709 for (uint32_t index = 0; index < length; index++)
711 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
714 OIC_LOG(ERROR, TAG, "jarrayObj is not available");
718 res = CALEClientSendData(env, jarrayObj);
719 if (res != CA_STATUS_OK)
721 OIC_LOG(ERROR, TAG, "BT device - send has failed");
724 jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
727 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
731 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
734 OIC_LOG(ERROR, TAG, "address is not available");
738 res = CALECheckSendState(address);
739 if (CA_STATUS_OK != res)
741 OIC_LOG_V(INFO, TAG, "multicast : send has failed for this device[%s]", address);
742 g_clientErrorCallback(address, data, dataLen, res);
743 (*env)->ReleaseStringUTFChars(env, jni_address, address);
747 (*env)->ReleaseStringUTFChars(env, jni_address, address);
750 OIC_LOG(DEBUG, TAG, "connection routine is finished");
752 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
753 if (!g_isFinishedSendData)
755 ca_mutex_lock(g_threadMutex);
756 ca_cond_wait(g_threadCond, g_threadMutex);
757 OIC_LOG(DEBUG, TAG, "the data was sent for All devices");
758 ca_mutex_unlock(g_threadMutex);
761 // start LE Scan again
762 res = CALEClientStartScan();
763 if (CA_STATUS_OK != res)
765 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
766 ca_mutex_unlock(g_threadSendMutex);
770 ca_mutex_unlock(g_threadSendMutex);
771 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
775 res = CALEClientStartScan();
776 if (CA_STATUS_OK != res)
778 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
779 ca_mutex_unlock(g_threadSendMutex);
783 ca_mutex_unlock(g_threadSendMutex);
784 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
785 return CA_SEND_FAILED;
788 CAResult_t CALECheckSendState(const char* address)
790 VERIFY_NON_NULL(address, TAG, "address is null");
792 ca_mutex_lock(g_deviceStateListMutex);
793 CALEState_t* state = CALEClientGetStateInfo(address);
796 OIC_LOG(ERROR, TAG, "state is null");
797 ca_mutex_unlock(g_deviceStateListMutex);
798 return CA_SEND_FAILED;
801 if (STATE_SEND_SUCCESS != state->sendState)
803 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
804 ca_mutex_unlock(g_deviceStateListMutex);
805 return CA_SEND_FAILED;
807 ca_mutex_unlock(g_deviceStateListMutex);
811 CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
813 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
814 VERIFY_NON_NULL(device, TAG, "device is null");
815 VERIFY_NON_NULL(env, TAG, "env is null");
817 jstring jni_address = CALEGetAddressFromBTDevice(env, device);
820 OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
821 return CA_STATUS_FAILED;
824 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
827 OIC_LOG(ERROR, TAG, "address is not available");
828 return CA_STATUS_FAILED;
831 ca_mutex_lock(g_deviceStateListMutex);
832 CALEState_t* state = CALEClientGetStateInfo(address);
833 ca_mutex_unlock(g_deviceStateListMutex);
836 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
837 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
838 if (CA_STATUS_OK != ret)
840 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
841 (*env)->ReleaseStringUTFChars(env, jni_address, address);
847 if (STATE_CONNECTED == state->connectedState)
849 OIC_LOG(INFO, TAG, "GATT has already connected");
850 jobject gatt = CALEClientGetGattObjInList(env, address);
853 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
854 (*env)->ReleaseStringUTFChars(env, jni_address, address);
855 return CA_STATUS_FAILED;
858 CAResult_t ret = CALEClientWriteCharacteristic(env, gatt);
859 if (CA_STATUS_OK != ret)
861 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
862 (*env)->ReleaseStringUTFChars(env, jni_address, address);
868 OIC_LOG(DEBUG, TAG, "start to connect LE");
869 CAResult_t ret = CALEClientConnect(env, device, JNI_FALSE, g_leGattCallback);
870 if (CA_STATUS_OK != ret)
872 OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
873 (*env)->ReleaseStringUTFChars(env, jni_address, address);
879 (*env)->ReleaseStringUTFChars(env, jni_address, address);
883 jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
885 VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
886 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
888 jclass jni_cid_gattdevice_list = (*env)->FindClass(env, CLASSPATH_BT_GATT);
889 if (!jni_cid_gattdevice_list)
891 OIC_LOG(ERROR, TAG, "jni_cid_gattdevice_list is null");
895 jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
896 "()Landroid/bluetooth/BluetoothDevice;");
897 if (!jni_mid_getDevice)
899 OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
903 jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
906 OIC_LOG(ERROR, TAG, "jni_obj_device is null");
910 jstring jni_address = CALEGetAddressFromBTDevice(env, jni_obj_device);
913 OIC_LOG(ERROR, TAG, "jni_address is null");
923 CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
926 OIC_LOG(DEBUG, TAG, "Gatt Close");
927 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
928 VERIFY_NON_NULL(env, TAG, "env is null");
930 // get BluetoothGatt class
931 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
932 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
933 if (!jni_cid_BluetoothGatt)
935 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
936 return CA_STATUS_FAILED;
939 jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
940 if (!jni_mid_closeGatt)
942 OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
946 // call disconnect gatt method
947 OIC_LOG(DEBUG, TAG, "request to close GATT");
948 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
950 if ((*env)->ExceptionCheck(env))
952 OIC_LOG(ERROR, TAG, "closeGATT has failed");
953 (*env)->ExceptionDescribe(env);
954 (*env)->ExceptionClear(env);
955 return CA_STATUS_FAILED;
961 CAResult_t CALEClientStartScan()
963 if (!g_isStartedMulticastServer)
965 OIC_LOG(ERROR, TAG, "server is not started yet..scan will be passed");
966 return CA_STATUS_FAILED;
969 if (!g_isStartedLEClient)
971 OIC_LOG(ERROR, TAG, "LE client is not started");
972 return CA_STATUS_FAILED;
977 OIC_LOG(ERROR, TAG, "g_jvm is null");
978 return CA_STATUS_FAILED;
983 OIC_LOG(INFO, TAG, "scanning is already started");
987 bool isAttached = false;
989 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
992 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
994 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
997 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
998 return CA_STATUS_FAILED;
1003 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1005 CAResult_t ret = CA_STATUS_OK;
1006 // scan gatt server with UUID
1007 if (g_leScanCallback && g_uuidList)
1010 ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
1011 if(CA_STATUS_OK != ret)
1013 OIC_LOG(ERROR, TAG, "CALEClientStartScanWithUUIDImpl has failed");
1016 ret = CALEClientStartScanImpl(env, g_leScanCallback);
1017 if (CA_STATUS_OK != ret)
1019 OIC_LOG(ERROR, TAG, "CALEClientStartScanImpl has failed");
1026 (*g_jvm)->DetachCurrentThread(g_jvm);
1032 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
1034 VERIFY_NON_NULL(callback, TAG, "callback is null");
1035 VERIFY_NON_NULL(env, TAG, "env is null");
1037 if (!CALEIsEnableBTAdapter(env))
1039 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1040 return CA_ADAPTER_NOT_ENABLED;
1043 // get default bt adapter class
1044 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1045 if (!jni_cid_BTAdapter)
1047 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1048 return CA_STATUS_FAILED;
1051 // get remote bt adapter method
1052 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1053 "getDefaultAdapter",
1054 METHODID_OBJECTNONPARAM);
1055 if (!jni_mid_getDefaultAdapter)
1057 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1058 return CA_STATUS_FAILED;
1061 // get start le scan method
1062 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1063 "(Landroid/bluetooth/BluetoothAdapter$"
1064 "LeScanCallback;)Z");
1065 if (!jni_mid_startLeScan)
1067 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1068 return CA_STATUS_FAILED;
1071 // gat bt adapter object
1072 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1073 jni_mid_getDefaultAdapter);
1074 if (!jni_obj_BTAdapter)
1076 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1077 return CA_STATUS_FAILED;
1080 // call start le scan method
1081 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1082 jni_mid_startLeScan, callback);
1083 if (!jni_obj_startLeScan)
1085 OIC_LOG(ERROR, TAG, "startLeScan is failed");
1086 return CA_STATUS_FAILED;
1090 OIC_LOG(DEBUG, TAG, "startLeScan is started");
1091 g_isStartedScan = true;
1094 return CA_STATUS_OK;
1097 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
1099 VERIFY_NON_NULL(callback, TAG, "callback is null");
1100 VERIFY_NON_NULL(uuids, TAG, "uuids is null");
1101 VERIFY_NON_NULL(env, TAG, "env is null");
1103 if (!CALEIsEnableBTAdapter(env))
1105 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1106 return CA_ADAPTER_NOT_ENABLED;
1109 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1110 if (!jni_cid_BTAdapter)
1112 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1113 return CA_STATUS_FAILED;
1116 // get remote bt adapter method
1117 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1118 "getDefaultAdapter",
1119 METHODID_OBJECTNONPARAM);
1120 if (!jni_mid_getDefaultAdapter)
1122 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1123 return CA_STATUS_FAILED;
1126 // get start le scan method
1127 jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
1128 "([Ljava/util/UUID;Landroid/bluetooth/"
1129 "BluetoothAdapter$LeScanCallback;)Z");
1130 if (!jni_mid_startLeScan)
1132 OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
1133 return CA_STATUS_FAILED;
1136 // get bt adapter object
1137 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1138 jni_mid_getDefaultAdapter);
1139 if (!jni_obj_BTAdapter)
1141 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
1142 return CA_STATUS_FAILED;
1145 // call start le scan method
1146 jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
1147 jni_mid_startLeScan, uuids, callback);
1148 if (!jni_obj_startLeScan)
1150 OIC_LOG(ERROR, TAG, "startLeScan With UUID is failed");
1151 return CA_STATUS_FAILED;
1155 OIC_LOG(DEBUG, TAG, "startLeScan With UUID is started");
1156 g_isStartedScan = true;
1159 return CA_STATUS_OK;
1162 jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
1164 VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
1165 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1168 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1171 OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
1175 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
1176 "(Ljava/lang/String;)"
1177 "Ljava/util/UUID;");
1178 if (!jni_mid_fromString)
1180 OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
1184 jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
1185 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
1189 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1193 return jni_obj_uuid;
1196 CAResult_t CALEClientStopScan()
1200 OIC_LOG(ERROR, TAG, "g_jvm is null");
1201 return CA_STATUS_FAILED;
1204 if (!g_isStartedScan)
1206 OIC_LOG(INFO, TAG, "scanning is already stopped");
1207 return CA_STATUS_OK;
1210 bool isAttached = false;
1212 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1215 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1216 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1219 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1220 return CA_STATUS_FAILED;
1225 CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
1226 if (CA_STATUS_OK != ret)
1228 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1232 g_isStartedScan = false;
1237 (*g_jvm)->DetachCurrentThread(g_jvm);
1243 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
1245 OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
1246 VERIFY_NON_NULL(callback, TAG, "callback is null");
1247 VERIFY_NON_NULL(env, TAG, "env is null");
1249 if (!CALEIsEnableBTAdapter(env))
1251 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1252 return CA_ADAPTER_NOT_ENABLED;
1255 // get default bt adapter class
1256 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
1257 if (!jni_cid_BTAdapter)
1259 OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
1260 return CA_STATUS_FAILED;
1263 // get remote bt adapter method
1264 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
1265 "getDefaultAdapter",
1266 METHODID_OBJECTNONPARAM);
1267 if (!jni_mid_getDefaultAdapter)
1269 OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
1270 return CA_STATUS_FAILED;
1273 // get start le scan method
1274 jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
1275 "(Landroid/bluetooth/"
1276 "BluetoothAdapter$LeScanCallback;)V");
1277 if (!jni_mid_stopLeScan)
1279 OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
1280 return CA_STATUS_FAILED;
1283 // gat bt adapter object
1284 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
1285 jni_mid_getDefaultAdapter);
1286 if (!jni_obj_BTAdapter)
1288 OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
1289 return CA_STATUS_FAILED;
1292 OIC_LOG(DEBUG, TAG, "CALL API - request to stop LE Scan");
1293 // call start le scan method
1294 (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
1295 if ((*env)->ExceptionCheck(env))
1297 OIC_LOG(ERROR, TAG, "stopLeScan has failed");
1298 (*env)->ExceptionDescribe(env);
1299 (*env)->ExceptionClear(env);
1300 return CA_STATUS_FAILED;
1303 return CA_STATUS_OK;
1306 CAResult_t CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect,
1309 OIC_LOG(DEBUG, TAG, "GATT CONNECT");
1310 VERIFY_NON_NULL(env, TAG, "env is null");
1311 VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1312 VERIFY_NON_NULL(callback, TAG, "callback is null");
1314 if (!CALEIsEnableBTAdapter(env))
1316 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1317 return CA_ADAPTER_NOT_ENABLED;
1320 jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
1323 OIC_LOG(ERROR, TAG, "bleConnect: CALEGetAddressFromBTDevice is null");
1324 return CA_STATUS_FAILED;
1327 // get BluetoothDevice class
1328 OIC_LOG(DEBUG, TAG, "get BluetoothDevice class");
1329 jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
1330 if (!jni_cid_BluetoothDevice)
1332 OIC_LOG(ERROR, TAG, "bleConnect: jni_cid_BluetoothDevice is null");
1333 return CA_STATUS_FAILED;
1336 // get connectGatt method
1337 OIC_LOG(DEBUG, TAG, "get connectGatt method");
1338 jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
1339 "(Landroid/content/Context;ZLandroid/"
1340 "bluetooth/BluetoothGattCallback;)"
1341 "Landroid/bluetooth/BluetoothGatt;");
1342 if (!jni_mid_connectGatt)
1344 OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
1345 return CA_STATUS_FAILED;
1348 OIC_LOG(DEBUG, TAG, "Call object method - connectGatt");
1349 jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
1350 jni_mid_connectGatt,
1352 autoconnect, callback);
1353 if (!jni_obj_connectGatt)
1355 OIC_LOG(ERROR, TAG, "CALL API - connectGatt was failed..it will be removed");
1356 CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
1357 CALEClientUpdateSendCnt(env);
1358 return CA_STATUS_FAILED;
1362 OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
1364 return CA_STATUS_OK;
1367 CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
1369 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1370 VERIFY_NON_NULL(env, TAG, "env is null");
1371 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1373 if (!CALEIsEnableBTAdapter(env))
1375 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1376 return CA_ADAPTER_NOT_ENABLED;
1379 // get BluetoothGatt class
1380 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1381 if (!jni_cid_BluetoothGatt)
1383 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1384 return CA_STATUS_FAILED;
1387 OIC_LOG(DEBUG, TAG, "get gatt disconnect method");
1388 jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1389 "disconnect", "()V");
1390 if (!jni_mid_disconnectGatt)
1392 OIC_LOG(ERROR, TAG, "jni_mid_disconnectGatt is null");
1393 return CA_STATUS_FAILED;
1396 // call disconnect gatt method
1397 (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
1398 if ((*env)->ExceptionCheck(env))
1400 OIC_LOG(ERROR, TAG, "disconnect has failed");
1401 (*env)->ExceptionDescribe(env);
1402 (*env)->ExceptionClear(env);
1403 return CA_STATUS_FAILED;
1406 OIC_LOG(DEBUG, TAG, "disconnecting Gatt...");
1408 return CA_STATUS_OK;
1411 CAResult_t CALEClientDisconnectAll(JNIEnv *env)
1413 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1414 VERIFY_NON_NULL(env, TAG, "env is null");
1416 if (!g_gattObjectList)
1418 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
1419 return CA_STATUS_FAILED;
1422 uint32_t length = u_arraylist_length(g_gattObjectList);
1423 for (uint32_t index = 0; index < length; index++)
1425 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
1428 OIC_LOG(ERROR, TAG, "jarrayObj is null");
1431 CAResult_t res = CALEClientDisconnect(env, jarrayObj);
1432 if (CA_STATUS_OK != res)
1434 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1439 OICFree(g_gattObjectList);
1440 g_gattObjectList = NULL;
1442 return CA_STATUS_OK;
1445 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
1447 VERIFY_NON_NULL(env, TAG, "env is null");
1448 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1450 if (!CALEIsEnableBTAdapter(env))
1452 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1453 return CA_ADAPTER_NOT_ENABLED;
1456 // get BluetoothGatt class
1457 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1458 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1459 if (!jni_cid_BluetoothGatt)
1461 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1462 return CA_STATUS_FAILED;
1465 OIC_LOG(DEBUG, TAG, "discovery gatt services method");
1466 jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1467 "discoverServices", "()Z");
1468 if (!jni_mid_discoverServices)
1470 OIC_LOG(ERROR, TAG, "jni_mid_discoverServices is null");
1471 return CA_STATUS_FAILED;
1473 // call disconnect gatt method
1474 OIC_LOG(DEBUG, TAG, "CALL API - request discovery gatt services");
1475 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
1478 OIC_LOG(ERROR, TAG, "discoverServices has not been started");
1479 return CA_STATUS_FAILED;
1482 return CA_STATUS_OK;
1485 CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
1487 VERIFY_NON_NULL(env, TAG, "env is null");
1488 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
1491 jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
1492 if (!jni_obj_character)
1494 CALEClientSendFinish(env, gatt);
1495 return CA_STATUS_FAILED;
1498 CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
1499 if (CA_STATUS_OK != ret)
1501 CALEClientSendFinish(env, gatt);
1505 return CA_STATUS_OK;
1508 CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
1509 jobject gattCharacteristic)
1511 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1512 VERIFY_NON_NULL(env, TAG, "env is null");
1513 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1514 VERIFY_NON_NULL(gattCharacteristic, TAG, "gattCharacteristic is null");
1516 if (!CALEIsEnableBTAdapter(env))
1518 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1519 return CA_STATUS_FAILED;
1522 // get BluetoothGatt class
1523 OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1524 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1525 if (!jni_cid_BluetoothGatt)
1527 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1528 return CA_STATUS_FAILED;
1531 OIC_LOG(DEBUG, TAG, "write characteristic method");
1532 jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1533 "writeCharacteristic",
1534 "(Landroid/bluetooth/"
1535 "BluetoothGattCharacteristic;)Z");
1536 if (!jni_mid_writeCharacteristic)
1538 OIC_LOG(ERROR, TAG, "jni_mid_writeCharacteristic is null");
1539 return CA_STATUS_FAILED;
1542 // call disconnect gatt method
1543 OIC_LOG(DEBUG, TAG, "CALL API - request to write gatt characteristic");
1544 jboolean ret = (jboolean)(*env)->CallBooleanMethod(env, bluetoothGatt,
1545 jni_mid_writeCharacteristic,
1546 gattCharacteristic);
1549 OIC_LOG(DEBUG, TAG, "writeCharacteristic success");
1553 OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
1554 return CA_STATUS_FAILED;
1557 return CA_STATUS_OK;
1560 CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
1562 VERIFY_NON_NULL(env, TAG, "env is null");
1563 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1565 if (!CALEIsEnableBTAdapter(env))
1567 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1568 return CA_STATUS_FAILED;
1571 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1572 if (!jni_cid_BluetoothGatt)
1574 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1575 return CA_STATUS_FAILED;
1578 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
1581 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1582 return CA_STATUS_FAILED;
1585 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1586 if (!jni_obj_GattCharacteristic)
1588 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1589 return CA_STATUS_FAILED;
1592 OIC_LOG(DEBUG, TAG, "read characteristic method");
1593 jmethodID jni_mid_readCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1594 "readCharacteristic",
1595 "(Landroid/bluetooth/"
1596 "BluetoothGattCharacteristic;)Z");
1597 if (!jni_mid_readCharacteristic)
1599 OIC_LOG(ERROR, TAG, "jni_mid_readCharacteristic is null");
1600 return CA_STATUS_FAILED;
1603 // call disconnect gatt method
1604 OIC_LOG(DEBUG, TAG, "CALL API - request to read gatt characteristic");
1605 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readCharacteristic,
1606 jni_obj_GattCharacteristic);
1609 OIC_LOG(DEBUG, TAG, "readCharacteristic success");
1613 OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
1614 return CA_STATUS_FAILED;
1617 return CA_STATUS_OK;
1620 CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoothGatt,
1621 jobject characteristic)
1623 VERIFY_NON_NULL(env, TAG, "env is null");
1624 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1625 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1627 if (!CALEIsEnableBTAdapter(env))
1629 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1630 return CA_ADAPTER_NOT_ENABLED;
1633 // get BluetoothGatt class
1634 OIC_LOG(DEBUG, TAG, "CALEClientSetCharacteristicNotification");
1635 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1636 if (!jni_cid_BluetoothGatt)
1638 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1639 return CA_STATUS_FAILED;
1642 // set Characteristic Notification
1643 jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
1644 "setCharacteristicNotification",
1645 "(Landroid/bluetooth/"
1646 "BluetoothGattCharacteristic;Z)Z");
1647 if (!jni_mid_setNotification)
1649 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1650 return CA_STATUS_FAILED;
1653 jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification,
1654 characteristic, JNI_TRUE);
1655 if (JNI_TRUE == ret)
1657 OIC_LOG(DEBUG, TAG, "CALL API - setCharacteristicNotification success");
1661 OIC_LOG(ERROR, TAG, "CALL API - setCharacteristicNotification has failed");
1662 return CA_STATUS_FAILED;
1665 return CA_STATUS_OK;
1668 jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
1670 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1671 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1672 VERIFY_NON_NULL_RET(characterUUID, TAG, "characterUUID is null", NULL);
1674 if (!CALEIsEnableBTAdapter(env))
1676 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1680 // get BluetoothGatt class
1681 OIC_LOG(DEBUG, TAG, "CALEClientGetGattService");
1682 jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
1683 if (!jni_cid_BluetoothGatt)
1685 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1689 jmethodID jni_mid_getService = (*env)->GetMethodID(
1690 env, jni_cid_BluetoothGatt, "getService",
1691 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
1692 if (!jni_mid_getService)
1694 OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
1698 jobject jni_obj_service_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1699 if (!jni_obj_service_uuid)
1701 OIC_LOG(ERROR, TAG, "jni_obj_service_uuid is null");
1705 // get bluetooth gatt service
1706 OIC_LOG(DEBUG, TAG, "request to get service");
1707 jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService,
1708 jni_obj_service_uuid);
1709 if (!jni_obj_gattService)
1711 OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
1715 // get bluetooth gatt service class
1716 jclass jni_cid_BluetoothGattService = (*env)->FindClass(
1717 env, "android/bluetooth/BluetoothGattService");
1718 if (!jni_cid_BluetoothGattService)
1720 OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGattService is null");
1724 OIC_LOG(DEBUG, TAG, "get gatt getCharacteristic method");
1725 jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService,
1726 "getCharacteristic",
1727 "(Ljava/util/UUID;)"
1728 "Landroid/bluetooth/"
1729 "BluetoothGattCharacteristic;");
1730 if (!jni_mid_getCharacteristic)
1732 OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
1736 const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
1739 OIC_LOG(ERROR, TAG, "uuid is null");
1743 jobject jni_obj_tx_uuid = CALEClientGetUUIDObject(env, uuid);
1744 if (!jni_obj_tx_uuid)
1746 OIC_LOG(ERROR, TAG, "jni_obj_tx_uuid is null");
1747 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1751 OIC_LOG(DEBUG, TAG, "request to get Characteristic");
1752 jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
1753 jni_mid_getCharacteristic,
1756 (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
1757 return jni_obj_GattCharacteristic;
1760 jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jbyteArray data)
1762 OIC_LOG(DEBUG, TAG, "CALEClientCreateGattCharacteristic");
1763 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1764 VERIFY_NON_NULL_RET(bluetoothGatt, TAG, "bluetoothGatt is null", NULL);
1765 VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
1767 if (!CALEIsEnableBTAdapter(env))
1769 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1773 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1776 OIC_LOG(ERROR, TAG, "jni_uuid is null");
1780 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
1781 if (!jni_obj_GattCharacteristic)
1783 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
1787 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth"
1788 "/BluetoothGattCharacteristic");
1789 if (!jni_cid_BTGattCharacteristic)
1791 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1795 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1796 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
1798 if (!jni_mid_setValue)
1800 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
1804 jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
1806 if (JNI_TRUE == ret)
1808 OIC_LOG(DEBUG, TAG, "the locally stored value has been set");
1812 OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
1817 jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1818 "setWriteType", "(I)V");
1819 if (!jni_mid_setWriteType)
1821 OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
1825 jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
1826 "WRITE_TYPE_NO_RESPONSE", "I");
1827 if (!jni_fid_no_response)
1829 OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
1833 jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
1834 jni_fid_no_response);
1836 (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
1838 return jni_obj_GattCharacteristic;
1841 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
1843 VERIFY_NON_NULL_RET(characteristic, TAG, "characteristic is null", NULL);
1844 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
1846 if (!CALEIsEnableBTAdapter(env))
1848 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1852 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1853 "BluetoothGattCharacteristic");
1854 if (!jni_cid_BTGattCharacteristic)
1856 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1860 OIC_LOG(DEBUG, TAG, "get value in Characteristic");
1861 jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
1863 if (!jni_mid_getValue)
1865 OIC_LOG(ERROR, TAG, "jni_mid_getValue is null");
1869 jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
1871 return jni_obj_data_array;
1874 CAResult_t CALEClientCreateUUIDList()
1878 OIC_LOG(ERROR, TAG, "g_jvm is null");
1879 return CA_STATUS_FAILED;
1882 bool isAttached = false;
1884 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1887 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1888 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1892 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1893 return CA_STATUS_FAILED;
1898 // create new object array
1899 jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
1900 if (!jni_cid_uuid_list)
1902 OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
1906 jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1,
1907 jni_cid_uuid_list, NULL);
1908 if (!jni_obj_uuid_list)
1910 OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
1915 jobject jni_obj_uuid = CALEClientGetUUIDObject(env, OIC_GATT_SERVICE_UUID);
1918 OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
1921 (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
1923 g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
1927 (*g_jvm)->DetachCurrentThread(g_jvm);
1930 return CA_STATUS_OK;
1937 (*g_jvm)->DetachCurrentThread(g_jvm);
1939 return CA_STATUS_FAILED;
1942 CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
1943 jobject characteristic)
1945 VERIFY_NON_NULL(env, TAG, "env is null");
1946 VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
1947 VERIFY_NON_NULL(characteristic, TAG, "characteristic is null");
1949 if (!CALEIsEnableBTAdapter(env))
1951 OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1952 return CA_ADAPTER_NOT_ENABLED;
1955 OIC_LOG(DEBUG, TAG, "CALEClientSetUUIDToDescriptor");
1956 jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
1957 "BluetoothGattCharacteristic");
1958 if (!jni_cid_BTGattCharacteristic)
1960 OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
1961 return CA_STATUS_FAILED;
1964 OIC_LOG(DEBUG, TAG, "set value in Characteristic");
1965 jmethodID jni_mid_getDescriptor = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
1967 "(Ljava/util/UUID;)Landroid/bluetooth/"
1968 "BluetoothGattDescriptor;");
1969 if (!jni_mid_getDescriptor)
1971 OIC_LOG(ERROR, TAG, "jni_mid_getDescriptor is null");
1972 return CA_STATUS_FAILED;
1975 jobject jni_obj_cc_uuid = CALEClientGetUUIDObject(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
1976 if (!jni_obj_cc_uuid)
1978 OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
1979 return CA_STATUS_FAILED;
1982 OIC_LOG(DEBUG, TAG, "request to get descriptor");
1983 jobject jni_obj_descriptor = (*env)->CallObjectMethod(env, characteristic,
1984 jni_mid_getDescriptor, jni_obj_cc_uuid);
1985 if (!jni_obj_descriptor)
1987 OIC_LOG(ERROR, TAG, "jni_obj_descriptor is null");
1988 return CA_STATUS_FAILED;
1991 OIC_LOG(DEBUG, TAG, "set value in descriptor");
1992 jclass jni_cid_descriptor = (*env)->FindClass(env,
1993 "android/bluetooth/BluetoothGattDescriptor");
1994 if (!jni_cid_descriptor)
1996 OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
1997 return CA_STATUS_FAILED;
2000 jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
2001 if (!jni_mid_setValue)
2003 OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
2004 return CA_STATUS_FAILED;
2007 jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
2008 "ENABLE_NOTIFICATION_VALUE", "[B");
2009 if (!jni_fid_NotiValue)
2011 OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
2012 return CA_STATUS_FAILED;
2015 OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
2017 jboolean jni_setvalue = (*env)->CallBooleanMethod(
2018 env, jni_obj_descriptor, jni_mid_setValue,
2019 (jbyteArray)(*env)->GetStaticObjectField(env, jni_cid_descriptor, jni_fid_NotiValue));
2022 OIC_LOG(DEBUG, TAG, "setValue success");
2026 OIC_LOG(ERROR, TAG, "setValue has failed");
2027 return CA_STATUS_FAILED;
2030 jclass jni_cid_gatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
2033 OIC_LOG(ERROR, TAG, "jni_cid_gatt is null");
2034 return CA_STATUS_FAILED;
2037 OIC_LOG(DEBUG, TAG, "write Descriptor in gatt object");
2038 jmethodID jni_mid_writeDescriptor = (*env)->GetMethodID(env, jni_cid_gatt, "writeDescriptor",
2039 "(Landroid/bluetooth/"
2040 "BluetoothGattDescriptor;)Z");
2041 if (!jni_mid_writeDescriptor)
2043 OIC_LOG(ERROR, TAG, "jni_mid_writeDescriptor is null");
2044 return CA_STATUS_FAILED;
2047 OIC_LOG(DEBUG, TAG, "request to write descriptor");
2048 jboolean jni_ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeDescriptor,
2049 jni_obj_descriptor);
2052 OIC_LOG(DEBUG, TAG, "writeDescriptor success");
2056 OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
2057 return CA_STATUS_FAILED;
2060 return CA_STATUS_OK;
2063 void CALEClientCreateScanDeviceList(JNIEnv *env)
2065 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
2066 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2068 ca_mutex_lock(g_deviceListMutex);
2069 // create new object array
2070 if (g_deviceList == NULL)
2072 OIC_LOG(DEBUG, TAG, "Create device list");
2074 g_deviceList = u_arraylist_create();
2076 ca_mutex_unlock(g_deviceListMutex);
2079 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
2081 OIC_LOG(DEBUG, TAG, "IN - CALEClientAddScanDeviceToList");
2082 VERIFY_NON_NULL(device, TAG, "device is null");
2083 VERIFY_NON_NULL(env, TAG, "env is null");
2085 ca_mutex_lock(g_deviceListMutex);
2089 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2090 ca_mutex_unlock(g_deviceListMutex);
2091 return CA_STATUS_FAILED;
2094 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2095 if (!jni_remoteAddress)
2097 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2098 ca_mutex_unlock(g_deviceListMutex);
2099 return CA_STATUS_FAILED;
2102 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2105 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2106 ca_mutex_unlock(g_deviceListMutex);
2107 return CA_STATUS_FAILED;
2110 if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
2112 jobject gdevice = (*env)->NewGlobalRef(env, device);
2113 u_arraylist_add(g_deviceList, gdevice);
2114 ca_cond_signal(g_deviceDescCond);
2115 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
2117 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2119 ca_mutex_unlock(g_deviceListMutex);
2121 OIC_LOG(DEBUG, TAG, "OUT - CALEClientAddScanDeviceToList");
2122 return CA_STATUS_OK;
2125 bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
2127 OIC_LOG(DEBUG, TAG, "IN - CALEClientIsDeviceInScanDeviceList");
2128 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2129 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2133 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
2137 uint32_t length = u_arraylist_length(g_deviceList);
2138 for (uint32_t index = 0; index < length; index++)
2140 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2143 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2147 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2148 if (!jni_setAddress)
2150 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2154 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2157 OIC_LOG(ERROR, TAG, "setAddress is null");
2161 if (!strcmp(remoteAddress, setAddress))
2163 OIC_LOG(DEBUG, TAG, "the device is already set");
2164 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2168 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2171 OIC_LOG(DEBUG, TAG, "OUT - CALEClientIsDeviceInScanDeviceList");
2172 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
2177 CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
2179 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
2180 VERIFY_NON_NULL(env, TAG, "env is null");
2182 ca_mutex_lock(g_deviceListMutex);
2186 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2187 ca_mutex_unlock(g_deviceListMutex);
2188 return CA_STATUS_FAILED;
2191 uint32_t length = u_arraylist_length(g_deviceList);
2192 for (uint32_t index = 0; index < length; index++)
2194 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2197 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2200 (*env)->DeleteGlobalRef(env, jarrayObj);
2203 OICFree(g_deviceList);
2204 g_deviceList = NULL;
2206 ca_mutex_unlock(g_deviceListMutex);
2207 return CA_STATUS_OK;
2210 CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
2212 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
2213 VERIFY_NON_NULL(address, TAG, "address is null");
2214 VERIFY_NON_NULL(env, TAG, "env is null");
2216 ca_mutex_lock(g_deviceListMutex);
2220 OIC_LOG(ERROR, TAG, "g_deviceList is null");
2221 ca_mutex_unlock(g_deviceListMutex);
2222 return CA_STATUS_FAILED;
2225 uint32_t length = u_arraylist_length(g_deviceList);
2226 for (uint32_t index = 0; index < length; index++)
2228 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceList, index);
2231 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2232 ca_mutex_unlock(g_deviceListMutex);
2233 return CA_STATUS_FAILED;
2236 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
2237 if (!jni_setAddress)
2239 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2240 ca_mutex_unlock(g_deviceListMutex);
2241 return CA_STATUS_FAILED;
2244 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2247 OIC_LOG(ERROR, TAG, "setAddress is null");
2248 ca_mutex_unlock(g_deviceListMutex);
2249 return CA_STATUS_FAILED;
2252 const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
2255 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2256 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2257 ca_mutex_unlock(g_deviceListMutex);
2258 return CA_STATUS_FAILED;
2261 if (!strcmp(setAddress, remoteAddress))
2263 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2264 (*env)->DeleteGlobalRef(env, jarrayObj);
2265 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2266 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2268 if (NULL == u_arraylist_remove(g_deviceList, index))
2270 OIC_LOG(ERROR, TAG, "List removal failed.");
2271 ca_mutex_unlock(g_deviceListMutex);
2272 return CA_STATUS_FAILED;
2274 ca_mutex_unlock(g_deviceListMutex);
2275 return CA_STATUS_OK;
2277 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2278 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
2281 ca_mutex_unlock(g_deviceListMutex);
2282 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
2284 return CA_STATUS_OK;
2291 CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
2293 OIC_LOG(DEBUG, TAG, "CALEClientAddGattobjToList");
2294 VERIFY_NON_NULL(env, TAG, "env is null");
2295 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2297 ca_mutex_lock(g_gattObjectMutex);
2299 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2300 if (!jni_remoteAddress)
2302 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2303 ca_mutex_unlock(g_gattObjectMutex);
2304 return CA_STATUS_FAILED;
2307 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2310 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2311 ca_mutex_unlock(g_gattObjectMutex);
2312 return CA_STATUS_FAILED;
2315 if (!CALEClientIsGattObjInList(env, remoteAddress))
2317 jobject newGatt = (*env)->NewGlobalRef(env, gatt);
2318 u_arraylist_add(g_gattObjectList, newGatt);
2319 OIC_LOG(DEBUG, TAG, "Set GATT Object to Array as Element");
2322 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2323 ca_mutex_unlock(g_gattObjectMutex);
2324 return CA_STATUS_OK;
2327 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
2329 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2330 VERIFY_NON_NULL(env, TAG, "env is null");
2331 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2333 uint32_t length = u_arraylist_length(g_gattObjectList);
2334 for (uint32_t index = 0; index < length; index++)
2337 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2340 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2344 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2345 if (!jni_setAddress)
2347 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2351 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2354 OIC_LOG(ERROR, TAG, "setAddress is null");
2358 if (!strcmp(remoteAddress, setAddress))
2360 OIC_LOG(DEBUG, TAG, "the device is already set");
2361 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2366 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2371 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2375 jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
2377 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2378 VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
2379 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2381 ca_mutex_lock(g_gattObjectMutex);
2382 uint32_t length = u_arraylist_length(g_gattObjectList);
2383 for (uint32_t index = 0; index < length; index++)
2385 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2388 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2389 ca_mutex_unlock(g_gattObjectMutex);
2393 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2394 if (!jni_setAddress)
2396 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2397 ca_mutex_unlock(g_gattObjectMutex);
2401 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2404 OIC_LOG(ERROR, TAG, "setAddress is null");
2405 ca_mutex_unlock(g_gattObjectMutex);
2409 if (!strcmp(remoteAddress, setAddress))
2411 OIC_LOG(DEBUG, TAG, "the device is already set");
2412 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2413 ca_mutex_unlock(g_gattObjectMutex);
2416 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2419 ca_mutex_unlock(g_gattObjectMutex);
2420 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2424 CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
2426 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2427 VERIFY_NON_NULL(env, TAG, "env is null");
2429 ca_mutex_lock(g_gattObjectMutex);
2430 if (!g_gattObjectList)
2432 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2433 ca_mutex_unlock(g_gattObjectMutex);
2434 return CA_STATUS_FAILED;
2437 uint32_t length = u_arraylist_length(g_gattObjectList);
2438 for (uint32_t index = 0; index < length; index++)
2440 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2443 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2446 (*env)->DeleteGlobalRef(env, jarrayObj);
2449 OICFree(g_gattObjectList);
2450 g_gattObjectList = NULL;
2451 ca_mutex_unlock(g_gattObjectMutex);
2452 return CA_STATUS_OK;
2455 CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
2457 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2458 VERIFY_NON_NULL(gatt, TAG, "gatt is null");
2459 VERIFY_NON_NULL(env, TAG, "env is null");
2461 ca_mutex_lock(g_gattObjectMutex);
2462 if (!g_gattObjectList)
2464 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2465 ca_mutex_unlock(g_gattObjectMutex);
2466 return CA_STATUS_FAILED;
2469 uint32_t length = u_arraylist_length(g_gattObjectList);
2470 for (uint32_t index = 0; index < length; index++)
2472 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2475 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2476 ca_mutex_unlock(g_gattObjectMutex);
2477 return CA_STATUS_FAILED;
2480 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2481 if (!jni_setAddress)
2483 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2484 ca_mutex_unlock(g_gattObjectMutex);
2485 return CA_STATUS_FAILED;
2488 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2491 OIC_LOG(ERROR, TAG, "setAddress is null");
2492 ca_mutex_unlock(g_gattObjectMutex);
2493 return CA_STATUS_FAILED;
2496 jstring jni_remoteAddress = CALEClientGetAddressFromGattObj(env, gatt);
2497 if (!jni_remoteAddress)
2499 OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2500 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2501 ca_mutex_unlock(g_gattObjectMutex);
2502 return CA_STATUS_FAILED;
2505 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2508 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2509 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2510 ca_mutex_unlock(g_gattObjectMutex);
2511 return CA_STATUS_FAILED;
2514 if (!strcmp(setAddress, remoteAddress))
2516 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2517 (*env)->DeleteGlobalRef(env, jarrayObj);
2518 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2519 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2521 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2523 OIC_LOG(ERROR, TAG, "List removal failed.");
2524 ca_mutex_unlock(g_gattObjectMutex);
2525 return CA_STATUS_FAILED;
2527 ca_mutex_unlock(g_gattObjectMutex);
2528 return CA_STATUS_OK;
2530 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2531 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2534 ca_mutex_unlock(g_gattObjectMutex);
2535 OIC_LOG(DEBUG, TAG, "there are no target object");
2536 return CA_STATUS_OK;
2539 CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
2541 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2542 VERIFY_NON_NULL(addr, TAG, "addr is null");
2543 VERIFY_NON_NULL(env, TAG, "env is null");
2545 ca_mutex_lock(g_gattObjectMutex);
2546 if (!g_gattObjectList)
2548 OIC_LOG(ERROR, TAG, "g_gattObjectList is null");
2549 ca_mutex_unlock(g_gattObjectMutex);
2550 return CA_STATUS_FAILED;
2553 uint32_t length = u_arraylist_length(g_gattObjectList);
2554 for (uint32_t index = 0; index < length; index++)
2556 jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
2559 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2560 ca_mutex_unlock(g_gattObjectMutex);
2561 return CA_STATUS_FAILED;
2564 jstring jni_setAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
2565 if (!jni_setAddress)
2567 OIC_LOG(ERROR, TAG, "jni_setAddress is null");
2568 ca_mutex_unlock(g_gattObjectMutex);
2569 return CA_STATUS_FAILED;
2572 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
2575 OIC_LOG(ERROR, TAG, "setAddress is null");
2576 ca_mutex_unlock(g_gattObjectMutex);
2577 return CA_STATUS_FAILED;
2580 const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
2583 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2584 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2585 ca_mutex_unlock(g_gattObjectMutex);
2586 return CA_STATUS_FAILED;
2589 if (!strcmp(setAddress, remoteAddress))
2591 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
2592 (*env)->DeleteGlobalRef(env, jarrayObj);
2594 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2595 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2596 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2598 OIC_LOG(ERROR, TAG, "List removal failed.");
2599 ca_mutex_unlock(g_gattObjectMutex);
2600 return CA_STATUS_FAILED;
2602 ca_mutex_unlock(g_gattObjectMutex);
2603 return CA_STATUS_OK;
2605 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
2606 (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
2609 ca_mutex_unlock(g_gattObjectMutex);
2610 OIC_LOG(DEBUG, TAG, "there are no target object");
2611 return CA_STATUS_FAILED;
2618 CAResult_t CALEClientUpdateDeviceState(const char* address, uint32_t connectedState,
2619 uint16_t notificationState, uint16_t sendState)
2621 VERIFY_NON_NULL(address, TAG, "address is null");
2623 CALEState_t *newstate = (CALEState_t*) OICMalloc(sizeof(CALEState_t));
2626 OIC_LOG(ERROR, TAG, "out of memory");
2627 return CA_MEMORY_ALLOC_FAILED;
2630 if (strlen(address) > CA_MACADDR_SIZE)
2632 OIC_LOG(ERROR, TAG, "address is not proper");
2634 return CA_STATUS_FAILED;
2637 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2638 newstate->connectedState = connectedState;
2639 newstate->notificationState = notificationState;
2640 newstate->sendState = sendState;
2641 return CALEClientAddDeviceStateToList(newstate);
2644 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2646 VERIFY_NON_NULL(state, TAG, "state is null");
2648 ca_mutex_lock(g_deviceStateListMutex);
2650 if (!g_deviceStateList)
2652 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2653 ca_mutex_unlock(g_deviceStateListMutex);
2654 return CA_STATUS_FAILED;
2657 if (CALEClientIsDeviceInList(state->address))
2659 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2662 OIC_LOG(ERROR, TAG, "curState is null");
2663 ca_mutex_unlock(g_deviceStateListMutex);
2664 return CA_STATUS_FAILED;
2667 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2669 state->notificationState = curState->notificationState;
2672 // delete previous state for update new state
2673 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2674 if (CA_STATUS_OK != res)
2676 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2677 ca_mutex_unlock(g_deviceStateListMutex);
2681 u_arraylist_add(g_deviceStateList, state); // update new state
2682 OIC_LOG_V(DEBUG, TAG, "Set State Info to List : %d, %d",
2683 state->connectedState, state->notificationState);
2685 ca_mutex_unlock(g_deviceStateListMutex);
2686 return CA_STATUS_OK;
2689 bool CALEClientIsDeviceInList(const char* remoteAddress)
2691 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2693 if (!g_deviceStateList)
2695 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2699 uint32_t length = u_arraylist_length(g_deviceStateList);
2700 for (uint32_t index = 0; index < length; index++)
2702 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2705 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2709 if (!strcmp(remoteAddress, state->address))
2711 OIC_LOG(DEBUG, TAG, "the device is already set");
2720 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2724 CAResult_t CALEClientRemoveAllDeviceState()
2726 OIC_LOG(DEBUG, TAG, "CALENativeRemoveAllDevices");
2728 ca_mutex_lock(g_deviceStateListMutex);
2729 if (!g_deviceStateList)
2731 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2732 ca_mutex_unlock(g_deviceStateListMutex);
2733 return CA_STATUS_FAILED;
2736 uint32_t length = u_arraylist_length(g_deviceStateList);
2737 for (uint32_t index = 0; index < length; index++)
2739 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2742 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2748 OICFree(g_deviceStateList);
2749 g_deviceStateList = NULL;
2750 ca_mutex_unlock(g_deviceStateListMutex);
2752 return CA_STATUS_OK;
2755 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2757 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2758 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2760 if (!g_deviceStateList)
2762 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2763 return CA_STATUS_FAILED;
2766 uint32_t length = u_arraylist_length(g_deviceStateList);
2767 for (uint32_t index = 0; index < length; index++)
2769 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2772 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2776 if (!strcmp(state->address, remoteAddress))
2778 OIC_LOG_V(DEBUG, TAG, "remove state : %s", remoteAddress);
2781 if (NULL == u_arraylist_remove(g_deviceStateList, index))
2783 OIC_LOG(ERROR, TAG, "List removal failed.");
2784 return CA_STATUS_FAILED;
2787 return CA_STATUS_OK;
2791 return CA_STATUS_FAILED;
2794 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2796 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2797 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2799 if (!g_deviceStateList)
2801 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2805 uint32_t length = u_arraylist_length(g_deviceStateList);
2806 for (uint32_t index = 0; index < length; index++)
2808 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2811 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2815 if (!strcmp(state->address, remoteAddress))
2817 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2824 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2826 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2827 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2829 ca_mutex_lock(g_deviceStateListMutex);
2830 if (!g_deviceStateList)
2832 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2833 ca_mutex_unlock(g_deviceStateListMutex);
2837 uint32_t length = u_arraylist_length(g_deviceStateList);
2838 for (uint32_t index = 0; index < length; index++)
2840 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2843 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2847 if (!strcmp(state->address, remoteAddress))
2849 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2851 if (STATE_CONNECTED == state->connectedState)
2853 ca_mutex_unlock(g_deviceStateListMutex);
2858 ca_mutex_unlock(g_deviceStateListMutex);
2863 ca_mutex_unlock(g_deviceStateListMutex);
2867 bool CALEClientIsSetCharacteristic(const char* remoteAddress)
2869 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2870 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2872 ca_mutex_lock(g_deviceStateListMutex);
2873 if (!g_deviceStateList)
2875 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2876 ca_mutex_unlock(g_deviceStateListMutex);
2880 uint32_t length = u_arraylist_length(g_deviceStateList);
2881 for (uint32_t index = 0; index < length; index++)
2883 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2886 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2890 if (!strcmp(state->address, remoteAddress))
2892 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2894 if (STATE_CHARACTER_SET == state->notificationState)
2896 ca_mutex_unlock(g_deviceStateListMutex);
2901 ca_mutex_unlock(g_deviceStateListMutex);
2907 ca_mutex_unlock(g_deviceStateListMutex);
2911 void CALEClientCreateDeviceList()
2913 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2915 // create new object array
2916 if (!g_gattObjectList)
2918 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2920 g_gattObjectList = u_arraylist_create();
2923 if (!g_deviceStateList)
2925 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2927 g_deviceStateList = u_arraylist_create();
2932 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2934 g_deviceList = u_arraylist_create();
2939 * Check Sent Count for remove g_sendBuffer
2941 void CALEClientUpdateSendCnt(JNIEnv *env)
2943 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2945 ca_mutex_lock(g_threadMutex);
2949 if (g_targetCnt <= g_currentSentCnt)
2952 g_currentSentCnt = 0;
2956 (*env)->DeleteGlobalRef(env, g_sendBuffer);
2957 g_sendBuffer = NULL;
2959 // notity the thread
2960 ca_cond_signal(g_threadCond);
2961 CALEClientSetSendFinishFlag(true);
2962 OIC_LOG(DEBUG, TAG, "set signal for send data");
2965 ca_mutex_unlock(g_threadMutex);
2968 CAResult_t CALEClientInitGattMutexVaraibles()
2970 OIC_LOG(DEBUG, TAG, "IN");
2972 if (NULL == g_bleReqRespClientCbMutex)
2974 g_bleReqRespClientCbMutex = ca_mutex_new();
2975 if (NULL == g_bleReqRespClientCbMutex)
2977 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2978 return CA_STATUS_FAILED;
2982 if (NULL == g_bleServerBDAddressMutex)
2984 g_bleServerBDAddressMutex = ca_mutex_new();
2985 if (NULL == g_bleServerBDAddressMutex)
2987 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2988 return CA_STATUS_FAILED;
2992 if (NULL == g_threadMutex)
2994 g_threadMutex = ca_mutex_new();
2995 if (NULL == g_threadMutex)
2997 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2998 return CA_STATUS_FAILED;
3002 if (NULL == g_threadSendMutex)
3004 g_threadSendMutex = ca_mutex_new();
3005 if (NULL == g_threadSendMutex)
3007 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3008 return CA_STATUS_FAILED;
3012 if (NULL == g_deviceListMutex)
3014 g_deviceListMutex = ca_mutex_new();
3015 if (NULL == g_deviceListMutex)
3017 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3018 return CA_STATUS_FAILED;
3022 if (NULL == g_gattObjectMutex)
3024 g_gattObjectMutex = ca_mutex_new();
3025 if (NULL == g_gattObjectMutex)
3027 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3028 return CA_STATUS_FAILED;
3032 if (NULL == g_deviceStateListMutex)
3034 g_deviceStateListMutex = ca_mutex_new();
3035 if (NULL == g_deviceStateListMutex)
3037 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3038 return CA_STATUS_FAILED;
3042 if (NULL == g_SendFinishMutex)
3044 g_SendFinishMutex = ca_mutex_new();
3045 if (NULL == g_SendFinishMutex)
3047 OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
3048 return CA_STATUS_FAILED;
3052 OIC_LOG(DEBUG, TAG, "OUT");
3053 return CA_STATUS_OK;
3056 void CALEClientTerminateGattMutexVariables()
3058 OIC_LOG(DEBUG, TAG, "IN");
3060 ca_mutex_free(g_bleReqRespClientCbMutex);
3061 g_bleReqRespClientCbMutex = NULL;
3063 ca_mutex_free(g_bleServerBDAddressMutex);
3064 g_bleServerBDAddressMutex = NULL;
3066 ca_mutex_free(g_threadMutex);
3067 g_threadMutex = NULL;
3069 ca_mutex_free(g_threadSendMutex);
3070 g_threadSendMutex = NULL;
3072 ca_mutex_free(g_deviceListMutex);
3073 g_deviceListMutex = NULL;
3075 ca_mutex_free(g_SendFinishMutex);
3076 g_SendFinishMutex = NULL;
3078 OIC_LOG(DEBUG, TAG, "OUT");
3081 void CALEClientSetSendFinishFlag(bool flag)
3083 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
3085 ca_mutex_lock(g_SendFinishMutex);
3086 g_isFinishedSendData = flag;
3087 ca_mutex_unlock(g_SendFinishMutex);
3094 CAResult_t CAStartLEGattClient()
3096 CAResult_t res = CALEClientStartMulticastServer();
3097 if (CA_STATUS_OK != res)
3099 OIC_LOG(ERROR, TAG, "CALEClientStartMulticastServer has failed");
3103 g_isStartedLEClient = true;
3109 void CAStopLEGattClient()
3111 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
3115 OIC_LOG(ERROR, TAG, "g_jvm is null");
3119 bool isAttached = false;
3121 jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
3124 OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
3125 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
3129 OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
3135 CAResult_t ret = CALEClientDisconnectAll(env);
3136 if (CA_STATUS_OK != ret)
3138 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
3141 ret = CALEClientStopScan();
3142 if(CA_STATUS_OK != ret)
3144 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
3147 ca_cond_signal(g_threadCond);
3151 (*g_jvm)->DetachCurrentThread(g_jvm);
3156 void CATerminateLEGattClient()
3158 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
3159 CALEClientTerminate();
3162 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t *data,
3163 uint32_t dataLen, CALETransferType_t type,
3166 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
3167 VERIFY_NON_NULL(data, TAG, "data is null");
3168 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
3170 if (LE_UNICAST != type || position < 0)
3172 OIC_LOG(ERROR, TAG, "this request is not unicast");
3173 return CA_STATUS_INVALID_PARAM;
3176 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
3179 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
3181 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
3182 VERIFY_NON_NULL(data, TAG, "data is null");
3184 return CALEClientSendMulticastMessage(data, dataLen);
3187 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
3189 OIC_LOG(DEBUG, TAG, "IN");
3191 ca_mutex_lock(g_bleReqRespClientCbMutex);
3192 g_CABLEClientDataReceivedCallback = callback;
3193 ca_mutex_unlock(g_bleReqRespClientCbMutex);
3195 OIC_LOG(DEBUG, TAG, "OUT");
3198 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
3200 OIC_LOG(DEBUG, TAG, "IN");
3202 CALEClientInitialize(handle);
3204 OIC_LOG(DEBUG, TAG, "OUT");
3207 CAResult_t CAGetLEAddress(char **local_address)
3209 VERIFY_NON_NULL(local_address, TAG, "local_address");
3210 OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
3211 return CA_NOT_SUPPORTED;
3214 JNIEXPORT void JNICALL
3215 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env, jobject obj,
3218 OIC_LOG(DEBUG, TAG, "CaLeRegisterLeScanCallback");
3219 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3220 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3221 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3223 g_leScanCallback = (*env)->NewGlobalRef(env, callback);
3226 JNIEXPORT void JNICALL
3227 Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, jobject obj,
3230 OIC_LOG(DEBUG, TAG, "CaLeRegisterGattCallback");
3231 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3232 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3233 VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
3235 g_leGattCallback = (*env)->NewGlobalRef(env, callback);
3238 JNIEXPORT void JNICALL
3239 Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject obj,
3242 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3243 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3244 VERIFY_NON_NULL_VOID(device, TAG, "device is null");
3246 CAResult_t res = CALEClientAddScanDeviceToList(env, device);
3247 if (CA_STATUS_OK != res)
3249 OIC_LOG_V(ERROR, TAG, "CALEClientAddScanDeviceToList has failed : %d", res);
3254 * Class: org_iotivity_ca_jar_caleinterface
3255 * Method: CALeGattConnectionStateChangeCallback
3256 * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
3258 JNIEXPORT void JNICALL
3259 Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(JNIEnv *env,
3265 OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status,
3267 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3268 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3269 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3271 if (GATT_SUCCESS == status && STATE_CONNECTED == newstate) // le connected
3273 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3279 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3282 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
3283 STATE_CHARACTER_NO_CHANGE,
3285 if (CA_STATUS_OK != res)
3287 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3288 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3291 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3294 CAResult_t res = CALEClientAddGattobjToList(env, gatt);
3295 if (CA_STATUS_OK != res)
3297 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
3301 res = CALEClientDiscoverServices(env, gatt);
3302 if (CA_STATUS_OK != res)
3304 OIC_LOG(ERROR, TAG, "CALEClientDiscoverServices has failed");
3308 else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate) // le disconnected
3310 CAResult_t res = CALEClientStartScan();
3311 if (CA_STATUS_OK != res)
3313 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
3316 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3319 OIC_LOG(ERROR, TAG, "CALEClientGetAddressFromGattObj has failed");
3322 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3325 res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3326 STATE_CHARACTER_NO_CHANGE,
3328 if (CA_STATUS_OK != res)
3330 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3332 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3335 res = CALEClientGattClose(env, gatt);
3336 if (CA_STATUS_OK != res)
3338 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3344 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3347 OIC_LOG(ERROR, TAG, "jni_address is null");
3352 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3355 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
3356 STATE_CHARACTER_NO_CHANGE,
3358 if (CA_STATUS_OK != res)
3360 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3363 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3365 CAResult_t res = CALEClientGattClose(env, gatt);
3366 if (CA_STATUS_OK != res)
3368 OIC_LOG(ERROR, TAG, "CALEClientGattClose has failed");
3378 CALEClientSendFinish(env, gatt);
3383 * Class: org_iotivity_ca_jar_caleinterface
3384 * Method: CALeGattServicesDiscoveredCallback
3385 * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
3387 JNIEXPORT void JNICALL
3388 Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIEnv *env,
3393 OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
3394 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3395 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3396 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3398 if (0 != status) // discovery error
3400 CALEClientSendFinish(env, gatt);
3404 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3407 CALEClientSendFinish(env, gatt);
3411 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3414 CALEClientSendFinish(env, gatt);
3418 if (!CALEClientIsSetCharacteristic(address))
3420 jstring jni_uuid = (*env)->NewStringUTF(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
3423 OIC_LOG(ERROR, TAG, "jni_uuid is null");
3427 jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, gatt, jni_uuid);
3428 if (!jni_obj_GattCharacteristic)
3430 OIC_LOG(ERROR, TAG, "jni_obj_GattCharacteristic is null");
3434 CAResult_t res = CALEClientSetCharacteristicNotification(env, gatt,
3435 jni_obj_GattCharacteristic);
3436 if (CA_STATUS_OK != res)
3438 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
3442 res = CALEClientSetUUIDToDescriptor(env, gatt, jni_obj_GattCharacteristic);
3443 if (CA_STATUS_OK != res)
3445 OIC_LOG(INFO, TAG, "Descriptor of the uuid is not found");
3446 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3447 if (CA_STATUS_OK != res)
3449 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3454 res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3456 if (CA_STATUS_OK != res)
3458 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3464 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3465 if (CA_STATUS_OK != res)
3467 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3471 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3476 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3477 CALEClientSendFinish(env, gatt);
3482 * Class: org_iotivity_ca_jar_caleinterface
3483 * Method: CALeGattCharacteristicWritjclasseCallback
3484 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
3486 JNIEXPORT void JNICALL
3487 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
3488 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data,
3491 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
3492 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3493 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3494 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3497 char* wroteData = (char*) (*env)->GetByteArrayElements(env, data, &isCopy);
3499 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", wroteData);
3501 // send success & signal
3502 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3508 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3514 if (GATT_SUCCESS != status) // error case
3516 OIC_LOG(ERROR, TAG, "send failure");
3517 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3519 if (CA_STATUS_OK != res)
3521 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3523 CALEClientSendFinish(env, gatt);
3527 OIC_LOG(DEBUG, TAG, "send success");
3528 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
3529 STATE_SEND_SUCCESS);
3530 if (CA_STATUS_OK != res)
3532 OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
3534 CALEClientUpdateSendCnt(env);
3537 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3543 CALEClientSendFinish(env, gatt);
3548 * Class: org_iotivity_ca_jar_caleinterface
3549 * Method: CALeGattCharacteristicChangedCallback
3550 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
3552 JNIEXPORT void JNICALL
3553 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
3554 JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
3556 OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
3557 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3558 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3559 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3560 VERIFY_NON_NULL_VOID(data, TAG, "data is null");
3562 // get Byte Array and convert to uint8_t*
3563 jint length = (*env)->GetArrayLength(env, data);
3566 jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
3568 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
3569 jni_byte_responseData);
3571 uint8_t* receivedData = OICMalloc(length);
3574 OIC_LOG(ERROR, TAG, "receivedData is null");
3578 memcpy(receivedData, jni_byte_responseData, length);
3579 (*env)->ReleaseByteArrayElements(env, data, jni_byte_responseData, JNI_ABORT);
3581 jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
3584 OIC_LOG(ERROR, TAG, "jni_address is null");
3585 OICFree(receivedData);
3589 const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
3592 OIC_LOG(ERROR, TAG, "address is null");
3593 OICFree(receivedData);
3597 OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data. : %p, %d",
3598 receivedData, length);
3600 ca_mutex_lock(g_bleServerBDAddressMutex);
3601 uint32_t sentLength = 0;
3602 g_CABLEClientDataReceivedCallback(address, receivedData, length,
3604 ca_mutex_unlock(g_bleServerBDAddressMutex);
3606 (*env)->ReleaseStringUTFChars(env, jni_address, address);
3610 * Class: org_iotivity_ca_jar_caleinterface
3611 * Method: CALeGattDescriptorWriteCallback
3612 * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
3614 JNIEXPORT void JNICALL
3615 Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv *env, jobject obj,
3619 OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
3620 VERIFY_NON_NULL_VOID(env, TAG, "env is null");
3621 VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
3622 VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
3624 CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
3625 if (CA_STATUS_OK != res)
3627 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
3635 CALEClientSendFinish(env, gatt);